blob: 8146bcb11427d06d8306e179ae126b189d56267f [file] [log] [blame]
Szymon Dompkef763c9e2021-03-12 09:19:22 +01001#pragma once
2
Krzysztof Grobelnyb5645942020-09-29 11:52:45 +02003#include <sdbusplus/asio/object_server.hpp>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +02004#include <sdbusplus/asio/property.hpp>
Krzysztof Grobelnyb5645942020-09-29 11:52:45 +02005
6#include <future>
7#include <thread>
8
9#include <gmock/gmock.h>
10
11class DbusEnvironment : public ::testing::Environment
12{
13 public:
14 ~DbusEnvironment();
15
16 void SetUp() override;
17 void TearDown() override;
18 void teardown();
19
20 static boost::asio::io_context& getIoc();
21 static std::shared_ptr<sdbusplus::asio::connection> getBus();
22 static std::shared_ptr<sdbusplus::asio::object_server> getObjServer();
23 static const char* serviceName();
24 static std::function<void()> setPromise(std::string_view name);
25 static void sleepFor(std::chrono::milliseconds);
26 static std::chrono::milliseconds measureTime(std::function<void()>);
27
28 static void synchronizeIoc()
29 {
30 while (ioc.poll() > 0)
Patrick Williams92cfff42021-02-22 17:15:39 -060031 {}
Krzysztof Grobelnyb5645942020-09-29 11:52:45 +020032 }
33
34 template <class Functor>
35 static void synchronizedPost(Functor&& functor)
36 {
37 boost::asio::post(ioc, std::forward<Functor>(functor));
38 synchronizeIoc();
39 }
40
Szymon Dompkef763c9e2021-03-12 09:19:22 +010041 template <class T, class F>
42 static T waitForFutures(
43 std::vector<std::future<T>> futures, T init, F&& accumulator,
Krzysztof Grobelnyb5645942020-09-29 11:52:45 +020044 std::chrono::milliseconds timeout = std::chrono::seconds(10))
45 {
46 constexpr auto precission = std::chrono::milliseconds(10);
47 auto elapsed = std::chrono::milliseconds(0);
48
Szymon Dompkef763c9e2021-03-12 09:19:22 +010049 auto sum = init;
50 for (auto& future : futures)
Krzysztof Grobelnyb5645942020-09-29 11:52:45 +020051 {
Szymon Dompkef763c9e2021-03-12 09:19:22 +010052 while (future.valid() && elapsed < timeout)
53 {
54 synchronizeIoc();
Krzysztof Grobelnyb5645942020-09-29 11:52:45 +020055
Szymon Dompkef763c9e2021-03-12 09:19:22 +010056 if (future.wait_for(precission) == std::future_status::ready)
57 {
58 sum = accumulator(sum, future.get());
59 }
60 else
61 {
62 elapsed += precission;
63 }
Krzysztof Grobelnyb5645942020-09-29 11:52:45 +020064 }
65 }
66
Szymon Dompkef763c9e2021-03-12 09:19:22 +010067 if (elapsed >= timeout)
68 {
69 throw std::runtime_error("Timed out while waiting for future");
70 }
71
72 return sum;
73 }
74
75 template <class T>
76 static T waitForFuture(
77 std::future<T> future,
78 std::chrono::milliseconds timeout = std::chrono::seconds(10))
79 {
80 std::vector<std::future<T>> futures;
81 futures.emplace_back(std::move(future));
82
83 return waitForFutures(
84 std::move(futures), T{},
85 [](auto, const auto& value) { return value; }, timeout);
Krzysztof Grobelnyb5645942020-09-29 11:52:45 +020086 }
87
88 static bool waitForFuture(
89 std::string_view name,
90 std::chrono::milliseconds timeout = std::chrono::seconds(10));
91
Szymon Dompkef763c9e2021-03-12 09:19:22 +010092 static bool waitForFutures(
93 std::string_view name,
94 std::chrono::milliseconds timeout = std::chrono::seconds(10));
95
Krzysztof Grobelnyb5645942020-09-29 11:52:45 +020096 private:
97 static std::future<bool> getFuture(std::string_view name);
98
99 static boost::asio::io_context ioc;
100 static std::shared_ptr<sdbusplus::asio::connection> bus;
101 static std::shared_ptr<sdbusplus::asio::object_server> objServer;
102 static std::map<std::string, std::vector<std::future<bool>>> futures;
103 static bool setUp;
104};