121-wx_ping_ping.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. //
  2. // Copyright (c) 2019-2024 Ivan Baidakou (basiliscos) (the dot dmol at gmail dot com)
  3. //
  4. // Distributed under the MIT Software License
  5. //
  6. #include <catch2/catch_test_macros.hpp>
  7. #include "rotor.hpp"
  8. #include "rotor/wx.hpp"
  9. #include "supervisor_wx_test.h"
  10. #include <wx/evtloop.h>
  11. #include <wx/apptrait.h>
  12. #include "access.h"
  13. IMPLEMENT_APP_NO_MAIN(rotor::test::RotorApp)
  14. namespace r = rotor;
  15. namespace rx = rotor::wx;
  16. namespace rt = rotor::test;
  17. struct ping_t {};
  18. struct pong_t {};
  19. static std::uint32_t destroyed = 0;
  20. struct pinger_t : public r::actor_base_t {
  21. std::uint32_t ping_sent = 0;
  22. std::uint32_t pong_received = 0;
  23. rotor::address_ptr_t ponger_addr;
  24. using r::actor_base_t::actor_base_t;
  25. ~pinger_t() { destroyed += 1; }
  26. void set_ponger_addr(const rotor::address_ptr_t &addr) { ponger_addr = addr; }
  27. void configure(r::plugin::plugin_base_t &plugin) noexcept override {
  28. r::actor_base_t::configure(plugin);
  29. plugin.with_casted<r::plugin::starter_plugin_t>([](auto &p) { p.subscribe_actor(&pinger_t::on_pong); });
  30. }
  31. void on_start() noexcept override {
  32. r::actor_base_t::on_start();
  33. send<ping_t>(ponger_addr);
  34. ++ping_sent;
  35. }
  36. void on_pong(rotor::message_t<pong_t> &) noexcept {
  37. ++pong_received;
  38. supervisor->shutdown();
  39. auto loop = wxEventLoopBase::GetActive();
  40. loop->ScheduleExit();
  41. }
  42. };
  43. struct ponger_t : public r::actor_base_t {
  44. std::uint32_t pong_sent = 0;
  45. std::uint32_t ping_received = 0;
  46. rotor::address_ptr_t pinger_addr;
  47. using r::actor_base_t::actor_base_t;
  48. ~ponger_t() { destroyed += 3; }
  49. void set_pinger_addr(const rotor::address_ptr_t &addr) { pinger_addr = addr; }
  50. void configure(r::plugin::plugin_base_t &plugin) noexcept override {
  51. plugin.with_casted<r::plugin::starter_plugin_t>([](auto &p) { p.subscribe_actor(&ponger_t::on_ping); });
  52. }
  53. void on_ping(rotor::message_t<ping_t> &) noexcept {
  54. ++ping_received;
  55. send<pong_t>(pinger_addr);
  56. ++pong_sent;
  57. }
  58. };
  59. TEST_CASE("ping/pong ", "[supervisor][wx]") {
  60. using app_t = rotor::test::RotorApp;
  61. auto app = new app_t();
  62. auto timeout = r::pt::milliseconds{10};
  63. app->CallOnInit();
  64. wxEventLoopBase *loop = app->GetTraits()->CreateEventLoop();
  65. wxEventLoopBase::SetActive(loop);
  66. rx::system_context_ptr_t system_context{new rx::system_context_wx_t(app)};
  67. wxEvtHandler handler;
  68. auto sup =
  69. system_context->create_supervisor<rt::supervisor_wx_test_t>().handler(&handler).timeout(timeout).finish();
  70. sup->start();
  71. auto pinger = sup->create_actor<pinger_t>().timeout(timeout).finish();
  72. auto ponger = sup->create_actor<ponger_t>().timeout(timeout).finish();
  73. pinger->set_ponger_addr(static_cast<r::actor_base_t *>(ponger.get())->get_address());
  74. ponger->set_pinger_addr(static_cast<r::actor_base_t *>(pinger.get())->get_address());
  75. sup->start();
  76. loop->Run();
  77. REQUIRE(pinger->ping_sent == 1);
  78. REQUIRE(pinger->pong_received == 1);
  79. REQUIRE(ponger->pong_sent == 1);
  80. REQUIRE(ponger->ping_received == 1);
  81. pinger.reset();
  82. ponger.reset();
  83. REQUIRE(destroyed == 4);
  84. REQUIRE(static_cast<r::actor_base_t *>(sup.get())->access<rt::to::state>() == r::state_t::SHUT_DOWN);
  85. REQUIRE(sup->get_leader_queue().size() == 0);
  86. CHECK(rt::empty(sup->get_subscription()));
  87. delete app;
  88. }