1 #pragma once 2 3 #include "types/duration_type.hpp" 4 5 #include <sdbusplus/asio/object_server.hpp> 6 #include <sdbusplus/asio/property.hpp> 7 8 #include <future> 9 #include <thread> 10 11 #include <gmock/gmock.h> 12 13 class DbusEnvironment : public ::testing::Environment 14 { 15 public: 16 ~DbusEnvironment(); 17 18 void SetUp() override; 19 void TearDown() override; 20 void teardown(); 21 22 static boost::asio::io_context& getIoc(); 23 static std::shared_ptr<sdbusplus::asio::connection> getBus(); 24 static std::shared_ptr<sdbusplus::asio::object_server> getObjServer(); 25 static const char* serviceName(); 26 static std::function<void()> setPromise(std::string_view name); 27 static void sleepFor(Milliseconds); 28 static Milliseconds measureTime(std::function<void()>); 29 30 static void synchronizeIoc() 31 { 32 while (ioc.poll() > 0) 33 {} 34 } 35 36 template <class Functor> 37 static void synchronizedPost(Functor&& functor) 38 { 39 boost::asio::post(ioc, std::forward<Functor>(functor)); 40 synchronizeIoc(); 41 } 42 43 template <class T, class F> 44 static T waitForFutures(std::vector<std::future<T>> futures, T init, 45 F&& accumulator, 46 Milliseconds timeout = std::chrono::seconds(10)) 47 { 48 constexpr auto precission = Milliseconds(10); 49 auto elapsed = Milliseconds(0); 50 51 auto sum = init; 52 for (auto& future : futures) 53 { 54 while (future.valid() && elapsed < timeout) 55 { 56 synchronizeIoc(); 57 58 if (future.wait_for(precission) == std::future_status::ready) 59 { 60 sum = accumulator(sum, future.get()); 61 } 62 else 63 { 64 elapsed += precission; 65 } 66 } 67 } 68 69 if (elapsed >= timeout) 70 { 71 throw std::runtime_error("Timed out while waiting for future"); 72 } 73 74 return sum; 75 } 76 77 template <class T> 78 static T waitForFuture(std::future<T> future, 79 Milliseconds timeout = std::chrono::seconds(10)) 80 { 81 std::vector<std::future<T>> futures; 82 futures.emplace_back(std::move(future)); 83 84 return waitForFutures( 85 std::move(futures), T{}, 86 [](auto, const auto& value) { return value; }, timeout); 87 } 88 89 static bool waitForFuture(std::string_view name, 90 Milliseconds timeout = std::chrono::seconds(10)); 91 92 static bool waitForFutures(std::string_view name, 93 Milliseconds timeout = std::chrono::seconds(10)); 94 95 private: 96 static std::future<bool> getFuture(std::string_view name); 97 98 static boost::asio::io_context ioc; 99 static std::shared_ptr<sdbusplus::asio::connection> bus; 100 static std::shared_ptr<sdbusplus::asio::object_server> objServer; 101 static std::map<std::string, std::vector<std::future<bool>>> futures; 102 static bool setUp; 103 }; 104