// 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 #include #include using namespace System; class RemoteContextTests : public testing::Test { public: Dispatcher dispatcher; }; TEST_F(RemoteContextTests, getReturnsResult) { RemoteContext context(dispatcher, [&] { return 2; }); ASSERT_EQ(2, context.get()); } TEST_F(RemoteContextTests, getRethrowsException) { RemoteContext<> context(dispatcher, [&] { throw std::string("Hi there!"); }); ASSERT_THROW(context.get(), std::string); } TEST_F(RemoteContextTests, destructorIgnoresException) { ASSERT_NO_THROW(RemoteContext<>(dispatcher, [&] { throw std::string("Hi there!"); })); } TEST_F(RemoteContextTests, canBeUsedWithoutObject) { ASSERT_EQ(42, RemoteContext(dispatcher, [&] { return 42; }).get()); } TEST_F(RemoteContextTests, interruptIsInterruptingWait) { ContextGroup cg(dispatcher); cg.spawn([&] { RemoteContext<> context(dispatcher, [&] { std::this_thread::sleep_for(std::chrono::milliseconds(10)); }); ASSERT_NO_THROW(context.wait()); ASSERT_TRUE(dispatcher.interrupted()); }); cg.interrupt(); cg.wait(); } TEST_F(RemoteContextTests, interruptIsInterruptingGet) { ContextGroup cg(dispatcher); cg.spawn([&] { RemoteContext<> context(dispatcher, [&] { std::this_thread::sleep_for(std::chrono::milliseconds(10)); }); ASSERT_NO_THROW(context.wait()); ASSERT_TRUE(dispatcher.interrupted()); }); cg.interrupt(); cg.wait(); } TEST_F(RemoteContextTests, destructorIgnoresInterrupt) { ContextGroup cg(dispatcher); cg.spawn([&] { ASSERT_NO_THROW(RemoteContext<>(dispatcher, [&] { std::this_thread::sleep_for(std::chrono::milliseconds(10)); })); }); cg.interrupt(); cg.wait(); } TEST_F(RemoteContextTests, canExecuteOtherContextsWhileWaiting) { auto start = std::chrono::high_resolution_clock::now(); ContextGroup cg(dispatcher); cg.spawn([&] { RemoteContext<> context(dispatcher, [&] { std::this_thread::sleep_for(std::chrono::milliseconds(100)); }); }); cg.spawn([&] { System::Timer(dispatcher).sleep(std::chrono::milliseconds(50)); auto end = std::chrono::high_resolution_clock::now(); ASSERT_GE(std::chrono::duration_cast(end - start).count(), 50); ASSERT_LT(std::chrono::duration_cast(end - start).count(), 100); }); cg.wait(); } TEST_F(RemoteContextTests, waitMethodWaitsForContexCompletion) { auto start = std::chrono::high_resolution_clock::now(); ContextGroup cg(dispatcher); cg.spawn([&] { RemoteContext<> context(dispatcher, [&] { std::this_thread::sleep_for(std::chrono::milliseconds(10)); }); }); cg.wait(); auto end = std::chrono::high_resolution_clock::now(); ASSERT_GE(std::chrono::duration_cast(end - start).count(), 10); } TEST_F(RemoteContextTests, waitMethodWaitsForContexCompletionOnInterrupt) { auto start = std::chrono::high_resolution_clock::now(); ContextGroup cg(dispatcher); cg.spawn([&] { RemoteContext<> context(dispatcher, [&] { std::this_thread::sleep_for(std::chrono::milliseconds(10)); }); }); cg.interrupt(); cg.wait(); auto end = std::chrono::high_resolution_clock::now(); ASSERT_GE(std::chrono::duration_cast(end - start).count(), 10); }