// Copyright (c) 2011-2016 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include #include using namespace System; TEST(EventTests, newEventIsNotSet) { Dispatcher dispatcher; Event event(dispatcher); ASSERT_FALSE(event.get()); } TEST(EventTests, eventIsWorking) { Dispatcher dispatcher; Event event(dispatcher); Context<> context(dispatcher, [&]() { event.set(); }); event.wait(); ASSERT_TRUE(event.get()); } TEST(EventTests, movedEventIsWorking) { Dispatcher dispatcher; Event event{Event(dispatcher)}; Context<> context(dispatcher, [&]() { event.set(); }); event.wait(); ASSERT_TRUE(event.get()); } TEST(EventTests, movedEventKeepsState) { Dispatcher dispatcher; Event event(dispatcher); Context<> context(dispatcher, [&]() { event.set(); }); event.wait(); Event event2(std::move(event)); ASSERT_TRUE(event2.get()); } TEST(EventTests, movedEventIsWorking2) { Dispatcher dispatcher; Event srcEvent(dispatcher); Event event; event = std::move(srcEvent); Context<> context(dispatcher, [&]() { event.set(); }); event.wait(); ASSERT_TRUE(event.get()); } TEST(EventTests, movedEventKeepsState2) { Dispatcher dispatcher; Event event(dispatcher); Context<> context(dispatcher, [&]() { event.set(); }); event.wait(); Event dstEvent; dstEvent = std::move(event); ASSERT_TRUE(dstEvent.get()); } TEST(EventTests, moveClearsEventState) { Dispatcher dispatcher; Event event(dispatcher); Context<> context(dispatcher, [&]() { event.set(); }); event.wait(); ASSERT_TRUE(event.get()); Event srcEvent(dispatcher); event = std::move(srcEvent); ASSERT_FALSE(event.get()); } TEST(EventTests, movedEventIsTheSame) { Dispatcher dispatcher; Event event(dispatcher); auto eventPtr1 = &event; Event srcEvent(dispatcher); event = std::move(srcEvent); auto eventPtr2 = &event; ASSERT_EQ(eventPtr1, eventPtr2); } TEST(EventTests, eventIsWorkingAfterClear) { Dispatcher dispatcher; Event event(dispatcher); event.clear(); Context<> context(dispatcher, [&]() { event.set(); }); event.wait(); ASSERT_TRUE(event.get()); } TEST(EventTests, eventIsWorkingAfterClearOnWaiting) { Dispatcher dispatcher; Event event(dispatcher); Context<> context(dispatcher, [&]() { event.clear(); event.set(); }); event.wait(); ASSERT_TRUE(event.get()); } TEST(EventTests, eventIsReusableAfterClear) { Dispatcher dispatcher; Event event(dispatcher); Context<> context(dispatcher, [&]() { event.set(); dispatcher.yield(); event.set(); }); event.wait(); event.clear(); event.wait(); SUCCEED(); } TEST(EventTests, eventSetIsWorkingOnNewEvent) { Dispatcher dispatcher; Event event(dispatcher); event.set(); ASSERT_TRUE(event.get()); } TEST(EventTests, setActuallySets) { Dispatcher dispatcher; Event event(dispatcher); Context<> context(dispatcher, [&]() { event.set(); }); event.wait(); SUCCEED(); } TEST(EventTests, setJustSets) { Dispatcher dispatcher; Event event(dispatcher); bool done = false; Context<> context(dispatcher, [&]() { event.wait(); done = true; }); dispatcher.yield(); ASSERT_FALSE(done); event.set(); ASSERT_FALSE(done); dispatcher.yield(); ASSERT_TRUE(done); } TEST(EventTests, setSetsOnlyOnce) { Dispatcher dispatcher; Event event(dispatcher); auto i = 0; Context<> context(dispatcher, [&]() { event.set(); event.set(); event.set(); dispatcher.yield(); i++; }); event.wait(); i++; event.wait(); ASSERT_EQ(i, 1); dispatcher.yield(); ASSERT_EQ(i, 2); } TEST(EventTests, waitIsWaiting) { Dispatcher dispatcher; Event event(dispatcher); bool done = false; Context<> context(dispatcher, [&]() { event.wait(); done = true; }); dispatcher.yield(); ASSERT_FALSE(done); event.set(); dispatcher.yield(); ASSERT_TRUE(done); } TEST(EventTests, setEventIsNotWaiting) { Dispatcher dispatcher; Event event(dispatcher); auto i = 0; Context<> context(dispatcher, [&]() { event.set(); dispatcher.yield(); i++; }); event.wait(); i++; ASSERT_EQ(i, 1); event.wait(); ASSERT_EQ(i, 1); dispatcher.yield(); ASSERT_EQ(i, 2); } TEST(EventTests, waitIsParallel) { Dispatcher dispatcher; Event event(dispatcher); auto i = 0; Context<> context(dispatcher, [&]() { i++; event.set(); }); ASSERT_EQ(i, 0); event.wait(); ASSERT_EQ(i, 1); } TEST(EventTests, waitIsMultispawn) { Dispatcher dispatcher; Event event(dispatcher); auto i = 0; Context<> context(dispatcher, [&]() { event.wait(); i++; }); Context<> contextSecond(dispatcher, [&]() { event.wait(); i++; }); ASSERT_EQ(i, 0); dispatcher.yield(); ASSERT_EQ(i, 0); event.set(); dispatcher.yield(); ASSERT_EQ(i, 2); } TEST(EventTests, setEventInPastUnblocksWaitersEvenAfterClear) { Dispatcher dispatcher; Event event(dispatcher); auto i = 0; Context<> context(dispatcher, [&]() { event.wait(); i++; }); Context<> contextSecond(dispatcher, [&]() { event.wait(); i++; }); dispatcher.yield(); ASSERT_EQ(i, 0); event.set(); event.clear(); dispatcher.yield(); ASSERT_EQ(i, 2); } TEST(EventTests, waitIsInterruptibleOnFront) { Dispatcher dispatcher; Event event(dispatcher); bool interrupted = false; Context<>(dispatcher, [&] { try { event.wait(); } catch (InterruptedException&) { interrupted = true; } }); ASSERT_TRUE(interrupted); } TEST(EventTests, waitIsInterruptibleOnBody) { Dispatcher dispatcher; Event event(dispatcher); Event event2(dispatcher); bool interrupted = false; Context<> context(dispatcher, [&] { try { event2.set(); event.wait(); } catch (InterruptedException&) { interrupted = true; } }); event2.wait(); context.interrupt(); context.get(); ASSERT_TRUE(interrupted); }