Implemented sensor class

Sensor class was introduced, it monitors
xyz.openbmc_project.Sensor.Value, for change and notifies all
listeners.

Tested:
  - Unit tested with service stub that provides dbus interface
    xyz.openbmc_project.Sensor.Value
  - All changes are delivered to listeners
  - All other unit tests are passing

Change-Id: I8c9d58cc986c1fe2a4d2386815d559814016efa6
Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
diff --git a/tests/src/dbus_environment.hpp b/tests/src/dbus_environment.hpp
new file mode 100644
index 0000000..d039922
--- /dev/null
+++ b/tests/src/dbus_environment.hpp
@@ -0,0 +1,84 @@
+#include <sdbusplus/asio/object_server.hpp>
+
+#include <future>
+#include <thread>
+
+#include <gmock/gmock.h>
+
+class DbusEnvironment : public ::testing::Environment
+{
+  public:
+    ~DbusEnvironment();
+
+    void SetUp() override;
+    void TearDown() override;
+    void teardown();
+
+    static boost::asio::io_context& getIoc();
+    static std::shared_ptr<sdbusplus::asio::connection> getBus();
+    static std::shared_ptr<sdbusplus::asio::object_server> getObjServer();
+    static const char* serviceName();
+    static std::function<void()> setPromise(std::string_view name);
+    static void sleepFor(std::chrono::milliseconds);
+    static std::chrono::milliseconds measureTime(std::function<void()>);
+
+    static void synchronizeIoc()
+    {
+        while (ioc.poll() > 0)
+        {
+        }
+    }
+
+    template <class Functor>
+    static void synchronizedPost(Functor&& functor)
+    {
+        boost::asio::post(ioc, std::forward<Functor>(functor));
+        synchronizeIoc();
+    }
+
+    template <class T>
+    static std::optional<T> waitForFuture(
+        std::future<T> future,
+        std::chrono::milliseconds timeout = std::chrono::seconds(10))
+    {
+        constexpr auto precission = std::chrono::milliseconds(10);
+        auto elapsed = std::chrono::milliseconds(0);
+
+        while (future.valid() && elapsed < timeout)
+        {
+            synchronizeIoc();
+
+            try
+            {
+                if (future.wait_for(precission) == std::future_status::ready)
+                {
+                    return future.get();
+                }
+                else
+                {
+                    elapsed += precission;
+                }
+            }
+            catch (const std::future_error& e)
+            {
+                std::cerr << e.what() << "\n";
+                return {};
+            }
+        }
+
+        return {};
+    }
+
+    static bool waitForFuture(
+        std::string_view name,
+        std::chrono::milliseconds timeout = std::chrono::seconds(10));
+
+  private:
+    static std::future<bool> getFuture(std::string_view name);
+
+    static boost::asio::io_context ioc;
+    static std::shared_ptr<sdbusplus::asio::connection> bus;
+    static std::shared_ptr<sdbusplus::asio::object_server> objServer;
+    static std::map<std::string, std::vector<std::future<bool>>> futures;
+    static bool setUp;
+};