1 #include <sdbusplus/asio/object_server.hpp>
2 
3 #include <future>
4 #include <thread>
5 
6 #include <gmock/gmock.h>
7 
8 class DbusEnvironment : public ::testing::Environment
9 {
10   public:
11     ~DbusEnvironment();
12 
13     void SetUp() override;
14     void TearDown() override;
15     void teardown();
16 
17     static boost::asio::io_context& getIoc();
18     static std::shared_ptr<sdbusplus::asio::connection> getBus();
19     static std::shared_ptr<sdbusplus::asio::object_server> getObjServer();
20     static const char* serviceName();
21     static std::function<void()> setPromise(std::string_view name);
22     static void sleepFor(std::chrono::milliseconds);
23     static std::chrono::milliseconds measureTime(std::function<void()>);
24 
25     static void synchronizeIoc()
26     {
27         while (ioc.poll() > 0)
28         {
29         }
30     }
31 
32     template <class Functor>
33     static void synchronizedPost(Functor&& functor)
34     {
35         boost::asio::post(ioc, std::forward<Functor>(functor));
36         synchronizeIoc();
37     }
38 
39     template <class T>
40     static std::optional<T> waitForFuture(
41         std::future<T> future,
42         std::chrono::milliseconds timeout = std::chrono::seconds(10))
43     {
44         constexpr auto precission = std::chrono::milliseconds(10);
45         auto elapsed = std::chrono::milliseconds(0);
46 
47         while (future.valid() && elapsed < timeout)
48         {
49             synchronizeIoc();
50 
51             try
52             {
53                 if (future.wait_for(precission) == std::future_status::ready)
54                 {
55                     return future.get();
56                 }
57                 else
58                 {
59                     elapsed += precission;
60                 }
61             }
62             catch (const std::future_error& e)
63             {
64                 std::cerr << e.what() << "\n";
65                 return {};
66             }
67         }
68 
69         return {};
70     }
71 
72     static bool waitForFuture(
73         std::string_view name,
74         std::chrono::milliseconds timeout = std::chrono::seconds(10));
75 
76   private:
77     static std::future<bool> getFuture(std::string_view name);
78 
79     static boost::asio::io_context ioc;
80     static std::shared_ptr<sdbusplus::asio::connection> bus;
81     static std::shared_ptr<sdbusplus::asio::object_server> objServer;
82     static std::map<std::string, std::vector<std::future<bool>>> futures;
83     static bool setUp;
84 };
85