xref: /openbmc/telemetry/tests/src/dbus_environment.cpp (revision f763c9e3bbe0f86a4a41e7bb0dc70bffde0af9b2)
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     futures[std::string(name)].emplace_back(promise->get_future());
66     return [p = std::move(promise)]() { p->set_value(true); };
67 }
68 
69 bool DbusEnvironment::waitForFuture(std::string_view name,
70                                     std::chrono::milliseconds timeout)
71 {
72     return waitForFuture(getFuture(name), timeout);
73 }
74 
75 bool DbusEnvironment::waitForFutures(std::string_view name,
76                                      std::chrono::milliseconds timeout)
77 {
78     auto& data = futures[std::string(name)];
79     auto ret = waitForFutures(
80         std::move(data), true, [](auto sum, auto val) { return sum && val; },
81         timeout);
82     data = std::vector<std::future<bool>>{};
83     return ret;
84 }
85 
86 std::future<bool> DbusEnvironment::getFuture(std::string_view name)
87 {
88     auto& data = futures[std::string(name)];
89     auto it = data.begin();
90 
91     if (it != data.end())
92     {
93         auto result = std::move(*it);
94         data.erase(it);
95         return result;
96     }
97 
98     return {};
99 }
100 
101 void DbusEnvironment::sleepFor(std::chrono::milliseconds timeout)
102 {
103     auto end = std::chrono::high_resolution_clock::now() + timeout;
104 
105     while (std::chrono::high_resolution_clock::now() < end)
106     {
107         synchronizeIoc();
108         std::this_thread::yield();
109     }
110 
111     synchronizeIoc();
112 }
113 
114 std::chrono::milliseconds
115     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<std::chrono::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