| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- #define BOOST_TEST_DYN_LINK
- #include "core/tristate_obj.h"
- #include "utility/bit_operations.hpp"
- #include "utility/debug_utility.hpp"
- #include <boost/asio/co_spawn.hpp>
- #include <boost/asio/detached.hpp>
- #include <boost/asio/high_resolution_timer.hpp>
- #include <boost/asio/this_coro.hpp>
- #include <boost/asio/use_awaitable.hpp>
- #include <boost/test/unit_test.hpp>
- #include <chrono>
- using boost::asio::awaitable;
- using boost::asio::co_spawn;
- using boost::asio::detached;
- using boost::asio::use_awaitable;
- using namespace sophiar;
- using namespace std::chrono_literals;
- awaitable<void> test_tristate_obj_1() {
- struct type_a : public tristate_obj {
- unsigned int cnt = 0;
- awaitable<bool> on_init(const nlohmann::json &) noexcept {
- set_bit(cnt, 0);
- co_return true;
- }
- awaitable<bool> on_start(const nlohmann::json &) noexcept {
- set_bit(cnt, 1);
- co_return true;
- }
- awaitable<void> on_stop() noexcept {
- set_bit(cnt, 2);
- co_return;
- }
- awaitable<void> on_reset() noexcept {
- set_bit(cnt, 3);
- co_return;
- }
- } node_a;
- co_await node_a.init({});
- BOOST_TEST(node_a.cnt == 0b0001);
- BOOST_TEST((node_a.get_state() == type_a::state_type::PENDING));
- co_await node_a.start({});
- BOOST_TEST(node_a.cnt == 0b0011);
- BOOST_TEST((node_a.get_state() == type_a::state_type::RUNNING));
- co_await node_a.stop();
- BOOST_TEST(node_a.cnt == 0b0111);
- BOOST_TEST((node_a.get_state() == type_a::state_type::PENDING));
- co_await node_a.reset();
- BOOST_TEST(node_a.cnt == 0b1111);
- BOOST_TEST((node_a.get_state() == type_a::state_type::INITIAL));
- node_a.cnt = 0;
- co_await node_a.start({}); // test start before init
- BOOST_TEST(node_a.cnt == 0b0000);
- BOOST_TEST((node_a.get_state() == type_a::state_type::INITIAL));
- co_await node_a.init({});
- co_await node_a.start({});
- BOOST_TEST(node_a.cnt == 0b0011);
- BOOST_TEST((node_a.get_state() == type_a::state_type::RUNNING));
- co_await node_a.reset(); // test force reset
- BOOST_TEST(node_a.cnt == 0b1111);
- BOOST_TEST((node_a.get_state() == type_a::state_type::INITIAL));
- co_return;
- }
- awaitable<void> test_tristate_obj_2() {
- struct type_a : public tristate_obj {
- int cnt = 0;
- boost::asio::high_resolution_timer timer;
- type_a()
- : timer(*global_context) {}
- awaitable<bool> on_init(const nlohmann::json &) noexcept {
- timer.expires_from_now(100ms);
- co_await timer.async_wait(use_awaitable);
- set_bit(cnt, 0);
- co_return true;
- }
- awaitable<bool> on_start(const nlohmann::json &) noexcept {
- timer.expires_from_now(100ms);
- co_await timer.async_wait(use_awaitable);
- set_bit(cnt, 1);
- co_return true;
- }
- awaitable<void> on_stop() noexcept {
- timer.expires_from_now(100ms);
- co_await timer.async_wait(use_awaitable);
- set_bit(cnt, 2);
- co_return;
- }
- awaitable<void> on_reset() noexcept {
- timer.expires_from_now(100ms);
- co_await timer.async_wait(use_awaitable);
- set_bit(cnt, 3);
- co_return;
- }
- } node_a;
- co_spawn(co_await boost::asio::this_coro::executor, [&]() -> awaitable<void> {
- co_await coro_sleep(50ms);
- co_await node_a.reset();
- co_return;
- }, detached);
- BOOST_TEST((co_await node_a.init({}) == false));
- BOOST_TEST(node_a.cnt == 0b1000);
- BOOST_TEST((node_a.get_state() == type_a::state_type::INITIAL));
- node_a.cnt = 0;
- BOOST_TEST((co_await node_a.init({}) == true));
- BOOST_TEST((node_a.get_state() == type_a::state_type::PENDING));
- co_spawn(co_await boost::asio::this_coro::executor, [&]() -> awaitable<void> {
- co_await coro_sleep(50ms);
- co_await node_a.stop();
- co_return;
- }, detached);
- BOOST_TEST((co_await node_a.start({}) == false));
- BOOST_TEST(node_a.cnt == 0b0101);
- BOOST_TEST((node_a.get_state() == type_a::state_type::PENDING));
- node_a.cnt = 0b0001;
- co_spawn(co_await boost::asio::this_coro::executor, [&]() -> awaitable<void> {
- co_await coro_sleep(50ms);
- co_await node_a.reset();
- co_return;
- }, detached);
- BOOST_TEST((co_await node_a.start({}) == false));
- BOOST_TEST(node_a.cnt = 0b0101);
- BOOST_TEST((node_a.get_state() == type_a::state_type::PENDING));
- co_await coro_sleep(150ms);
- BOOST_TEST(node_a.cnt == 0b1101);
- BOOST_TEST((node_a.get_state() == type_a::state_type::INITIAL));
- co_return;
- }
- awaitable<void> test_tristate_obj_3() {
- struct type_a : public tristate_obj {
- int cnt = 0;
- boost::asio::high_resolution_timer timer;
- type_a()
- : timer(*global_context) {}
- awaitable<bool> on_init(const nlohmann::json &) noexcept {
- timer.expires_from_now(100ms);
- co_await timer.async_wait(use_awaitable);
- ++cnt;
- co_return true;
- }
- awaitable<bool> on_start(const nlohmann::json &) noexcept {
- timer.expires_from_now(100ms);
- co_await timer.async_wait(use_awaitable);
- ++cnt;
- co_return true;
- }
- awaitable<void> on_stop() noexcept {
- timer.expires_from_now(100ms);
- co_await timer.async_wait(use_awaitable);
- ++cnt;
- co_return;
- }
- awaitable<void> on_reset() noexcept {
- timer.expires_from_now(100ms);
- co_await timer.async_wait(use_awaitable);
- ++cnt;
- co_return;
- }
- } node_a;
- node_a.cnt = 0;
- co_spawn(co_await boost::asio::this_coro::executor, [&]() -> awaitable<void> {
- BOOST_TEST(co_await node_a.init({}) == true);
- BOOST_TEST(node_a.cnt == 1);
- }, detached);
- BOOST_TEST(co_await node_a.init({}) == true);
- BOOST_TEST((node_a.get_state() == type_a::state_type::PENDING));
- BOOST_TEST(node_a.cnt == 1);
- node_a.cnt = 0;
- co_spawn(co_await boost::asio::this_coro::executor, [&]() -> awaitable<void> {
- BOOST_TEST(co_await node_a.start({}) == true);
- BOOST_TEST(node_a.cnt == 1);
- }, detached);
- BOOST_TEST(co_await node_a.start({}) == true);
- BOOST_TEST((node_a.get_state() == type_a::state_type::RUNNING));
- BOOST_TEST(node_a.cnt == 1);
- node_a.cnt = 0;
- co_spawn(co_await boost::asio::this_coro::executor, [&]() -> awaitable<void> {
- co_await node_a.stop();
- BOOST_TEST(node_a.cnt == 1);
- }, detached);
- co_await node_a.stop();
- BOOST_TEST((node_a.get_state() == type_a::state_type::PENDING));
- BOOST_TEST(node_a.cnt == 1);
- node_a.cnt = 0;
- co_spawn(co_await boost::asio::this_coro::executor, [&]() -> awaitable<void> {
- co_await node_a.reset();
- BOOST_TEST(node_a.cnt == 1);
- }, detached);
- co_await node_a.reset();
- BOOST_TEST((node_a.get_state() == type_a::state_type::INITIAL));
- BOOST_TEST(node_a.cnt == 1);
- node_a.cnt = 0;
- co_spawn(co_await boost::asio::this_coro::executor, [&]() -> awaitable<void> {
- co_await coro_sleep(50ms);
- co_await node_a.reset();
- co_return;
- }, detached);
- co_spawn(co_await boost::asio::this_coro::executor, [&]() -> awaitable<void> {
- BOOST_TEST(co_await node_a.init({}) == false);
- BOOST_TEST(node_a.cnt == 1);
- }, detached);
- BOOST_TEST(co_await node_a.init({}) == false);
- BOOST_TEST((node_a.get_state() == type_a::state_type::INITIAL));
- BOOST_TEST(node_a.cnt == 1);
- co_await node_a.init({});
- node_a.cnt = 0;
- co_spawn(co_await boost::asio::this_coro::executor, [&]() -> awaitable<void> {
- co_await coro_sleep(50ms);
- co_await node_a.stop();
- co_return;
- }, detached);
- co_spawn(co_await boost::asio::this_coro::executor, [&]() -> awaitable<void> {
- BOOST_TEST(co_await node_a.start({}) == false);
- BOOST_TEST(node_a.cnt == 1);
- }, detached);
- BOOST_TEST(co_await node_a.start({}) == false);
- BOOST_TEST((node_a.get_state() == type_a::state_type::PENDING));
- BOOST_TEST(node_a.cnt == 1);
- }
- BOOST_AUTO_TEST_CASE(test_tristate_obj) {
- initialize({});
- co_spawn(*global_context, test_tristate_obj_1(), detached);
- co_spawn(*global_context, test_tristate_obj_2(), detached);
- co_spawn(*global_context, test_tristate_obj_3(), detached);
- global_context->run();
- }
|