diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2016-09-28 11:45:33 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2016-09-28 16:34:22 +0200 |
commit | 3f3fc7b7723698e44427e2a14a2f4906832800bf (patch) | |
tree | 5acadfa4d77817c41f612c89c93925a149cbcfc0 /test/actor/actor.test.cpp | |
parent | a8b007daa0e85ea4b1a4898fd591d55d0117cc85 (diff) | |
download | qtlocation-mapboxgl-3f3fc7b7723698e44427e2a14a2f4906832800bf.tar.gz |
[test] add .test.cpp suffix to test case files
Diffstat (limited to 'test/actor/actor.test.cpp')
-rw-r--r-- | test/actor/actor.test.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/test/actor/actor.test.cpp b/test/actor/actor.test.cpp new file mode 100644 index 0000000000..7bb76784d6 --- /dev/null +++ b/test/actor/actor.test.cpp @@ -0,0 +1,139 @@ +#include <mbgl/actor/actor.hpp> +#include <mbgl/actor/thread_pool.hpp> + +#include <mbgl/test/util.hpp> + +#include <chrono> +#include <functional> +#include <future> + +using namespace mbgl; +using namespace std::chrono_literals; + +TEST(Actor, Construction) { + // Construction is currently synchronous. It may become asynchronous in the future. + + struct Test { + Test(ActorRef<Test>, bool& constructed) { + constructed = true; + }; + }; + + ThreadPool pool { 1 }; + bool constructed = false; + Actor<Test> test(pool, std::ref(constructed)); + + EXPECT_TRUE(constructed); +} + +TEST(Actor, DestructionClosesMailbox) { + // Destruction blocks until the actor is not receiving. + + struct Test { + std::promise<void> promise; + std::future<void> future; + std::atomic<bool> waited; + + Test(ActorRef<Test>, std::promise<void> promise_, std::future<void> future_) + : promise(std::move(promise_)), + future(std::move(future_)), + waited(false) { + } + + ~Test() { + EXPECT_TRUE(waited.load()); + } + + void wait() { + promise.set_value(); + future.wait(); + std::this_thread::sleep_for(1ms); + waited = true; + } + }; + + ThreadPool pool { 1 }; + + std::promise<void> enteredPromise; + std::future<void> enteredFuture = enteredPromise.get_future(); + + std::promise<void> exitingPromise; + std::future<void> exitingFuture = exitingPromise.get_future(); + + Actor<Test> test(pool, std::move(enteredPromise), std::move(exitingFuture)); + + test.invoke(&Test::wait); + enteredFuture.wait(); + exitingPromise.set_value(); +} + +TEST(Actor, OrderedMailbox) { + // Messages are processed in order. + + struct Test { + int last = 0; + std::promise<void> promise; + + Test(ActorRef<Test>, std::promise<void> promise_) + : promise(std::move(promise_)) { + } + + void receive(int i) { + EXPECT_EQ(i, last + 1); + last = i; + } + + void end() { + promise.set_value(); + } + }; + + ThreadPool pool { 1 }; + + std::promise<void> endedPromise; + std::future<void> endedFuture = endedPromise.get_future(); + Actor<Test> test(pool, std::move(endedPromise)); + + for (auto i = 1; i <= 10; ++i) { + test.invoke(&Test::receive, i); + } + + test.invoke(&Test::end); + endedFuture.wait(); +} + +TEST(Actor, NonConcurrentMailbox) { + // An individual actor is never itself concurrent. + + struct Test { + int last = 0; + std::promise<void> promise; + + Test(ActorRef<Test>, std::promise<void> promise_) + : promise(std::move(promise_)) { + } + + void receive(int i) { + EXPECT_EQ(i, last + 1); + last = i; + std::this_thread::sleep_for(1ms); + } + + void end() { + promise.set_value(); + } + }; + + ThreadPool pool { 10 }; + + std::promise<void> endedPromise; + std::future<void> endedFuture = endedPromise.get_future(); + Actor<Test> test(pool, std::move(endedPromise)); + + for (auto i = 1; i <= 10; ++i) { + test.invoke(&Test::receive, i); + } + + test.invoke(&Test::end); + endedFuture.wait(); +} |