1 #pragma once 2 3 #include <sdbusplus/asio/object_server.hpp> 4 #include <sdbusplus/asio/property.hpp> 5 6 #include <future> 7 #include <thread> 8 9 #include <gmock/gmock.h> 10 11 class 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) 31 {} 32 } 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 41 template <class T, class F> 42 static T waitForFutures( 43 std::vector<std::future<T>> futures, T init, F&& accumulator, 44 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 49 auto sum = init; 50 for (auto& future : futures) 51 { 52 while (future.valid() && elapsed < timeout) 53 { 54 synchronizeIoc(); 55 56 if (future.wait_for(precission) == std::future_status::ready) 57 { 58 sum = accumulator(sum, future.get()); 59 } 60 else 61 { 62 elapsed += precission; 63 } 64 } 65 } 66 67 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); 86 } 87 88 static bool waitForFuture( 89 std::string_view name, 90 std::chrono::milliseconds timeout = std::chrono::seconds(10)); 91 92 static bool waitForFutures( 93 std::string_view name, 94 std::chrono::milliseconds timeout = std::chrono::seconds(10)); 95 96 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 }; 105