From 3f3fc7b7723698e44427e2a14a2f4906832800bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Wed, 28 Sep 2016 11:45:33 +0200 Subject: [test] add .test.cpp suffix to test case files --- test/util/async_task.test.cpp | 153 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 test/util/async_task.test.cpp (limited to 'test/util/async_task.test.cpp') diff --git a/test/util/async_task.test.cpp b/test/util/async_task.test.cpp new file mode 100644 index 0000000000..78dc79dd19 --- /dev/null +++ b/test/util/async_task.test.cpp @@ -0,0 +1,153 @@ +#include +#include +#include + +#include + +#include + +using namespace mbgl::util; + +namespace { + +class TestWorker { +public: + TestWorker(AsyncTask *async_) + : async(async_) {} + + void run() { + for (unsigned i = 0; i < 100000; ++i) { + async->send(); + } + } + + void runWithCallback(std::function cb) { + for (unsigned i = 0; i < 100000; ++i) { + async->send(); + } + + cb(); + } + +private: + AsyncTask *async; +}; + +} // namespace + +TEST(AsyncTask, RequestCoalescing) { + RunLoop loop; + + unsigned count = 0; + AsyncTask async([&count] { ++count; }); + + async.send(); + async.send(); + async.send(); + async.send(); + async.send(); + + loop.runOnce(); + + EXPECT_EQ(count, 1u); +} + +TEST(AsyncTask, DestroyShouldNotRunQueue) { + RunLoop loop; + + unsigned count = 0; + auto async = std::make_unique([&count] { ++count; }); + + async->send(); + async.reset(); + + EXPECT_EQ(count, 0u); +} + +TEST(AsyncTask, DestroyAfterSignaling) { + RunLoop loop; + + // We're creating two tasks and signal both of them; the one that gets fired first destroys + // the other one. Make sure that the second one we destroyed doesn't fire. + + std::unique_ptr task1, task2; + + task1 = std::make_unique([&] { + task2.reset(); + if (!task1) { + FAIL() << "Task was destroyed but invoked anyway"; + } + }); + task2 = std::make_unique([&] { + task1.reset(); + if (!task2) { + FAIL() << "Task was destroyed but invoked anyway"; + } + }); + + task1->send(); + task2->send(); + + loop.runOnce(); +} + +TEST(AsyncTask, RequestCoalescingMultithreaded) { + RunLoop loop; + + unsigned count = 0; + AsyncTask async([&count] { ++count; }); + + std::vector>> threads; + ThreadContext context = {"Test"}; + + unsigned numThreads = 25; + for (unsigned i = 0; i < numThreads; ++i) { + std::unique_ptr> thread = + std::make_unique>(context, &async); + + thread->invoke(&TestWorker::run); + threads.push_back(std::move(thread)); + } + + // Join all the threads + threads.clear(); + + loop.runOnce(); + + EXPECT_EQ(count, 1u); +} + +TEST(AsyncTask, ThreadSafety) { + RunLoop loop; + + unsigned count = 0; + AsyncTask async([&count] { ++count; }); + + unsigned numThreads = 25; + + auto callback = [&] { + if (!--numThreads) { + loop.stop(); + } + }; + + std::vector>> threads; + std::vector> requests; + ThreadContext context = {"Test"}; + + for (unsigned i = 0; i < numThreads; ++i) { + std::unique_ptr> thread = + std::make_unique>(context, &async); + + requests.push_back( + thread->invokeWithCallback(&TestWorker::runWithCallback, callback)); + + threads.push_back(std::move(thread)); + } + + loop.run(); + + // We expect here more than 1 but 1 would also be + // a valid result, although very unlikely (I hope). + EXPECT_GT(count, 0u); +} -- cgit v1.2.1