Added Update method to report on dbus

- Update method, updates timestamp and readings

Tested:
  - Added new unit tests covering update method
  - All existing unit tests are passing

Change-Id: I6b3829126d9060dbaf436cbf8e6917294dc03134
Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
diff --git a/tests/src/dbus_environment.cpp b/tests/src/dbus_environment.cpp
index ab749db..71568f9 100644
--- a/tests/src/dbus_environment.cpp
+++ b/tests/src/dbus_environment.cpp
@@ -73,7 +73,7 @@
 bool DbusEnvironment::waitForFuture(std::string_view name,
                                     std::chrono::milliseconds timeout)
 {
-    return waitForFuture(getFuture(name), timeout).value_or(false);
+    return waitForFuture(getFuture(name), timeout);
 }
 
 std::future<bool> DbusEnvironment::getFuture(std::string_view name)
diff --git a/tests/src/dbus_environment.hpp b/tests/src/dbus_environment.hpp
index e483fe7..6a961e6 100644
--- a/tests/src/dbus_environment.hpp
+++ b/tests/src/dbus_environment.hpp
@@ -38,7 +38,7 @@
     }
 
     template <class T>
-    static std::optional<T> waitForFuture(
+    static T waitForFuture(
         std::future<T> future,
         std::chrono::milliseconds timeout = std::chrono::seconds(10))
     {
@@ -49,25 +49,17 @@
         {
             synchronizeIoc();
 
-            try
+            if (future.wait_for(precission) == std::future_status::ready)
             {
-                if (future.wait_for(precission) == std::future_status::ready)
-                {
-                    return future.get();
-                }
-                else
-                {
-                    elapsed += precission;
-                }
+                return future.get();
             }
-            catch (const std::future_error& e)
+            else
             {
-                std::cerr << e.what() << "\n";
-                return {};
+                elapsed += precission;
             }
         }
 
-        return {};
+        throw std::runtime_error("Timed out while waiting for future");
     }
 
     static bool waitForFuture(
diff --git a/tests/src/test_report.cpp b/tests/src/test_report.cpp
index b53d359..40e85da 100644
--- a/tests/src/test_report.cpp
+++ b/tests/src/test_report.cpp
@@ -7,6 +7,7 @@
 #include "report.hpp"
 #include "report_manager.hpp"
 #include "utils/conv_container.hpp"
+#include "utils/set_exception.hpp"
 
 #include <sdbusplus/exception.hpp>
 
@@ -78,13 +79,29 @@
         sdbusplus::asio::getProperty<T>(
             *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
             Report::reportIfaceName, property,
-            [&propertyPromise](boost::system::error_code ec) {
-                EXPECT_THAT(static_cast<bool>(ec), ::testing::Eq(false));
-                propertyPromise.set_value(T{});
+            [&propertyPromise](boost::system::error_code) {
+                utils::setException(propertyPromise, "GetProperty failed");
             },
             [&propertyPromise](T t) { propertyPromise.set_value(t); });
-        return DbusEnvironment::waitForFuture(propertyPromise.get_future())
-            .value_or(T{});
+        return DbusEnvironment::waitForFuture(propertyPromise.get_future());
+    }
+
+    boost::system::error_code call(const std::string& path,
+                                   const std::string& interface,
+                                   const std::string& method)
+    {
+        std::promise<boost::system::error_code> methodPromise;
+        DbusEnvironment::getBus()->async_method_call(
+            [&methodPromise](boost::system::error_code ec) {
+                methodPromise.set_value(ec);
+            },
+            DbusEnvironment::serviceName(), path, interface, method);
+        return DbusEnvironment::waitForFuture(methodPromise.get_future());
+    }
+
+    boost::system::error_code update(const std::string& path)
+    {
+        return call(path, Report::reportIfaceName, "Update");
     }
 
     template <class T>
@@ -102,21 +119,12 @@
             [&setPromise]() {
                 setPromise.set_value(boost::system::error_code{});
             });
-        return DbusEnvironment::waitForFuture(setPromise.get_future())
-            .value_or(boost::system::error_code{});
+        return DbusEnvironment::waitForFuture(setPromise.get_future());
     }
 
     boost::system::error_code deleteReport(const std::string& path)
     {
-        std::promise<boost::system::error_code> deleteReportPromise;
-        DbusEnvironment::getBus()->async_method_call(
-            [&deleteReportPromise](boost::system::error_code ec) {
-                deleteReportPromise.set_value(ec);
-            },
-            DbusEnvironment::serviceName(), path, Report::deleteIfaceName,
-            "Delete");
-        return DbusEnvironment::waitForFuture(deleteReportPromise.get_future())
-            .value_or(boost::system::error_code{});
+        return call(path, Report::deleteIfaceName, "Delete");
     }
 };
 
@@ -320,6 +328,61 @@
                 Eq(GetParam().reportingType()));
 }
 
+class TestReportOnRequestType : public TestReport
+{
+    void SetUp() override
+    {
+        sut = makeReport(ReportParams().reportingType("OnRequest"));
+    }
+};
+
+TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
+{
+    const uint64_t expectedTime = std::time(0);
+
+    ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
+
+    const auto [timestamp, readings] =
+        getProperty<Readings>(sut->getPath(), "Readings");
+
+    EXPECT_THAT(timestamp, Ge(expectedTime));
+}
+
+TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
+{
+    ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
+
+    const auto [timestamp, readings] =
+        getProperty<Readings>(sut->getPath(), "Readings");
+
+    EXPECT_THAT(readings,
+                ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
+                            std::make_tuple("aaa"s, "bbb"s, 21.7, 100u),
+                            std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
+}
+
+class TestReportNonOnRequestType :
+    public TestReport,
+    public WithParamInterface<ReportParams>
+{
+    void SetUp() override
+    {
+        sut = makeReport(GetParam());
+    }
+};
+
+INSTANTIATE_TEST_SUITE_P(_, TestReportNonOnRequestType,
+                         Values(ReportParams().reportingType("Periodic"),
+                                ReportParams().reportingType("OnChange")));
+
+TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
+{
+    ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
+
+    EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
+                Eq(Readings{}));
+}
+
 class TestReportNonPeriodicReport :
     public TestReport,
     public WithParamInterface<ReportParams>
@@ -347,15 +410,6 @@
     void SetUp() override
     {
         sut = makeReport(ReportParams().reportingType("Periodic"));
-
-        ASSERT_THAT(metricMocks, SizeIs(Ge(2)));
-        ON_CALL(*metricMocks[0], getReadings())
-            .WillByDefault(ReturnRefOfCopy(std::vector<MetricValue>(
-                {MetricValue{"a", "b", 17.1, 114},
-                 MetricValue{"aaa", "bbb", 21.7, 100}})));
-        ON_CALL(*metricMocks[1], getReadings())
-            .WillByDefault(ReturnRefOfCopy(
-                std::vector<MetricValue>({MetricValue{"aa", "bb", 42.0, 74}})));
     }
 };
 
diff --git a/tests/src/test_report_manager.cpp b/tests/src/test_report_manager.cpp
index 482434c..813fa19 100644
--- a/tests/src/test_report_manager.cpp
+++ b/tests/src/test_report_manager.cpp
@@ -54,8 +54,7 @@
             params.emitReadingUpdate(), params.logToMetricReportCollection(),
             static_cast<uint64_t>(params.interval().count()),
             params.readingParameters());
-        return DbusEnvironment::waitForFuture(addReportPromise.get_future())
-            .value_or(std::pair<boost::system::error_code, std::string>{});
+        return DbusEnvironment::waitForFuture(addReportPromise.get_future());
     }
 
     template <class T>
@@ -71,8 +70,7 @@
                 propertyPromise.set_value(T{});
             },
             [&propertyPromise](T t) { propertyPromise.set_value(t); });
-        return DbusEnvironment::waitForFuture(propertyPromise.get_future())
-            .value_or(T{});
+        return DbusEnvironment::waitForFuture(propertyPromise.get_future());
     }
 };
 
diff --git a/tests/src/utils/set_exception.hpp b/tests/src/utils/set_exception.hpp
new file mode 100644
index 0000000..6680af0
--- /dev/null
+++ b/tests/src/utils/set_exception.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <future>
+
+namespace utils
+{
+
+template <class T>
+inline void setException(std::promise<T>& promise, const std::string& message)
+{
+    promise.set_exception(std::make_exception_ptr(std::runtime_error(message)));
+}
+
+} // namespace utils