007-plugins.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. //
  2. // Copyright (c) 2019-2020 Ivan Baidakou (basiliscos) (the dot dmol at gmail dot com)
  3. //
  4. // Distributed under the MIT Software License
  5. //
  6. #include "catch.hpp"
  7. #include "rotor.hpp"
  8. #include "actor_test.h"
  9. #include "system_context_test.h"
  10. #include "supervisor_test.h"
  11. #include "access.h"
  12. namespace r = rotor;
  13. namespace rt = rotor::test;
  14. constexpr std::uint32_t PID_1 = 1u << 1;
  15. constexpr std::uint32_t PID_2 = 1u << 2;
  16. struct sample_plugin1_t;
  17. struct buggy_plugin_t;
  18. struct sample_plugin2_t;
  19. struct sample_actor_t : public rt::actor_test_t {
  20. using rt::actor_test_t::actor_test_t;
  21. using plugins_list_t = std::tuple<sample_plugin1_t, sample_plugin2_t>;
  22. std::uint32_t init_seq = 0;
  23. std::uint32_t deinit_seq = 0;
  24. };
  25. struct sample_actor2_t : public sample_actor_t {
  26. using sample_actor_t::sample_actor_t;
  27. using plugins_list_t = std::tuple<sample_plugin1_t, sample_plugin2_t, buggy_plugin_t>;
  28. };
  29. struct sample_plugin1_t : public r::plugin::plugin_base_t {
  30. const void *identity() const noexcept override {
  31. return static_cast<const void *>(typeid(sample_plugin1_t).name());
  32. }
  33. void activate(r::actor_base_t *actor_) noexcept override {
  34. auto &init_seq = static_cast<sample_actor_t *>(actor_)->init_seq;
  35. init_seq = (init_seq << 8 | PID_1);
  36. return r::plugin::plugin_base_t::activate(actor_);
  37. }
  38. void deactivate() noexcept override {
  39. auto &deinit_seq = static_cast<sample_actor_t *>(actor)->deinit_seq;
  40. deinit_seq = (deinit_seq << 8 | PID_1);
  41. return r::plugin::plugin_base_t::deactivate();
  42. }
  43. };
  44. struct sample_plugin2_t : public r::plugin::plugin_base_t {
  45. const void *identity() const noexcept override {
  46. return static_cast<const void *>(typeid(sample_plugin2_t).name());
  47. }
  48. void activate(r::actor_base_t *actor_) noexcept override {
  49. auto &init_seq = static_cast<sample_actor_t *>(actor_)->init_seq;
  50. init_seq = (init_seq << 8 | PID_2);
  51. return r::plugin::plugin_base_t::activate(actor_);
  52. }
  53. void deactivate() noexcept override {
  54. auto &deinit_seq = static_cast<sample_actor_t *>(actor)->deinit_seq;
  55. deinit_seq = (deinit_seq << 8 | PID_2);
  56. return r::plugin::plugin_base_t::deactivate();
  57. }
  58. };
  59. struct buggy_plugin_t : public r::plugin::plugin_base_t {
  60. const void *identity() const noexcept override { return static_cast<const void *>(typeid(buggy_plugin_t).name()); }
  61. void activate(r::actor_base_t *actor_) noexcept override {
  62. actor = actor_;
  63. actor_->commit_plugin_activation(*this, false);
  64. }
  65. };
  66. TEST_CASE("init/deinit sequence", "[plugin]") {
  67. rt::system_context_test_t system_context;
  68. using builder_t = typename sample_actor_t::template config_builder_t<sample_actor_t>;
  69. auto builder = builder_t([&](auto &) {}, system_context);
  70. auto actor = std::move(builder).timeout(rt::default_timeout).finish();
  71. const void *ptr = actor.get();
  72. CHECK(actor->access<rt::to::get_plugin>(ptr) == nullptr);
  73. REQUIRE(actor->get_activating_plugins().size() == 2);
  74. REQUIRE(actor->get_deactivating_plugins().size() == 0);
  75. actor->activate_plugins();
  76. REQUIRE((actor->init_seq == ((PID_1 << 8) | PID_2)));
  77. REQUIRE(actor->get_activating_plugins().size() == 0);
  78. REQUIRE(actor->get_deactivating_plugins().size() == 0);
  79. actor->deactivate_plugins();
  80. REQUIRE((actor->deinit_seq == ((PID_2 << 8) | PID_1)));
  81. REQUIRE(actor->get_deactivating_plugins().size() == 0);
  82. }
  83. TEST_CASE("fail init-plugin sequence", "[plugin]") {
  84. rt::system_context_test_t system_context;
  85. using builder_t = typename sample_actor2_t::template config_builder_t<sample_actor2_t>;
  86. auto builder = builder_t([&](auto &) {}, system_context);
  87. auto actor = std::move(builder).timeout(rt::default_timeout).finish();
  88. REQUIRE(actor->get_activating_plugins().size() == 3);
  89. REQUIRE(actor->get_deactivating_plugins().size() == 0);
  90. actor->activate_plugins();
  91. CHECK(actor->init_seq == ((PID_1 << 8) | PID_2));
  92. REQUIRE(actor->get_activating_plugins().size() == 1);
  93. REQUIRE(actor->get_deactivating_plugins().size() == 0);
  94. CHECK(actor->deinit_seq == ((PID_2 << 8) | PID_1));
  95. }