/workspaces/astro/sol3-sdk/cpp/sol3/process_manager/process_manager_test_fixture.h Source File

Space-ng SDK: /workspaces/astro/sol3-sdk/cpp/sol3/process_manager/process_manager_test_fixture.h Source File
Space-ng SDK
process_manager_test_fixture.h
Go to the documentation of this file.
1 // Copyright (c) Space-ng, inc. All rights reserved.
2 #pragma once
3 
4 #include "sol3/asio/strand.h"
5 #include "sol3/core/logging.h"
6 
7 #include <boost/asio/any_io_executor.hpp>
8 #include <boost/asio/dispatch.hpp>
9 #include <boost/asio/io_context.hpp>
10 #include <boost/asio/steady_timer.hpp>
11 #include <boost/asio/strand.hpp>
12 #include <boost/system/detail/error_code.hpp>
13 #include <gtest/gtest.h>
14 
15 #include <atomic>
16 #include <chrono>
17 #include <condition_variable>
18 #include <functional>
19 #include <memory>
20 #include <mutex>
21 #include <thread>
22 
23 namespace sol3::process_manager {
24 
25 class StrandTestFixture : public ::testing::Test {
26  protected:
27  void runAfter(std::chrono::milliseconds delay, std::function<void()> func) {
28  runAfterOn(io_.get_executor(), delay, std::move(func));
29  }
30 
32  std::chrono::milliseconds delay, std::function<void()> func) {
33  runAfterOn(strand_, delay, std::move(func));
34  }
35 
37  std::chrono::milliseconds timeout,
38  std::function<void()> on_success_in_strand) {
39  std::atomic<bool> done{false};
40  std::mutex mutex;
41  std::condition_variable cv;
42 
43  std::thread watchdog([&] {
44  std::unique_lock lock(mutex);
45  bool timed_out =
46  !cv.wait_for(lock, timeout, [&done] { return done.load(); });
47  if (timed_out) {
48  ADD_FAILURE() << "io loop did not exit within " << timeout.count()
49  << "ms";
50  io_.stop();
51  }
52  });
53 
54  try {
55  io_.run();
56  } catch (...) {
57  done = true;
58  cv.notify_one();
59  if (watchdog.joinable()) {
60  watchdog.join();
61  }
62  throw;
63  }
64  done = true;
65  cv.notify_one();
66  watchdog.join();
67  io_.restart();
68  if (io_.stopped()) {
69  ADD_FAILURE() << "Watchdog timed out. Cannot run final checks";
70  return;
71  }
72  boost::asio::dispatch(strand_, on_success_in_strand);
73  io_.restart();
74  io_.run_one();
75  }
76 
77  void SetUp() override {
79  strand_ = boost::asio::make_strand(io_);
80  }
81 
82  boost::asio::io_context io_;
83  asio::Strand strand_{boost::asio::make_strand(io_)};
84 
85  private:
86  static void runAfterOn(
87  boost::asio::any_io_executor ctx,
88  std::chrono::milliseconds delay,
89  std::function<void()> func) {
90  auto timer = std::make_shared<boost::asio::steady_timer>(ctx, delay);
91  timer->async_wait(
92  [timer, func = std::move(func)](boost::system::error_code ec) {
93  if (ec) {
94  ADD_FAILURE() << "Unexpected error in timer: " << ec.message();
95  return;
96  }
97  func();
98  });
99  }
100 };
101 
102 } // namespace sol3::process_manager
Definition: process_manager_test_fixture.h:25
asio::Strand strand_
Definition: process_manager_test_fixture.h:83
void SetUp() override
Definition: process_manager_test_fixture.h:77
void runAfterInStrand(std::chrono::milliseconds delay, std::function< void()> func)
Definition: process_manager_test_fixture.h:31
boost::asio::io_context io_
Definition: process_manager_test_fixture.h:82
void runAfter(std::chrono::milliseconds delay, std::function< void()> func)
Definition: process_manager_test_fixture.h:27
void runWithWatchdog(std::chrono::milliseconds timeout, std::function< void()> on_success_in_strand)
Definition: process_manager_test_fixture.h:36
void dispatch(TExecutor const &ex, TClass *obj, TFunc &&func)
Definition: handlers.h:172
boost::asio::strand< boost::asio::io_context::executor_type > Strand
Definition: strand.h:8
void setupLogging()
Definition: process.h:20