Fixed handling maxAppendLimit

maxLimit prevented using numeric_limits<uint64_t>::max as a way to let
telemetry service deduce appendLimit. This commit fixes constrain to
allow passing this special value.

Tested:
  - Added new unit tests that confirm numeric_limits<uint64_t>::max is
    correctly handled in telemetry service

Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
Change-Id: I5d67e83475cdfcbb58a71b783ac9eef1e5ad7010
diff --git a/src/report.cpp b/src/report.cpp
index 2b7134a..8acf182 100644
--- a/src/report.cpp
+++ b/src/report.cpp
@@ -89,11 +89,12 @@
     return sensorCount;
 }
 
-uint64_t Report::deduceAppendLimit(const uint64_t appendLimitIn) const
+std::optional<uint64_t>
+    Report::deduceAppendLimit(const uint64_t appendLimitIn) const
 {
     if (appendLimitIn == std::numeric_limits<uint64_t>::max())
     {
-        return sensorCount;
+        return std::nullopt;
     }
     else
     {
@@ -111,7 +112,7 @@
     }
     else
     {
-        return appendLimit;
+        return appendLimit.value_or(sensorCount);
     }
 }
 
@@ -243,9 +244,10 @@
                 return utils::enumToString(reportAction);
             });
         });
-    dbusIface->register_property_r("AppendLimit", appendLimit,
-                                   sdbusplus::vtable::property_::emits_change,
-                                   [this](const auto&) { return appendLimit; });
+    dbusIface->register_property_r(
+        "AppendLimit", appendLimit.value_or(sensorCount),
+        sdbusplus::vtable::property_::emits_change,
+        [this](const auto&) { return appendLimit.value_or(sensorCount); });
     dbusIface->register_property_rw(
         "ReportUpdates", std::string(),
         sdbusplus::vtable::property_::emits_change,
@@ -340,7 +342,8 @@
                 return utils::toUnderlying(reportAction);
             });
         data["Interval"] = interval.count();
-        data["AppendLimit"] = appendLimit;
+        data["AppendLimit"] =
+            appendLimit.value_or(std::numeric_limits<uint64_t>::max());
         data["ReportUpdates"] = utils::toUnderlying(reportUpdates);
         data["ReadingParameters"] =
             utils::transform(metrics, [](const auto& metric) {
diff --git a/src/report.hpp b/src/report.hpp
index 880ede7..98097ae 100644
--- a/src/report.hpp
+++ b/src/report.hpp
@@ -54,7 +54,8 @@
     std::unique_ptr<sdbusplus::asio::dbus_interface> makeReportInterface();
     static void timerProc(boost::system::error_code, Report& self);
     void scheduleTimer(Milliseconds interval);
-    uint64_t deduceAppendLimit(const uint64_t appendLimitIn) const;
+    std::optional<uint64_t>
+        deduceAppendLimit(const uint64_t appendLimitIn) const;
     uint64_t deduceBufferSize(const ReportUpdates reportUpdatesIn,
                               const ReportingType reportingTypeIn) const;
     void setReportUpdates(const ReportUpdates newReportUpdates);
@@ -71,7 +72,7 @@
     ReadingParameters readingParameters;
     bool persistency = false;
     uint64_t sensorCount;
-    uint64_t appendLimit;
+    std::optional<uint64_t> appendLimit;
     ReportUpdates reportUpdates;
     CircularVector<ReadingData> readingsBuffer;
     Readings readings = {};
diff --git a/src/report_manager.cpp b/src/report_manager.cpp
index 8687316..f5dc105 100644
--- a/src/report_manager.cpp
+++ b/src/report_manager.cpp
@@ -144,7 +144,8 @@
             "Reached maximal report count");
     }
 
-    if (appendLimit > maxAppendLimit)
+    if (appendLimit > maxAppendLimit &&
+        appendLimit != std::numeric_limits<uint64_t>::max())
     {
         throw sdbusplus::exception::SdBusError(
             static_cast<int>(std::errc::invalid_argument),
diff --git a/tests/src/test_report.cpp b/tests/src/test_report.cpp
index 675171a..af22166 100644
--- a/tests/src/test_report.cpp
+++ b/tests/src/test_report.cpp
@@ -280,6 +280,8 @@
                                                }))),
            std::make_pair("Interval",
                           nlohmann::json(ReportParams().interval().count())),
+           std::make_pair("AppendLimit",
+                          nlohmann::json(ReportParams().appendLimit())),
            std::make_pair(
                "ReadingParameters",
                nlohmann::json(
@@ -766,3 +768,17 @@
     auto appendLimit = getProperty<uint64_t>(sut->getPath(), "AppendLimit");
     EXPECT_EQ(appendLimit, 2ull);
 }
+
+TEST_F(TestReportInitialization, appendLimitSetToUintMaxIsStoredCorrectly)
+{
+    nlohmann::json storedConfiguration;
+
+    EXPECT_CALL(storageMock, store(to_file_path(ReportParams().reportId()), _))
+        .WillOnce(SaveArg<1>(&storedConfiguration));
+
+    sut = makeReport(
+        ReportParams().appendLimit(std::numeric_limits<uint64_t>::max()));
+
+    ASSERT_THAT(storedConfiguration.at("AppendLimit"),
+                Eq(std::numeric_limits<uint64_t>::max()));
+}
diff --git a/tests/src/test_report_manager.cpp b/tests/src/test_report_manager.cpp
index 9af5c57..a18579c 100644
--- a/tests/src/test_report_manager.cpp
+++ b/tests/src/test_report_manager.cpp
@@ -279,6 +279,19 @@
     EXPECT_THAT(path, Eq(std::string()));
 }
 
+TEST_F(TestReportManager, addReportWithAppendLimitEqualToUint64MaxIsAllowed)
+{
+    reportParams.appendLimit(std::numeric_limits<uint64_t>::max());
+
+    EXPECT_CALL(reportFactoryMock, convertMetricParams(_, _));
+    reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock))
+        .WillOnce(Return(ByMove(std::move(reportMockPtr))));
+
+    auto [ec, path] = addReport(reportParams);
+    EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
+    EXPECT_THAT(path, Eq(reportMock.getPath()));
+}
+
 TEST_F(TestReportManager, DISABLED_failToAddReportWhenMaxReportIsReached)
 {
     reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))