007-plugins.cpp 4.3 KB

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