blob: eeedd96dff27c2b9fde63ce1d8f468ec593373d4 [file] [log] [blame]
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +02001#include "dbus_environment.hpp"
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +00002#include "helpers.hpp"
Wludzik, Jozefe2362792020-10-27 17:23:55 +01003#include "mocks/json_storage_mock.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +02004#include "mocks/report_factory_mock.hpp"
Wludzik, Jozefe2362792020-10-27 17:23:55 +01005#include "params/report_params.hpp"
6#include "report.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +02007#include "report_manager.hpp"
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +00008#include "utils/conversion.hpp"
Wludzik, Jozefe2362792020-10-27 17:23:55 +01009#include "utils/transform.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020010
11using namespace testing;
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000012using namespace std::string_literals;
Wludzik, Jozefe2362792020-10-27 17:23:55 +010013using namespace std::chrono_literals;
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020014
15class TestReportManager : public Test
16{
17 public:
Wludzik, Jozefe2362792020-10-27 17:23:55 +010018 ReportParams reportParams;
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020019
20 std::unique_ptr<ReportFactoryMock> reportFactoryMockPtr =
21 std::make_unique<StrictMock<ReportFactoryMock>>();
22 ReportFactoryMock& reportFactoryMock = *reportFactoryMockPtr;
Wludzik, Jozefe2362792020-10-27 17:23:55 +010023
24 std::unique_ptr<StorageMock> storageMockPtr =
25 std::make_unique<NiceMock<StorageMock>>();
26 StorageMock& storageMock = *storageMockPtr;
27
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000028 std::unique_ptr<ReportMock> reportMockPtr =
29 std::make_unique<NiceMock<ReportMock>>(reportParams.reportName());
30 ReportMock& reportMock = *reportMockPtr;
31
Wludzik, Jozefe2362792020-10-27 17:23:55 +010032 std::unique_ptr<ReportManager> sut;
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020033
34 MockFunction<void(std::string)> checkPoint;
35
Wludzik, Jozefe2362792020-10-27 17:23:55 +010036 void SetUp() override
37 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000038 EXPECT_CALL(reportFactoryMock, convertMetricParams(_, _))
39 .Times(AnyNumber());
40
Wludzik, Jozefe2362792020-10-27 17:23:55 +010041 sut = std::make_unique<ReportManager>(std::move(reportFactoryMockPtr),
42 std::move(storageMockPtr),
43 DbusEnvironment::getObjServer());
44 }
45
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020046 void TearDown() override
47 {
48 DbusEnvironment::synchronizeIoc();
49 }
50
51 std::pair<boost::system::error_code, std::string>
Wludzik, Jozefe2362792020-10-27 17:23:55 +010052 addReport(const ReportParams& params)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020053 {
54 std::promise<std::pair<boost::system::error_code, std::string>>
55 addReportPromise;
56 DbusEnvironment::getBus()->async_method_call(
57 [&addReportPromise](boost::system::error_code ec,
58 const std::string& path) {
59 addReportPromise.set_value({ec, path});
60 },
61 DbusEnvironment::serviceName(), ReportManager::reportManagerPath,
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000062 ReportManager::reportManagerIfaceName, "AddReportFutureVersion",
Wludzik, Jozefe2362792020-10-27 17:23:55 +010063 params.reportName(), params.reportingType(),
64 params.emitReadingUpdate(), params.logToMetricReportCollection(),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000065 params.interval().count(),
66 toReadingParameters(params.metricParameters()));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +010067 return DbusEnvironment::waitForFuture(addReportPromise.get_future());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020068 }
69
70 template <class T>
Szymon Dompkee28aa532021-10-27 12:33:12 +020071 static T getProperty(const std::string& property)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020072 {
Szymon Dompkee28aa532021-10-27 12:33:12 +020073 return DbusEnvironment::getProperty<T>(
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020074 ReportManager::reportManagerPath,
Szymon Dompkee28aa532021-10-27 12:33:12 +020075 ReportManager::reportManagerIfaceName, property);
Karol Niczyj32859b62021-05-19 10:20:46 +020076 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020077};
78
79TEST_F(TestReportManager, minInterval)
80{
81 EXPECT_THAT(getProperty<uint64_t>("MinInterval"),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000082 Eq(ReportManager::minInterval.count()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020083}
84
85TEST_F(TestReportManager, maxReports)
86{
Wludzik, Jozef503c1582020-12-11 14:48:01 +010087 EXPECT_THAT(getProperty<size_t>("MaxReports"),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020088 Eq(ReportManager::maxReports));
89}
90
91TEST_F(TestReportManager, addReport)
92{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000093 EXPECT_CALL(reportFactoryMock, convertMetricParams(_, _));
94 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock))
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020095 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
96
Wludzik, Jozefe2362792020-10-27 17:23:55 +010097 auto [ec, path] = addReport(reportParams);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020098 EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
99 EXPECT_THAT(path, Eq(reportMock.getPath()));
100}
101
Karol Niczyj32859b62021-05-19 10:20:46 +0200102TEST_F(TestReportManager, addReportWithMaxLengthName)
103{
Szymon Dompkee28aa532021-10-27 12:33:12 +0200104 std::string reportName(ReportManager::maxReportNameLength, 'z');
Karol Niczyj32859b62021-05-19 10:20:46 +0200105 reportParams.reportName(reportName);
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000106 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock));
Karol Niczyj32859b62021-05-19 10:20:46 +0200107
108 auto [ec, path] = addReport(reportParams);
109
110 EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
111 EXPECT_THAT(path, Eq("/"s + reportName));
112}
113
114TEST_F(TestReportManager, DISABLED_failToAddReportWithTooLongName)
115{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000116 reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
Karol Niczyj32859b62021-05-19 10:20:46 +0200117 .Times(0);
118
119 reportParams.reportName(
Szymon Dompkee28aa532021-10-27 12:33:12 +0200120 std::string(ReportManager::maxReportNameLength + 1, 'z'));
Karol Niczyj32859b62021-05-19 10:20:46 +0200121
122 auto [ec, path] = addReport(reportParams);
123
124 EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
125 EXPECT_THAT(path, Eq(std::string()));
126}
127
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100128TEST_F(TestReportManager, DISABLED_failToAddReportTwice)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200129{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000130 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock))
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000131 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200132
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100133 addReport(reportParams);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200134
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100135 auto [ec, path] = addReport(reportParams);
Karol Niczyj32859b62021-05-19 10:20:46 +0200136
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200137 EXPECT_THAT(ec.value(), Eq(boost::system::errc::file_exists));
138 EXPECT_THAT(path, Eq(std::string()));
139}
140
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100141TEST_F(TestReportManager, DISABLED_failToAddReportWithInvalidInterval)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200142{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000143 reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000144 .Times(0);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200145
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100146 reportParams.reportingType("Periodic");
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100147 reportParams.interval(reportParams.interval() - 1ms);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200148
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100149 auto [ec, path] = addReport(reportParams);
Karol Niczyj32859b62021-05-19 10:20:46 +0200150
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200151 EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
152 EXPECT_THAT(path, Eq(std::string()));
153}
154
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100155TEST_F(TestReportManager, DISABLED_failToAddReportWithInvalidReportingType)
156{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000157 reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100158 .Times(0);
159
160 reportParams.reportingType("Invalid");
161
162 auto [ec, path] = addReport(reportParams);
Karol Niczyj32859b62021-05-19 10:20:46 +0200163
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100164 EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
165 EXPECT_THAT(path, Eq(std::string()));
166}
167
168TEST_F(TestReportManager, DISABLED_failToAddReportWithMoreSensorsThanExpected)
169{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000170 reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100171 .Times(0);
172
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000173 auto metricParams = reportParams.metricParameters();
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100174 for (size_t i = 0; i < ReportManager::maxReadingParams + 1; i++)
175 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000176 metricParams.push_back(metricParams.front());
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100177 }
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000178 reportParams.metricParameters(std::move(metricParams));
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100179
180 auto [ec, path] = addReport(reportParams);
Karol Niczyj32859b62021-05-19 10:20:46 +0200181
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100182 EXPECT_THAT(ec.value(), Eq(boost::system::errc::argument_list_too_long));
183 EXPECT_THAT(path, Eq(std::string()));
184}
185
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100186TEST_F(TestReportManager, DISABLED_failToAddReportWhenMaxReportIsReached)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200187{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000188 reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200189 .Times(ReportManager::maxReports);
190
191 for (size_t i = 0; i < ReportManager::maxReports; i++)
192 {
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100193 reportParams.reportName(reportParams.reportName() + std::to_string(i));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200194
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100195 auto [ec, path] = addReport(reportParams);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200196 EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
197 }
198
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100199 reportParams.reportName(reportParams.reportName() +
200 std::to_string(ReportManager::maxReports));
201 auto [ec, path] = addReport(reportParams);
Karol Niczyj32859b62021-05-19 10:20:46 +0200202
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200203 EXPECT_THAT(ec.value(), Eq(boost::system::errc::too_many_files_open));
204 EXPECT_THAT(path, Eq(std::string()));
205}
206
207TEST_F(TestReportManager, removeReport)
208{
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200209 {
210 InSequence seq;
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000211 EXPECT_CALL(reportFactoryMock, convertMetricParams(_, _));
212 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock))
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200213 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
214 EXPECT_CALL(reportMock, Die());
215 EXPECT_CALL(checkPoint, Call("end"));
216 }
217
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100218 addReport(reportParams);
219 sut->removeReport(&reportMock);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200220 checkPoint.Call("end");
221}
222
223TEST_F(TestReportManager, removingReportThatIsNotInContainerHasNoEffect)
224{
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200225 {
226 InSequence seq;
227 EXPECT_CALL(checkPoint, Call("end"));
228 EXPECT_CALL(reportMock, Die());
229 }
230
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100231 sut->removeReport(&reportMock);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200232 checkPoint.Call("end");
233}
234
235TEST_F(TestReportManager, removingSameReportTwiceHasNoSideEffect)
236{
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200237 {
238 InSequence seq;
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000239 EXPECT_CALL(reportFactoryMock, convertMetricParams(_, _));
240 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock))
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200241 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
242 EXPECT_CALL(reportMock, Die());
243 EXPECT_CALL(checkPoint, Call("end"));
244 }
245
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100246 addReport(reportParams);
247 sut->removeReport(&reportMock);
248 sut->removeReport(&reportMock);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200249 checkPoint.Call("end");
250}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100251
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100252TEST_F(TestReportManager, updateReportCallsUpdateReadingsForExistReport)
253{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000254 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock))
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100255 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
256 EXPECT_CALL(reportMock, updateReadings());
257
258 addReport(reportParams);
259 sut->updateReport(reportParams.reportName());
260}
261
262TEST_F(TestReportManager, updateReportDoNothingIfReportDoesNotExist)
263{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000264 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock))
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100265 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
266 EXPECT_CALL(reportMock, updateReadings()).Times(0);
267
268 addReport(reportParams);
269 sut->updateReport("NotAReport");
270}
271
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000272class TestReportManagerWithAggregationOperationType :
273 public TestReportManager,
274 public WithParamInterface<OperationType>
275{
276 public:
277 OperationType operationType = GetParam();
278};
279
280INSTANTIATE_TEST_SUITE_P(_, TestReportManagerWithAggregationOperationType,
281 Values(OperationType::single, OperationType::max,
282 OperationType::min, OperationType::avg,
283 OperationType::sum));
284
285TEST_P(TestReportManagerWithAggregationOperationType,
286 addReportWithDifferentOperationTypes)
287{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000288 reportParams.metricParameters(
289 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
290 {LabeledSensorParameters{"Service",
291 "/xyz/openbmc_project/sensors/power/p1"}},
292 operationType,
293 "MetricId1",
294 "Metadata1",
295 CollectionTimeScope::point,
296 CollectionDuration(Milliseconds(0u))}}});
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000297
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000298 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock))
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000299 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
300
301 auto [ec, path] = addReport(reportParams);
Karol Niczyj32859b62021-05-19 10:20:46 +0200302
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000303 EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
304 EXPECT_THAT(path, Eq("/"s + reportParams.reportName()));
305}
306
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100307class TestReportManagerStorage : public TestReportManager
308{
309 public:
310 using FilePath = interfaces::JsonStorage::FilePath;
311 using DirectoryPath = interfaces::JsonStorage::DirectoryPath;
312
313 void SetUp() override
314 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000315 EXPECT_CALL(reportFactoryMock, convertMetricParams(_, _)).Times(0);
316
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100317 ON_CALL(storageMock, list())
318 .WillByDefault(Return(std::vector<FilePath>{FilePath("report1")}));
319 ON_CALL(storageMock, load(FilePath("report1")))
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100320 .WillByDefault(InvokeWithoutArgs([this] { return data; }));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100321 }
322
323 void makeReportManager()
324 {
325 sut = std::make_unique<ReportManager>(std::move(reportFactoryMockPtr),
326 std::move(storageMockPtr),
327 DbusEnvironment::getObjServer());
328 }
329
330 nlohmann::json data = nlohmann::json{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200331 {"Enabled", reportParams.enabled()},
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100332 {"Version", Report::reportVersion},
333 {"Name", reportParams.reportName()},
334 {"ReportingType", reportParams.reportingType()},
335 {"EmitsReadingsUpdate", reportParams.emitReadingUpdate()},
336 {"LogToMetricReportsCollection",
337 reportParams.logToMetricReportCollection()},
338 {"Interval", reportParams.interval().count()},
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000339 {"ReadingParameters", reportParams.metricParameters()}};
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100340};
341
342TEST_F(TestReportManagerStorage, reportManagerCtorAddReportFromStorage)
343{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000344 reportFactoryMock.expectMake(reportParams, _, Ref(storageMock));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100345
346 makeReportManager();
347}
348
349TEST_F(TestReportManagerStorage,
350 reportManagerCtorRemoveFileIfVersionDoesNotMatch)
351{
352 data["Version"] = Report::reportVersion - 1;
353
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100354 EXPECT_CALL(storageMock, remove(FilePath("report1")));
355
356 makeReportManager();
357}
358
359TEST_F(TestReportManagerStorage,
360 reportManagerCtorRemoveFileIfIntervalHasWrongType)
361{
362 data["Interval"] = "1000";
363
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100364 EXPECT_CALL(storageMock, remove(FilePath("report1")));
365
366 makeReportManager();
367}