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