123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- // SPDX-License-Identifier: MIT
- // SPDX-FileCopyrightText: 2022 Ivan Baidakou
- #if defined(__ANDROID__)
- #undef __ANDROID__
- #endif
- #include "catch.hpp"
- #include "rotor-light/planner.hpp"
- #include "rotor-light/queue.hpp"
- #include "rotor-light/supervisor.hpp"
- #include <string>
- using namespace rotor_light;
- using MessageStorage =
- traits::MessageStorage<message::ChangeState, message::ChangeStateAck>;
- using AppQueue = Queue<MessageStorage, 5>;
- using AppPlanner = Planner<1>;
- TEST_CASE("normal hierarchy", "[hierarchy]") {
- struct A1 : Actor<1> {
- using Parent = Actor<1>;
- using Parent::Parent;
- };
- struct S1_1 : Supervisor<3, A1> {
- using Parent = Supervisor<3, A1>;
- using Parent::Parent;
- };
- struct S1_2 : Supervisor<3, S1_1> {
- using Parent = Supervisor<3, S1_1>;
- using Parent::Parent;
- };
- AppQueue queue;
- AppPlanner planner;
- Context context{&queue, &planner, nullptr};
- S1_2 sup;
- sup.bind(context);
- auto sup2 = sup.get_child<0>();
- auto act = sup2->get_child<0>();
- sup.start();
- sup.process();
- CHECK(sup.get_state() == State::operational);
- CHECK(sup2->get_state() == State::operational);
- CHECK(act->get_state() == State::operational);
- SECTION("stop root supervisor") {
- sup.stop();
- sup.process();
- CHECK(sup.get_state() == State::off);
- CHECK(sup2->get_state() == State::off);
- CHECK(act->get_state() == State::off);
- }
- SECTION("manual stop") {
- sup2->stop();
- sup.process();
- CHECK(sup.get_state() == State::operational);
- CHECK(sup2->get_state() == State::off);
- CHECK(act->get_state() == State::off);
- sup.stop();
- sup.process();
- CHECK(sup.get_state() == State::off);
- }
- }
- TEST_CASE("auto collapse hierarchy", "[hierarchy]") {
- struct A1 : Actor<1> {
- using Parent = Actor<1>;
- using Parent::Parent;
- };
- struct A2 : Actor<1> {
- using Parent = Actor<1>;
- using Parent::Parent;
- void advance_init() override {
- send<ctx::thread, message::ChangeStateAck>(0, supervisor->get_id(), id,
- State::initialized, false);
- init_attempted = true;
- }
- bool init_attempted = false;
- };
- struct S1_1 : Supervisor<3, A1, A2> {
- using Parent = Supervisor<3, A1, A2>;
- using Parent::Parent;
- };
- struct S1_2 : Supervisor<3, S1_1> {
- using Parent = Supervisor<3, S1_1>;
- using Parent::Parent;
- };
- AppQueue queue;
- AppPlanner planner;
- Context context{&queue, &planner, nullptr};
- S1_2 sup;
- sup.bind(context);
- auto sup2 = sup.get_child<0>();
- auto act1 = sup2->get_child<0>();
- auto act2 = sup2->get_child<1>();
- sup.start();
- sup.process();
- CHECK(sup.get_state() == State::off);
- CHECK(sup2->get_state() == State::off);
- CHECK(act1->get_state() == State::off);
- CHECK(act2->get_state() == State::off);
- REQUIRE(act2->init_attempted);
- }
|