xref: /openbmc/telemetry/tests/src/test_report_manager.cpp (revision bc766b4d8bb2a33a3c8540a4d7c21fb6cda5d104)
12f9f9b87SWludzik, Jozef #include "dbus_environment.hpp"
2d2238194SKrzysztof Grobelny #include "helpers.hpp"
3e2362796SWludzik, Jozef #include "mocks/json_storage_mock.hpp"
42f9f9b87SWludzik, Jozef #include "mocks/report_factory_mock.hpp"
5e2362796SWludzik, Jozef #include "params/report_params.hpp"
6e2362796SWludzik, Jozef #include "report.hpp"
72f9f9b87SWludzik, Jozef #include "report_manager.hpp"
8e2362796SWludzik, Jozef #include "utils/transform.hpp"
92f9f9b87SWludzik, Jozef 
102f9f9b87SWludzik, Jozef using namespace testing;
11e2362796SWludzik, Jozef using namespace std::chrono_literals;
122f9f9b87SWludzik, Jozef 
132f9f9b87SWludzik, Jozef class TestReportManager : public Test
142f9f9b87SWludzik, Jozef {
152f9f9b87SWludzik, Jozef   public:
16e2362796SWludzik, Jozef     ReportParams reportParams;
172f9f9b87SWludzik, Jozef 
182f9f9b87SWludzik, Jozef     std::unique_ptr<ReportFactoryMock> reportFactoryMockPtr =
192f9f9b87SWludzik, Jozef         std::make_unique<StrictMock<ReportFactoryMock>>();
202f9f9b87SWludzik, Jozef     ReportFactoryMock& reportFactoryMock = *reportFactoryMockPtr;
21e2362796SWludzik, Jozef 
22e2362796SWludzik, Jozef     std::unique_ptr<StorageMock> storageMockPtr =
23e2362796SWludzik, Jozef         std::make_unique<NiceMock<StorageMock>>();
24e2362796SWludzik, Jozef     StorageMock& storageMock = *storageMockPtr;
25e2362796SWludzik, Jozef 
26d2238194SKrzysztof Grobelny     std::unique_ptr<ReportMock> reportMockPtr =
27d2238194SKrzysztof Grobelny         std::make_unique<NiceMock<ReportMock>>(reportParams.reportName());
28d2238194SKrzysztof Grobelny     ReportMock& reportMock = *reportMockPtr;
29d2238194SKrzysztof Grobelny 
30e2362796SWludzik, Jozef     std::unique_ptr<ReportManager> sut;
312f9f9b87SWludzik, Jozef 
322f9f9b87SWludzik, Jozef     MockFunction<void(std::string)> checkPoint;
332f9f9b87SWludzik, Jozef 
34e2362796SWludzik, Jozef     void SetUp() override
35e2362796SWludzik, Jozef     {
36e2362796SWludzik, Jozef         sut = std::make_unique<ReportManager>(std::move(reportFactoryMockPtr),
37e2362796SWludzik, Jozef                                               std::move(storageMockPtr),
38e2362796SWludzik, Jozef                                               DbusEnvironment::getObjServer());
39e2362796SWludzik, Jozef     }
40e2362796SWludzik, Jozef 
412f9f9b87SWludzik, Jozef     void TearDown() override
422f9f9b87SWludzik, Jozef     {
432f9f9b87SWludzik, Jozef         DbusEnvironment::synchronizeIoc();
442f9f9b87SWludzik, Jozef     }
452f9f9b87SWludzik, Jozef 
462f9f9b87SWludzik, Jozef     std::pair<boost::system::error_code, std::string>
47e2362796SWludzik, Jozef         addReport(const ReportParams& params)
482f9f9b87SWludzik, Jozef     {
492f9f9b87SWludzik, Jozef         std::promise<std::pair<boost::system::error_code, std::string>>
502f9f9b87SWludzik, Jozef             addReportPromise;
512f9f9b87SWludzik, Jozef         DbusEnvironment::getBus()->async_method_call(
522f9f9b87SWludzik, Jozef             [&addReportPromise](boost::system::error_code ec,
532f9f9b87SWludzik, Jozef                                 const std::string& path) {
542f9f9b87SWludzik, Jozef                 addReportPromise.set_value({ec, path});
552f9f9b87SWludzik, Jozef             },
562f9f9b87SWludzik, Jozef             DbusEnvironment::serviceName(), ReportManager::reportManagerPath,
57e2362796SWludzik, Jozef             ReportManager::reportManagerIfaceName, "AddReport",
58e2362796SWludzik, Jozef             params.reportName(), params.reportingType(),
59e2362796SWludzik, Jozef             params.emitReadingUpdate(), params.logToMetricReportCollection(),
60e2362796SWludzik, Jozef             static_cast<uint64_t>(params.interval().count()),
61e2362796SWludzik, Jozef             params.readingParameters());
62f32f6fefSKrzysztof Grobelny         return DbusEnvironment::waitForFuture(addReportPromise.get_future());
632f9f9b87SWludzik, Jozef     }
642f9f9b87SWludzik, Jozef 
652f9f9b87SWludzik, Jozef     template <class T>
662f9f9b87SWludzik, Jozef     static T getProperty(std::string property)
672f9f9b87SWludzik, Jozef     {
682f9f9b87SWludzik, Jozef         std::promise<T> propertyPromise;
692f9f9b87SWludzik, Jozef         sdbusplus::asio::getProperty<T>(
702f9f9b87SWludzik, Jozef             *DbusEnvironment::getBus(), DbusEnvironment::serviceName(),
712f9f9b87SWludzik, Jozef             ReportManager::reportManagerPath,
722f9f9b87SWludzik, Jozef             ReportManager::reportManagerIfaceName, property,
732f9f9b87SWludzik, Jozef             [&propertyPromise](boost::system::error_code ec) {
742f9f9b87SWludzik, Jozef                 EXPECT_THAT(static_cast<bool>(ec), ::testing::Eq(false));
752f9f9b87SWludzik, Jozef                 propertyPromise.set_value(T{});
762f9f9b87SWludzik, Jozef             },
772f9f9b87SWludzik, Jozef             [&propertyPromise](T t) { propertyPromise.set_value(t); });
78f32f6fefSKrzysztof Grobelny         return DbusEnvironment::waitForFuture(propertyPromise.get_future());
792f9f9b87SWludzik, Jozef     }
802f9f9b87SWludzik, Jozef };
812f9f9b87SWludzik, Jozef 
822f9f9b87SWludzik, Jozef TEST_F(TestReportManager, minInterval)
832f9f9b87SWludzik, Jozef {
842f9f9b87SWludzik, Jozef     EXPECT_THAT(getProperty<uint64_t>("MinInterval"),
852f9f9b87SWludzik, Jozef                 Eq(static_cast<uint64_t>(ReportManager::minInterval.count())));
862f9f9b87SWludzik, Jozef }
872f9f9b87SWludzik, Jozef 
882f9f9b87SWludzik, Jozef TEST_F(TestReportManager, maxReports)
892f9f9b87SWludzik, Jozef {
902f9f9b87SWludzik, Jozef     EXPECT_THAT(getProperty<uint32_t>("MaxReports"),
912f9f9b87SWludzik, Jozef                 Eq(ReportManager::maxReports));
922f9f9b87SWludzik, Jozef }
932f9f9b87SWludzik, Jozef 
942f9f9b87SWludzik, Jozef TEST_F(TestReportManager, addReport)
952f9f9b87SWludzik, Jozef {
96d2238194SKrzysztof Grobelny     reportFactoryMock.expectMake(_, reportParams, Ref(*sut), Ref(storageMock))
972f9f9b87SWludzik, Jozef         .WillOnce(Return(ByMove(std::move(reportMockPtr))));
982f9f9b87SWludzik, Jozef 
99e2362796SWludzik, Jozef     auto [ec, path] = addReport(reportParams);
1002f9f9b87SWludzik, Jozef     EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
1012f9f9b87SWludzik, Jozef     EXPECT_THAT(path, Eq(reportMock.getPath()));
1022f9f9b87SWludzik, Jozef }
1032f9f9b87SWludzik, Jozef 
104e2362796SWludzik, Jozef TEST_F(TestReportManager, DISABLED_failToAddReportTwice)
1052f9f9b87SWludzik, Jozef {
106d2238194SKrzysztof Grobelny     reportFactoryMock.expectMake(_, reportParams, Ref(*sut), Ref(storageMock))
107d2238194SKrzysztof Grobelny         .WillOnce(Return(ByMove(std::move(reportMockPtr))));
1082f9f9b87SWludzik, Jozef 
109e2362796SWludzik, Jozef     addReport(reportParams);
1102f9f9b87SWludzik, Jozef 
111e2362796SWludzik, Jozef     auto [ec, path] = addReport(reportParams);
1122f9f9b87SWludzik, Jozef     EXPECT_THAT(ec.value(), Eq(boost::system::errc::file_exists));
1132f9f9b87SWludzik, Jozef     EXPECT_THAT(path, Eq(std::string()));
1142f9f9b87SWludzik, Jozef }
1152f9f9b87SWludzik, Jozef 
116e2362796SWludzik, Jozef TEST_F(TestReportManager, DISABLED_failToAddReportWithInvalidInterval)
1172f9f9b87SWludzik, Jozef {
118d2238194SKrzysztof Grobelny     reportFactoryMock.expectMake(_, std::nullopt, Ref(*sut), Ref(storageMock))
119d2238194SKrzysztof Grobelny         .Times(0);
120d2238194SKrzysztof Grobelny     reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock), _)
121d2238194SKrzysztof Grobelny         .Times(0);
1222f9f9b87SWludzik, Jozef 
123*bc766b4dSWludzik, Jozef     reportParams.reportingType("Periodic");
124e2362796SWludzik, Jozef     reportParams.interval(reportParams.interval() - 1ms);
1252f9f9b87SWludzik, Jozef 
126e2362796SWludzik, Jozef     auto [ec, path] = addReport(reportParams);
1272f9f9b87SWludzik, Jozef     EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
1282f9f9b87SWludzik, Jozef     EXPECT_THAT(path, Eq(std::string()));
1292f9f9b87SWludzik, Jozef }
1302f9f9b87SWludzik, Jozef 
131*bc766b4dSWludzik, Jozef TEST_F(TestReportManager, DISABLED_failToAddReportWithInvalidReportingType)
132*bc766b4dSWludzik, Jozef {
133*bc766b4dSWludzik, Jozef     reportFactoryMock.expectMake(_, std::nullopt, Ref(*sut), Ref(storageMock))
134*bc766b4dSWludzik, Jozef         .Times(0);
135*bc766b4dSWludzik, Jozef     reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock), _)
136*bc766b4dSWludzik, Jozef         .Times(0);
137*bc766b4dSWludzik, Jozef 
138*bc766b4dSWludzik, Jozef     reportParams.reportingType("Invalid");
139*bc766b4dSWludzik, Jozef 
140*bc766b4dSWludzik, Jozef     auto [ec, path] = addReport(reportParams);
141*bc766b4dSWludzik, Jozef     EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
142*bc766b4dSWludzik, Jozef     EXPECT_THAT(path, Eq(std::string()));
143*bc766b4dSWludzik, Jozef }
144*bc766b4dSWludzik, Jozef 
145*bc766b4dSWludzik, Jozef TEST_F(TestReportManager, DISABLED_failToAddReportWithMoreSensorsThanExpected)
146*bc766b4dSWludzik, Jozef {
147*bc766b4dSWludzik, Jozef     reportFactoryMock.expectMake(_, std::nullopt, Ref(*sut), Ref(storageMock))
148*bc766b4dSWludzik, Jozef         .Times(0);
149*bc766b4dSWludzik, Jozef     reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock), _)
150*bc766b4dSWludzik, Jozef         .Times(0);
151*bc766b4dSWludzik, Jozef 
152*bc766b4dSWludzik, Jozef     auto readingParams = reportParams.readingParameters();
153*bc766b4dSWludzik, Jozef     for (size_t i = 0; i < ReportManager::maxReadingParams + 1; i++)
154*bc766b4dSWludzik, Jozef     {
155*bc766b4dSWludzik, Jozef         readingParams.push_back(readingParams.front());
156*bc766b4dSWludzik, Jozef     }
157*bc766b4dSWludzik, Jozef     reportParams.readingParameters(std::move(readingParams));
158*bc766b4dSWludzik, Jozef 
159*bc766b4dSWludzik, Jozef     auto [ec, path] = addReport(reportParams);
160*bc766b4dSWludzik, Jozef     EXPECT_THAT(ec.value(), Eq(boost::system::errc::argument_list_too_long));
161*bc766b4dSWludzik, Jozef     EXPECT_THAT(path, Eq(std::string()));
162*bc766b4dSWludzik, Jozef }
163*bc766b4dSWludzik, Jozef 
164e2362796SWludzik, Jozef TEST_F(TestReportManager, DISABLED_failToAddReportWhenMaxReportIsReached)
1652f9f9b87SWludzik, Jozef {
166d2238194SKrzysztof Grobelny     reportFactoryMock.expectMake(_, std::nullopt, Ref(*sut), Ref(storageMock))
1672f9f9b87SWludzik, Jozef         .Times(ReportManager::maxReports);
1682f9f9b87SWludzik, Jozef 
1692f9f9b87SWludzik, Jozef     for (size_t i = 0; i < ReportManager::maxReports; i++)
1702f9f9b87SWludzik, Jozef     {
171e2362796SWludzik, Jozef         reportParams.reportName(reportParams.reportName() + std::to_string(i));
1722f9f9b87SWludzik, Jozef 
173e2362796SWludzik, Jozef         auto [ec, path] = addReport(reportParams);
1742f9f9b87SWludzik, Jozef         EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
1752f9f9b87SWludzik, Jozef     }
1762f9f9b87SWludzik, Jozef 
177e2362796SWludzik, Jozef     reportParams.reportName(reportParams.reportName() +
178e2362796SWludzik, Jozef                             std::to_string(ReportManager::maxReports));
179e2362796SWludzik, Jozef     auto [ec, path] = addReport(reportParams);
1802f9f9b87SWludzik, Jozef     EXPECT_THAT(ec.value(), Eq(boost::system::errc::too_many_files_open));
1812f9f9b87SWludzik, Jozef     EXPECT_THAT(path, Eq(std::string()));
1822f9f9b87SWludzik, Jozef }
1832f9f9b87SWludzik, Jozef 
1842f9f9b87SWludzik, Jozef TEST_F(TestReportManager, removeReport)
1852f9f9b87SWludzik, Jozef {
1862f9f9b87SWludzik, Jozef     {
1872f9f9b87SWludzik, Jozef         InSequence seq;
188d2238194SKrzysztof Grobelny         reportFactoryMock
189d2238194SKrzysztof Grobelny             .expectMake(_, reportParams, Ref(*sut), Ref(storageMock))
1902f9f9b87SWludzik, Jozef             .WillOnce(Return(ByMove(std::move(reportMockPtr))));
1912f9f9b87SWludzik, Jozef         EXPECT_CALL(reportMock, Die());
1922f9f9b87SWludzik, Jozef         EXPECT_CALL(checkPoint, Call("end"));
1932f9f9b87SWludzik, Jozef     }
1942f9f9b87SWludzik, Jozef 
195e2362796SWludzik, Jozef     addReport(reportParams);
196e2362796SWludzik, Jozef     sut->removeReport(&reportMock);
1972f9f9b87SWludzik, Jozef     checkPoint.Call("end");
1982f9f9b87SWludzik, Jozef }
1992f9f9b87SWludzik, Jozef 
2002f9f9b87SWludzik, Jozef TEST_F(TestReportManager, removingReportThatIsNotInContainerHasNoEffect)
2012f9f9b87SWludzik, Jozef {
2022f9f9b87SWludzik, Jozef     {
2032f9f9b87SWludzik, Jozef         InSequence seq;
2042f9f9b87SWludzik, Jozef         EXPECT_CALL(checkPoint, Call("end"));
2052f9f9b87SWludzik, Jozef         EXPECT_CALL(reportMock, Die());
2062f9f9b87SWludzik, Jozef     }
2072f9f9b87SWludzik, Jozef 
208e2362796SWludzik, Jozef     sut->removeReport(&reportMock);
2092f9f9b87SWludzik, Jozef     checkPoint.Call("end");
2102f9f9b87SWludzik, Jozef }
2112f9f9b87SWludzik, Jozef 
2122f9f9b87SWludzik, Jozef TEST_F(TestReportManager, removingSameReportTwiceHasNoSideEffect)
2132f9f9b87SWludzik, Jozef {
2142f9f9b87SWludzik, Jozef     {
2152f9f9b87SWludzik, Jozef         InSequence seq;
216d2238194SKrzysztof Grobelny         reportFactoryMock
217d2238194SKrzysztof Grobelny             .expectMake(_, reportParams, Ref(*sut), Ref(storageMock))
2182f9f9b87SWludzik, Jozef             .WillOnce(Return(ByMove(std::move(reportMockPtr))));
2192f9f9b87SWludzik, Jozef         EXPECT_CALL(reportMock, Die());
2202f9f9b87SWludzik, Jozef         EXPECT_CALL(checkPoint, Call("end"));
2212f9f9b87SWludzik, Jozef     }
2222f9f9b87SWludzik, Jozef 
223e2362796SWludzik, Jozef     addReport(reportParams);
224e2362796SWludzik, Jozef     sut->removeReport(&reportMock);
225e2362796SWludzik, Jozef     sut->removeReport(&reportMock);
2262f9f9b87SWludzik, Jozef     checkPoint.Call("end");
2272f9f9b87SWludzik, Jozef }
228e2362796SWludzik, Jozef 
229e2362796SWludzik, Jozef class TestReportManagerStorage : public TestReportManager
230e2362796SWludzik, Jozef {
231e2362796SWludzik, Jozef   public:
232e2362796SWludzik, Jozef     using FilePath = interfaces::JsonStorage::FilePath;
233e2362796SWludzik, Jozef     using DirectoryPath = interfaces::JsonStorage::DirectoryPath;
234e2362796SWludzik, Jozef 
235e2362796SWludzik, Jozef     void SetUp() override
236e2362796SWludzik, Jozef     {
237e2362796SWludzik, Jozef         ON_CALL(storageMock, list())
238e2362796SWludzik, Jozef             .WillByDefault(Return(std::vector<FilePath>{FilePath("report1")}));
239e2362796SWludzik, Jozef         ON_CALL(storageMock, load(FilePath("report1")))
2406ccfcbf5SKrzysztof Grobelny             .WillByDefault(InvokeWithoutArgs([this] { return data; }));
241e2362796SWludzik, Jozef     }
242e2362796SWludzik, Jozef 
243e2362796SWludzik, Jozef     void makeReportManager()
244e2362796SWludzik, Jozef     {
245e2362796SWludzik, Jozef         sut = std::make_unique<ReportManager>(std::move(reportFactoryMockPtr),
246e2362796SWludzik, Jozef                                               std::move(storageMockPtr),
247e2362796SWludzik, Jozef                                               DbusEnvironment::getObjServer());
248e2362796SWludzik, Jozef     }
249e2362796SWludzik, Jozef 
250d2238194SKrzysztof Grobelny     static std::vector<LabeledMetricParameters>
251d2238194SKrzysztof Grobelny         convertToLabeled(const ReadingParameters& params)
252d2238194SKrzysztof Grobelny     {
253d2238194SKrzysztof Grobelny         return utils::transform(params, [](const auto& item) {
254d2238194SKrzysztof Grobelny             return LabeledMetricParameters(
255d2238194SKrzysztof Grobelny                 utils::transform(std::get<0>(item),
256d2238194SKrzysztof Grobelny                                  [](const auto& elem) {
257d2238194SKrzysztof Grobelny                                      return LabeledSensorParameters("service",
258d2238194SKrzysztof Grobelny                                                                     elem);
259d2238194SKrzysztof Grobelny                                  }),
260d2238194SKrzysztof Grobelny                 std::get<1>(item), std::get<2>(item), std::get<3>(item));
261d2238194SKrzysztof Grobelny         });
262d2238194SKrzysztof Grobelny     }
263d2238194SKrzysztof Grobelny 
264e2362796SWludzik, Jozef     nlohmann::json data = nlohmann::json{
265e2362796SWludzik, Jozef         {"Version", Report::reportVersion},
266e2362796SWludzik, Jozef         {"Name", reportParams.reportName()},
267e2362796SWludzik, Jozef         {"ReportingType", reportParams.reportingType()},
268e2362796SWludzik, Jozef         {"EmitsReadingsUpdate", reportParams.emitReadingUpdate()},
269e2362796SWludzik, Jozef         {"LogToMetricReportsCollection",
270e2362796SWludzik, Jozef          reportParams.logToMetricReportCollection()},
271e2362796SWludzik, Jozef         {"Interval", reportParams.interval().count()},
272e2362796SWludzik, Jozef         {"ReadingParameters",
273d2238194SKrzysztof Grobelny          convertToLabeled(reportParams.readingParameters())}};
274e2362796SWludzik, Jozef };
275e2362796SWludzik, Jozef 
276e2362796SWludzik, Jozef TEST_F(TestReportManagerStorage, reportManagerCtorAddReportFromStorage)
277e2362796SWludzik, Jozef {
278d2238194SKrzysztof Grobelny     reportFactoryMock.expectMake(
279d2238194SKrzysztof Grobelny         reportParams, _, Ref(storageMock),
280d2238194SKrzysztof Grobelny         ElementsAreArray(convertToLabeled(reportParams.readingParameters())));
281e2362796SWludzik, Jozef 
282e2362796SWludzik, Jozef     makeReportManager();
283e2362796SWludzik, Jozef }
284e2362796SWludzik, Jozef 
285e2362796SWludzik, Jozef TEST_F(TestReportManagerStorage,
286e2362796SWludzik, Jozef        reportManagerCtorRemoveFileIfVersionDoesNotMatch)
287e2362796SWludzik, Jozef {
288e2362796SWludzik, Jozef     data["Version"] = Report::reportVersion - 1;
289e2362796SWludzik, Jozef 
290e2362796SWludzik, Jozef     EXPECT_CALL(storageMock, remove(FilePath("report1")));
291e2362796SWludzik, Jozef 
292e2362796SWludzik, Jozef     makeReportManager();
293e2362796SWludzik, Jozef }
294e2362796SWludzik, Jozef 
295e2362796SWludzik, Jozef TEST_F(TestReportManagerStorage,
296e2362796SWludzik, Jozef        reportManagerCtorRemoveFileIfIntervalHasWrongType)
297e2362796SWludzik, Jozef {
298e2362796SWludzik, Jozef     data["Interval"] = "1000";
299e2362796SWludzik, Jozef 
300e2362796SWludzik, Jozef     EXPECT_CALL(storageMock, remove(FilePath("report1")));
301e2362796SWludzik, Jozef 
302e2362796SWludzik, Jozef     makeReportManager();
303e2362796SWludzik, Jozef }
304