1 #include "dbus_environment.hpp"
2 
3 #include <future>
4 #include <thread>
5 
6 DbusEnvironment::~DbusEnvironment()
7 {
8     teardown();
9 }
10 
11 void DbusEnvironment::SetUp()
12 {
13     if (setUp == false)
14     {
15         setUp = true;
16 
17         bus = std::make_shared<sdbusplus::asio::connection>(ioc);
18         bus->request_name(serviceName());
19 
20         objServer = std::make_unique<sdbusplus::asio::object_server>(bus);
21     }
22 }
23 
24 void DbusEnvironment::TearDown()
25 {
26     ioc.poll();
27 
28     futures.clear();
29 }
30 
31 void DbusEnvironment::teardown()
32 {
33     if (setUp == true)
34     {
35         setUp = false;
36 
37         objServer = nullptr;
38         bus = nullptr;
39     }
40 }
41 
42 boost::asio::io_context& DbusEnvironment::getIoc()
43 {
44     return ioc;
45 }
46 
47 std::shared_ptr<sdbusplus::asio::connection> DbusEnvironment::getBus()
48 {
49     return bus;
50 }
51 
52 std::shared_ptr<sdbusplus::asio::object_server> DbusEnvironment::getObjServer()
53 {
54     return objServer;
55 }
56 
57 const char* DbusEnvironment::serviceName()
58 {
59     return "telemetry.ut";
60 }
61 
62 std::function<void()> DbusEnvironment::setPromise(std::string_view name)
63 {
64     auto promise = std::make_shared<std::promise<bool>>();
65 
66     {
67         futures[std::string(name)].emplace_back(promise->get_future());
68     }
69 
70     return [p = std::move(promise)]() { p->set_value(true); };
71 }
72 
73 bool DbusEnvironment::waitForFuture(std::string_view name,
74                                     std::chrono::milliseconds timeout)
75 {
76     return waitForFuture(getFuture(name), timeout).value_or(false);
77 }
78 
79 std::future<bool> DbusEnvironment::getFuture(std::string_view name)
80 {
81     auto& data = futures[std::string(name)];
82     auto it = data.begin();
83 
84     if (it != data.end())
85     {
86         auto result = std::move(*it);
87         data.erase(it);
88         return result;
89     }
90 
91     return {};
92 }
93 
94 void DbusEnvironment::sleepFor(std::chrono::milliseconds timeout)
95 {
96     auto end = std::chrono::high_resolution_clock::now() + timeout;
97 
98     while (std::chrono::high_resolution_clock::now() < end)
99     {
100         synchronizeIoc();
101         std::this_thread::yield();
102     }
103 
104     synchronizeIoc();
105 }
106 
107 std::chrono::milliseconds
108     DbusEnvironment::measureTime(std::function<void()> fun)
109 {
110     auto begin = std::chrono::high_resolution_clock::now();
111     fun();
112     auto end = std::chrono::high_resolution_clock::now();
113 
114     return std::chrono::duration_cast<std::chrono::milliseconds>(end - begin);
115 }
116 
117 boost::asio::io_context DbusEnvironment::ioc;
118 std::shared_ptr<sdbusplus::asio::connection> DbusEnvironment::bus;
119 std::shared_ptr<sdbusplus::asio::object_server> DbusEnvironment::objServer;
120 std::map<std::string, std::vector<std::future<bool>>> DbusEnvironment::futures;
121 bool DbusEnvironment::setUp = false;
122