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