Added support for Enabled property

Enabled property is added so that user can select via dbus interface if
Readings are updated and signal on Readings update is emitted, moreover
Metric calculation on received sensor data is active only when Enabled
is set to true

Tested:
- New unit tests were created, ran all new and previous UTs, all passed
- Tested under QEMU by adding reports for single and multiple sensors,
  changing Enabled property and emitting signal of value change for
  sensors added into the report, checking if Readings is accordingly
  updated or not updated
- Verified persistency, if Enabled property is successfully stored and
  restored after Telemetry service restart and also checked if after the
  restart dependencies of Enabled (Readings, Metric calculation) are
  properly initiated

Signed-off-by: Lukasz Kazmierczak <lukasz.kazmierczak@intel.com>
Change-Id: I29cf13693a48d15cb16d2ad6707f483f67f4879b
diff --git a/tests/src/fakes/clock_fake.hpp b/tests/src/fakes/clock_fake.hpp
index 28c2940..3871a3b 100644
--- a/tests/src/fakes/clock_fake.hpp
+++ b/tests/src/fakes/clock_fake.hpp
@@ -27,6 +27,11 @@
         timePoint = time_point{timeSinceEpoch};
     }
 
+    void reset(void) noexcept
+    {
+        set(Milliseconds(0));
+    }
+
     static uint64_t toTimestamp(Milliseconds time)
     {
         return time.count();
diff --git a/tests/src/mocks/metric_mock.hpp b/tests/src/mocks/metric_mock.hpp
index f66f38d..a105aa0 100644
--- a/tests/src/mocks/metric_mock.hpp
+++ b/tests/src/mocks/metric_mock.hpp
@@ -16,6 +16,7 @@
     }
 
     MOCK_METHOD(void, initialize, (), (override));
+    MOCK_METHOD(void, deinitialize, (), (override));
     MOCK_METHOD(std::vector<MetricValue>, getReadings, (), (const, override));
     MOCK_METHOD(LabeledMetricParameters, dumpConfiguration, (),
                 (const, override));
diff --git a/tests/src/mocks/report_factory_mock.hpp b/tests/src/mocks/report_factory_mock.hpp
index a486e74..e456429 100644
--- a/tests/src/mocks/report_factory_mock.hpp
+++ b/tests/src/mocks/report_factory_mock.hpp
@@ -35,7 +35,7 @@
             .WillByDefault(
                 WithArgs<1>(Invoke(&ReportFactoryMock::convertToLabeled)));
 
-        ON_CALL(*this, make(A<const std::string&>(), _, _, _, _, _, _, _))
+        ON_CALL(*this, make(A<const std::string&>(), _, _, _, _, _, _, _, _))
             .WillByDefault(WithArgs<0>(Invoke([](const std::string& name) {
                 return std::make_unique<NiceMock<ReportMock>>(name);
             })));
@@ -48,8 +48,8 @@
     MOCK_METHOD(std::unique_ptr<interfaces::Report>, make,
                 (const std::string&, const std::string&, bool, bool,
                  Milliseconds, interfaces::ReportManager&,
-                 interfaces::JsonStorage&,
-                 std::vector<LabeledMetricParameters>),
+                 interfaces::JsonStorage&, std::vector<LabeledMetricParameters>,
+                 bool),
                 (const, override));
 
     auto& expectMake(
@@ -60,17 +60,17 @@
         if (paramsRef)
         {
             const ReportParams& params = *paramsRef;
-            return EXPECT_CALL(*this,
-                               make(params.reportName(), params.reportingType(),
-                                    params.emitReadingUpdate(),
-                                    params.logToMetricReportCollection(),
-                                    params.interval(), rm, js,
-                                    params.metricParameters()));
+            return EXPECT_CALL(
+                *this,
+                make(params.reportName(), params.reportingType(),
+                     params.emitReadingUpdate(),
+                     params.logToMetricReportCollection(), params.interval(),
+                     rm, js, params.metricParameters(), params.enabled()));
         }
         else
         {
             using testing::_;
-            return EXPECT_CALL(*this, make(_, _, _, _, _, rm, js, _));
+            return EXPECT_CALL(*this, make(_, _, _, _, _, rm, js, _, _));
         }
     }
 };
diff --git a/tests/src/mocks/sensor_mock.hpp b/tests/src/mocks/sensor_mock.hpp
index d71d77e..b86a26e 100644
--- a/tests/src/mocks/sensor_mock.hpp
+++ b/tests/src/mocks/sensor_mock.hpp
@@ -26,6 +26,8 @@
     MOCK_METHOD(Id, id, (), (const, override));
     MOCK_METHOD(void, registerForUpdates,
                 (const std::weak_ptr<interfaces::SensorListener>&), (override));
+    MOCK_METHOD(void, unregisterFromUpdates,
+                (const std::weak_ptr<interfaces::SensorListener>&), (override));
 
     const uint64_t mockId = generateUniqueMockId();
 
diff --git a/tests/src/params/report_params.hpp b/tests/src/params/report_params.hpp
index 3bfd308..cc71ce3 100644
--- a/tests/src/params/report_params.hpp
+++ b/tests/src/params/report_params.hpp
@@ -64,6 +64,17 @@
         return intervalProperty;
     }
 
+    ReportParams& enabled(bool val)
+    {
+        enabledProperty = val;
+        return *this;
+    }
+
+    bool enabled() const
+    {
+        return enabledProperty;
+    }
+
     ReportParams& metricParameters(std::vector<LabeledMetricParameters> val)
     {
         metricParametersProperty = std::move(val);
@@ -98,4 +109,5 @@
              "Metadata2",
              CollectionTimeScope::point,
              CollectionDuration(Milliseconds(0u))}}};
+    bool enabledProperty = true;
 };
diff --git a/tests/src/test_metric.cpp b/tests/src/test_metric.cpp
index 87e32f9..a8c3d86 100644
--- a/tests/src/test_metric.cpp
+++ b/tests/src/test_metric.cpp
@@ -63,6 +63,18 @@
     sut->initialize();
 }
 
+TEST_F(TestMetric, unsubscribesForSensorDuringDeinitialization)
+{
+    sut = makeSut(params);
+
+    EXPECT_CALL(*sensorMocks.front(),
+                unregisterFromUpdates(Truly([sut = sut.get()](const auto& a0) {
+                    return a0.lock().get() == sut;
+                })));
+
+    sut->deinitialize();
+}
+
 TEST_F(TestMetric, containsEmptyReadingAfterCreated)
 {
     sut = makeSut(params);
@@ -177,8 +189,7 @@
   public:
     void SetUp() override
     {
-        clockFakePtr->set(0ms);
-
+        clockFake.reset();
         sut = makeSut(params.operationType(GetParam().operationType())
                           .collectionTimeScope(GetParam().collectionTimeScope())
                           .collectionDuration(GetParam().collectionDuration()));
diff --git a/tests/src/test_report.cpp b/tests/src/test_report.cpp
index 441ebd9..79e66ff 100644
--- a/tests/src/test_report.cpp
+++ b/tests/src/test_report.cpp
@@ -73,7 +73,8 @@
             params.emitReadingUpdate(), params.logToMetricReportCollection(),
             params.interval(), *reportManagerMock, storageMock,
             utils::convContainer<std::shared_ptr<interfaces::Metric>>(
-                metricMocks));
+                metricMocks),
+            params.enabled());
     }
 
     template <class T>
@@ -138,6 +139,8 @@
 
 TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
 {
+    EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
+                Eq(defaultParams.enabled()));
     EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
                 Eq(defaultParams.interval().count()));
     EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
@@ -157,6 +160,14 @@
                 Eq(Readings{}));
 }
 
+TEST_F(TestReport, setEnabledWithNewValue)
+{
+    bool newValue = !defaultParams.enabled();
+    EXPECT_THAT(setProperty(sut->getPath(), "Enabled", newValue).value(),
+                Eq(boost::system::errc::success));
+    EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(newValue));
+}
+
 TEST_F(TestReport, setIntervalWithValidValue)
 {
     uint64_t newValue = defaultParams.interval().count() + 1;
@@ -240,7 +251,8 @@
 
 INSTANTIATE_TEST_SUITE_P(
     _, TestReportStore,
-    Values(std::make_pair("Version"s, nlohmann::json(4)),
+    Values(std::make_pair("Enabled"s, nlohmann::json(ReportParams().enabled())),
+           std::make_pair("Version"s, nlohmann::json(4)),
            std::make_pair("Name"s, nlohmann::json(ReportParams().reportName())),
            std::make_pair("ReportingType",
                           nlohmann::json(ReportParams().reportingType())),
@@ -379,15 +391,28 @@
                 Eq(GetParam().reportingType()));
 }
 
-TEST_P(TestReportAllReportTypes, updateReadingsCallUpdateReadingsProperty)
+TEST_P(TestReportAllReportTypes, updateReadingsCallEnabledPropertyOff)
+{
+    const uint64_t expectedTime = std::time(0);
+
+    setProperty(sut->getPath(), "Enabled", false);
+    sut->updateReadings();
+    const auto [timestamp, readings] =
+        getProperty<Readings>(sut->getPath(), "Readings");
+
+    EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(false));
+    EXPECT_THAT(timestamp, Lt(expectedTime));
+}
+
+TEST_P(TestReportAllReportTypes, updateReadingsCallEnabledPropertyOn)
 {
     const uint64_t expectedTime = std::time(0);
 
     sut->updateReadings();
-
     const auto [timestamp, readings] =
         getProperty<Readings>(sut->getPath(), "Readings");
 
+    EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(true));
     EXPECT_THAT(timestamp, Ge(expectedTime));
 }
 
@@ -539,14 +564,26 @@
     MockFunction<void()> readingsUpdated;
 };
 
-TEST_F(TestReportInitialization, metricsAreInitializedWhenConstructed)
+TEST_F(TestReportInitialization,
+       metricsAreInitializedWhenEnabledReportConstructed)
 {
+    initMetricMocks(defaultParams.metricParameters());
     for (auto& metric : metricMocks)
     {
-        EXPECT_CALL(*metric, initialize());
+        EXPECT_CALL(*metric, initialize()).Times(1);
     }
+    sut = makeReport(defaultParams.enabled(true));
+}
 
-    sut = makeReport(ReportParams());
+TEST_F(TestReportInitialization,
+       metricsAreNotInitializedWhenDisabledReportConstructed)
+{
+    initMetricMocks(defaultParams.metricParameters());
+    for (auto& metric : metricMocks)
+    {
+        EXPECT_CALL(*metric, initialize()).Times(0);
+    }
+    sut = makeReport(defaultParams.enabled(false));
 }
 
 TEST_F(TestReportInitialization,
diff --git a/tests/src/test_report_manager.cpp b/tests/src/test_report_manager.cpp
index 2287707..e0705ca 100644
--- a/tests/src/test_report_manager.cpp
+++ b/tests/src/test_report_manager.cpp
@@ -352,6 +352,7 @@
     }
 
     nlohmann::json data = nlohmann::json{
+        {"Enabled", reportParams.enabled()},
         {"Version", Report::reportVersion},
         {"Name", reportParams.reportName()},
         {"ReportingType", reportParams.reportingType()},
diff --git a/tests/src/test_sensor.cpp b/tests/src/test_sensor.cpp
index 820602c..5547cf0 100644
--- a/tests/src/test_sensor.cpp
+++ b/tests/src/test_sensor.cpp
@@ -34,6 +34,13 @@
         DbusEnvironment::synchronizeIoc();
     }
 
+    void unregisterFromUpdates(
+        std::shared_ptr<interfaces::SensorListener> listener)
+    {
+        sut->unregisterFromUpdates(listener);
+        DbusEnvironment::synchronizeIoc();
+    }
+
     static std::unique_ptr<stubs::DbusSensorObject> makeSensorObject()
     {
         return std::make_unique<stubs::DbusSensorObject>(
@@ -153,6 +160,22 @@
     registerForUpdates(listenerMock2);
 }
 
+TEST_F(TestSensorNotification, notNotifiesWithValueWhenUnregistered)
+{
+    EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.));
+    EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
+        .Times(0);
+    EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
+        .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
+
+    registerForUpdates(listenerMock2);
+    unregisterFromUpdates(listenerMock);
+
+    sensorObject->setValue(42.7);
+
+    ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
+}
+
 TEST_F(TestSensorNotification,
        dbusSensorIsAddedToSystemAfterSensorIsCreatedThenValueIsUpdated)
 {