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