Merge branch 'development'

* development:
  Add unit test for processing events behavior
  Add unit test for processing events behavior
  Update test
This commit is contained in:
Dawid Drozd 2021-06-30 10:03:00 +02:00
commit fad6be4f7a
2 changed files with 80 additions and 6 deletions

View File

@ -37,11 +37,11 @@ TEST_CASE("Should not be processed with unnecessary delay", "[concurrent][EventB
listener.listen([bus](const EventTest& event) { listener.listen([bus](const EventTest& event) {
const auto eventAge = std::chrono::duration_cast<std::chrono::milliseconds>( const auto eventAge = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - event.created); std::chrono::steady_clock::now() - event.created);
CHECK(eventAge < 5ms); CHECK(eventAge.count() < (5ms).count());
std::cout << "Event:" << event.data << " old: " << eventAge.count() << "ms" << std::endl; std::cout << "Event:" << event.data << " old: " << eventAge.count() << "ms" << std::endl;
std::this_thread::sleep_for(2ms); std::this_thread::sleep_for(2ms); // Some heavy work when processing event
bus->postpone(EventTest{"other"}); bus->postpone(EventTest{"other"});
std::this_thread::sleep_for(3ms); std::this_thread::sleep_for(3ms); // Some heavy work when processing event
}); });
std::atomic<bool> isWorking = true; std::atomic<bool> isWorking = true;
@ -72,7 +72,7 @@ TEST_CASE("Should not be processed with unnecessary delay", "[concurrent][EventB
{ {
const auto sleepTime = std::chrono::duration_cast<std::chrono::milliseconds>( const auto sleepTime = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - start); std::chrono::steady_clock::now() - start);
CHECK(sleepTime < 5ms); CHECK(sleepTime.count() < (5ms).count());
// No events waiting for us // No events waiting for us
std::cout << "I was sleeping for: " << sleepTime.count() << " ms" << std::endl; std::cout << "I was sleeping for: " << sleepTime.count() << " ms" << std::endl;
} }
@ -98,7 +98,7 @@ TEST_CASE("Should wait for event being scheduled", "[concurrent][EventBus]")
listener.listen([bus](const EventTest& event) { listener.listen([bus](const EventTest& event) {
const auto eventAge = std::chrono::duration_cast<std::chrono::milliseconds>( const auto eventAge = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - event.created); std::chrono::steady_clock::now() - event.created);
CHECK(eventAge < 5ms); CHECK(eventAge.count() < (5ms).count());
std::cout << "Event:" << event.data << " old: " << eventAge.count() << "ms" << std::endl; std::cout << "Event:" << event.data << " old: " << eventAge.count() << "ms" << std::endl;
}); });
@ -120,7 +120,7 @@ TEST_CASE("Should wait for event being scheduled", "[concurrent][EventBus]")
{ {
const auto sleepTime = std::chrono::duration_cast<std::chrono::milliseconds>( const auto sleepTime = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - start); std::chrono::steady_clock::now() - start);
CHECK(sleepTime >= 9ms); CHECK(sleepTime.count() >= (9ms).count());
std::cout << "[SUCCESS] I was sleeping for: " << sleepTime.count() << " ms i:" << i std::cout << "[SUCCESS] I was sleeping for: " << sleepTime.count() << " ms i:" << i
<< std::endl; << std::endl;

View File

@ -351,6 +351,80 @@ TEST_CASE("Should not process events When no more events", "[EventBus]")
REQUIRE(bus.process() == 0); REQUIRE(bus.process() == 0);
} }
TEST_CASE("Should process event When listener transit", "[EventBus]")
{
/**
* This case may be usefull when we use EventBus for some kind of state machine and we are
* during transit from one state to other.
*/
EventBus bus;
auto listenerA = EventBus::Listener::createNotOwning(bus);
auto listenerB = EventBus::Listener::createNotOwning(bus);
int listenerAReceiveEvent = 0;
int listenerBReceiveEvent = 0;
listenerA.listen([&](const event::Value& event) { ++listenerAReceiveEvent; });
REQUIRE(bus.process() == 0);
// All cases should be same because of deterministic way of processing
SECTION("Post event before transit")
{
bus.postpone(event::Value{3}); // <-- before
listenerA.unlistenAll();
listenerB.listen([&](const event::Value& event) { ++listenerBReceiveEvent; });
}
SECTION("Post event in transit")
{
listenerA.unlistenAll();
bus.postpone(event::Value{3}); // <-- in
listenerB.listen([&](const event::Value& event) { ++listenerBReceiveEvent; });
}
SECTION("Post event after transit")
{
listenerA.unlistenAll();
listenerB.listen([&](const event::Value& event) { ++listenerBReceiveEvent; });
bus.postpone(event::Value{3}); // <-- after
}
REQUIRE(bus.process() == 1);
CHECK(listenerAReceiveEvent == 0);
CHECK(listenerBReceiveEvent == 1);
}
TEST_CASE("Should NOT process event When listener unlisten before process", "[EventBus]")
{
EventBus bus;
auto listener = EventBus::Listener::createNotOwning(bus);
int listenerReceiveEvent = 0;
listener.listen([&](const event::Value& event) { ++listenerReceiveEvent; });
REQUIRE(bus.process() == 0);
bus.postpone(event::Value{3});
REQUIRE(bus.process() == 1);
CHECK(listenerReceiveEvent == 1);
// All cases should be same because of deterministic way of processing
SECTION("Post event before unlisten")
{
bus.postpone(event::Value{3}); // <-- before
listener.unlistenAll();
}
SECTION("Post event after transit")
{
listener.unlistenAll();
bus.postpone(event::Value{3}); // <-- after
}
REQUIRE(bus.process() == 1);
CHECK(listenerReceiveEvent == 1);
}
TEST_CASE("Should distinguish event producer When", "[EventBus]") TEST_CASE("Should distinguish event producer When", "[EventBus]")
{ {
// EventBus bus; // EventBus bus;