blob: 22877075683c43b0dc9a4ccf5bbd5e36010dbad3 [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"
Ed Tanous0e7ae5d2021-02-23 14:06:49 -08009#include "utils/set_exception.hpp"
Wludzik, Jozefe2362792020-10-27 17:23:55 +010010#include "utils/transform.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020011
12using namespace testing;
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000013using namespace std::string_literals;
Wludzik, Jozefe2362792020-10-27 17:23:55 +010014using namespace std::chrono_literals;
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020015
16class TestReportManager : public Test
17{
18 public:
Wludzik, Jozefe2362792020-10-27 17:23:55 +010019 ReportParams reportParams;
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020020
21 std::unique_ptr<ReportFactoryMock> reportFactoryMockPtr =
22 std::make_unique<StrictMock<ReportFactoryMock>>();
23 ReportFactoryMock& reportFactoryMock = *reportFactoryMockPtr;
Wludzik, Jozefe2362792020-10-27 17:23:55 +010024
25 std::unique_ptr<StorageMock> storageMockPtr =
26 std::make_unique<NiceMock<StorageMock>>();
27 StorageMock& storageMock = *storageMockPtr;
28
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000029 std::unique_ptr<ReportMock> reportMockPtr =
30 std::make_unique<NiceMock<ReportMock>>(reportParams.reportName());
31 ReportMock& reportMock = *reportMockPtr;
32
Wludzik, Jozefe2362792020-10-27 17:23:55 +010033 std::unique_ptr<ReportManager> sut;
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020034
35 MockFunction<void(std::string)> checkPoint;
36
Wludzik, Jozefe2362792020-10-27 17:23:55 +010037 void SetUp() override
38 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000039 EXPECT_CALL(reportFactoryMock, convertMetricParams(_, _))
40 .Times(AnyNumber());
41
Wludzik, Jozefe2362792020-10-27 17:23:55 +010042 sut = std::make_unique<ReportManager>(std::move(reportFactoryMockPtr),
43 std::move(storageMockPtr),
44 DbusEnvironment::getObjServer());
45 }
46
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020047 void TearDown() override
48 {
49 DbusEnvironment::synchronizeIoc();
50 }
51
52 std::pair<boost::system::error_code, std::string>
Wludzik, Jozefe2362792020-10-27 17:23:55 +010053 addReport(const ReportParams& params)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020054 {
55 std::promise<std::pair<boost::system::error_code, std::string>>
56 addReportPromise;
57 DbusEnvironment::getBus()->async_method_call(
58 [&addReportPromise](boost::system::error_code ec,
59 const std::string& path) {
60 addReportPromise.set_value({ec, path});
61 },
62 DbusEnvironment::serviceName(), ReportManager::reportManagerPath,
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000063 ReportManager::reportManagerIfaceName, "AddReportFutureVersion",
Wludzik, Jozefe2362792020-10-27 17:23:55 +010064 params.reportName(), params.reportingType(),
65 params.emitReadingUpdate(), params.logToMetricReportCollection(),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000066 params.interval().count(),
67 toReadingParameters(params.metricParameters()));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +010068 return DbusEnvironment::waitForFuture(addReportPromise.get_future());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020069 }
70
71 template <class T>
72 static T getProperty(std::string property)
73 {
Ed Tanous0e7ae5d2021-02-23 14:06:49 -080074 auto propertyPromise = std::promise<T>();
75 auto propertyFuture = propertyPromise.get_future();
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020076 sdbusplus::asio::getProperty<T>(
77 *DbusEnvironment::getBus(), DbusEnvironment::serviceName(),
78 ReportManager::reportManagerPath,
79 ReportManager::reportManagerIfaceName, property,
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000080 [&propertyPromise](const boost::system::error_code& ec, T t) {
Ed Tanous0e7ae5d2021-02-23 14:06:49 -080081 if (ec)
82 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000083 utils::setException(propertyPromise, "Get property failed");
Ed Tanous0e7ae5d2021-02-23 14:06:49 -080084 return;
85 }
86 propertyPromise.set_value(t);
87 });
88 return DbusEnvironment::waitForFuture(std::move(propertyFuture));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020089 }
Karol Niczyj32859b62021-05-19 10:20:46 +020090
91 static std::string prepareReportNameWithLength(size_t length)
92 {
93 std::stringstream reportNameStream;
94 for (size_t i = 0; i < length; ++i)
95 {
96 reportNameStream << "z";
97 }
98 return reportNameStream.str();
99 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200100};
101
102TEST_F(TestReportManager, minInterval)
103{
104 EXPECT_THAT(getProperty<uint64_t>("MinInterval"),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000105 Eq(ReportManager::minInterval.count()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200106}
107
108TEST_F(TestReportManager, maxReports)
109{
Wludzik, Jozef503c1582020-12-11 14:48:01 +0100110 EXPECT_THAT(getProperty<size_t>("MaxReports"),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200111 Eq(ReportManager::maxReports));
112}
113
114TEST_F(TestReportManager, addReport)
115{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000116 EXPECT_CALL(reportFactoryMock, convertMetricParams(_, _));
117 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock))
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200118 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
119
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100120 auto [ec, path] = addReport(reportParams);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200121 EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
122 EXPECT_THAT(path, Eq(reportMock.getPath()));
123}
124
Karol Niczyj32859b62021-05-19 10:20:46 +0200125TEST_F(TestReportManager, addReportWithMaxLengthName)
126{
127 std::string reportName =
128 prepareReportNameWithLength(ReportManager::maxReportNameLength);
129 reportParams.reportName(reportName);
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000130 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock));
Karol Niczyj32859b62021-05-19 10:20:46 +0200131
132 auto [ec, path] = addReport(reportParams);
133
134 EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
135 EXPECT_THAT(path, Eq("/"s + reportName));
136}
137
138TEST_F(TestReportManager, DISABLED_failToAddReportWithTooLongName)
139{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000140 reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
Karol Niczyj32859b62021-05-19 10:20:46 +0200141 .Times(0);
142
143 reportParams.reportName(
144 prepareReportNameWithLength(ReportManager::maxReportNameLength + 1));
145
146 auto [ec, path] = addReport(reportParams);
147
148 EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
149 EXPECT_THAT(path, Eq(std::string()));
150}
151
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100152TEST_F(TestReportManager, DISABLED_failToAddReportTwice)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200153{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000154 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock))
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000155 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200156
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100157 addReport(reportParams);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200158
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100159 auto [ec, path] = addReport(reportParams);
Karol Niczyj32859b62021-05-19 10:20:46 +0200160
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200161 EXPECT_THAT(ec.value(), Eq(boost::system::errc::file_exists));
162 EXPECT_THAT(path, Eq(std::string()));
163}
164
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100165TEST_F(TestReportManager, DISABLED_failToAddReportWithInvalidInterval)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200166{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000167 reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000168 .Times(0);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200169
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100170 reportParams.reportingType("Periodic");
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100171 reportParams.interval(reportParams.interval() - 1ms);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200172
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100173 auto [ec, path] = addReport(reportParams);
Karol Niczyj32859b62021-05-19 10:20:46 +0200174
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200175 EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
176 EXPECT_THAT(path, Eq(std::string()));
177}
178
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100179TEST_F(TestReportManager, DISABLED_failToAddReportWithInvalidReportingType)
180{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000181 reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100182 .Times(0);
183
184 reportParams.reportingType("Invalid");
185
186 auto [ec, path] = addReport(reportParams);
Karol Niczyj32859b62021-05-19 10:20:46 +0200187
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100188 EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
189 EXPECT_THAT(path, Eq(std::string()));
190}
191
192TEST_F(TestReportManager, DISABLED_failToAddReportWithMoreSensorsThanExpected)
193{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000194 reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100195 .Times(0);
196
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000197 auto metricParams = reportParams.metricParameters();
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100198 for (size_t i = 0; i < ReportManager::maxReadingParams + 1; i++)
199 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000200 metricParams.push_back(metricParams.front());
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100201 }
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000202 reportParams.metricParameters(std::move(metricParams));
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100203
204 auto [ec, path] = addReport(reportParams);
Karol Niczyj32859b62021-05-19 10:20:46 +0200205
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100206 EXPECT_THAT(ec.value(), Eq(boost::system::errc::argument_list_too_long));
207 EXPECT_THAT(path, Eq(std::string()));
208}
209
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100210TEST_F(TestReportManager, DISABLED_failToAddReportWhenMaxReportIsReached)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200211{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000212 reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200213 .Times(ReportManager::maxReports);
214
215 for (size_t i = 0; i < ReportManager::maxReports; i++)
216 {
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100217 reportParams.reportName(reportParams.reportName() + std::to_string(i));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200218
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100219 auto [ec, path] = addReport(reportParams);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200220 EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
221 }
222
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100223 reportParams.reportName(reportParams.reportName() +
224 std::to_string(ReportManager::maxReports));
225 auto [ec, path] = addReport(reportParams);
Karol Niczyj32859b62021-05-19 10:20:46 +0200226
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200227 EXPECT_THAT(ec.value(), Eq(boost::system::errc::too_many_files_open));
228 EXPECT_THAT(path, Eq(std::string()));
229}
230
231TEST_F(TestReportManager, removeReport)
232{
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200233 {
234 InSequence seq;
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000235 EXPECT_CALL(reportFactoryMock, convertMetricParams(_, _));
236 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock))
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200237 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
238 EXPECT_CALL(reportMock, Die());
239 EXPECT_CALL(checkPoint, Call("end"));
240 }
241
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100242 addReport(reportParams);
243 sut->removeReport(&reportMock);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200244 checkPoint.Call("end");
245}
246
247TEST_F(TestReportManager, removingReportThatIsNotInContainerHasNoEffect)
248{
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200249 {
250 InSequence seq;
251 EXPECT_CALL(checkPoint, Call("end"));
252 EXPECT_CALL(reportMock, Die());
253 }
254
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100255 sut->removeReport(&reportMock);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200256 checkPoint.Call("end");
257}
258
259TEST_F(TestReportManager, removingSameReportTwiceHasNoSideEffect)
260{
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200261 {
262 InSequence seq;
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000263 EXPECT_CALL(reportFactoryMock, convertMetricParams(_, _));
264 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock))
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200265 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
266 EXPECT_CALL(reportMock, Die());
267 EXPECT_CALL(checkPoint, Call("end"));
268 }
269
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100270 addReport(reportParams);
271 sut->removeReport(&reportMock);
272 sut->removeReport(&reportMock);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200273 checkPoint.Call("end");
274}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100275
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100276TEST_F(TestReportManager, updateReportCallsUpdateReadingsForExistReport)
277{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000278 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock))
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100279 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
280 EXPECT_CALL(reportMock, updateReadings());
281
282 addReport(reportParams);
283 sut->updateReport(reportParams.reportName());
284}
285
286TEST_F(TestReportManager, updateReportDoNothingIfReportDoesNotExist)
287{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000288 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock))
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100289 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
290 EXPECT_CALL(reportMock, updateReadings()).Times(0);
291
292 addReport(reportParams);
293 sut->updateReport("NotAReport");
294}
295
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000296class TestReportManagerWithAggregationOperationType :
297 public TestReportManager,
298 public WithParamInterface<OperationType>
299{
300 public:
301 OperationType operationType = GetParam();
302};
303
304INSTANTIATE_TEST_SUITE_P(_, TestReportManagerWithAggregationOperationType,
305 Values(OperationType::single, OperationType::max,
306 OperationType::min, OperationType::avg,
307 OperationType::sum));
308
309TEST_P(TestReportManagerWithAggregationOperationType,
310 addReportWithDifferentOperationTypes)
311{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000312 reportParams.metricParameters(
313 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
314 {LabeledSensorParameters{"Service",
315 "/xyz/openbmc_project/sensors/power/p1"}},
316 operationType,
317 "MetricId1",
318 "Metadata1",
319 CollectionTimeScope::point,
320 CollectionDuration(Milliseconds(0u))}}});
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000321
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000322 reportFactoryMock.expectMake(reportParams, Ref(*sut), Ref(storageMock))
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000323 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
324
325 auto [ec, path] = addReport(reportParams);
Karol Niczyj32859b62021-05-19 10:20:46 +0200326
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000327 EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
328 EXPECT_THAT(path, Eq("/"s + reportParams.reportName()));
329}
330
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100331class TestReportManagerStorage : public TestReportManager
332{
333 public:
334 using FilePath = interfaces::JsonStorage::FilePath;
335 using DirectoryPath = interfaces::JsonStorage::DirectoryPath;
336
337 void SetUp() override
338 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000339 EXPECT_CALL(reportFactoryMock, convertMetricParams(_, _)).Times(0);
340
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100341 ON_CALL(storageMock, list())
342 .WillByDefault(Return(std::vector<FilePath>{FilePath("report1")}));
343 ON_CALL(storageMock, load(FilePath("report1")))
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100344 .WillByDefault(InvokeWithoutArgs([this] { return data; }));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100345 }
346
347 void makeReportManager()
348 {
349 sut = std::make_unique<ReportManager>(std::move(reportFactoryMockPtr),
350 std::move(storageMockPtr),
351 DbusEnvironment::getObjServer());
352 }
353
354 nlohmann::json data = nlohmann::json{
355 {"Version", Report::reportVersion},
356 {"Name", reportParams.reportName()},
357 {"ReportingType", reportParams.reportingType()},
358 {"EmitsReadingsUpdate", reportParams.emitReadingUpdate()},
359 {"LogToMetricReportsCollection",
360 reportParams.logToMetricReportCollection()},
361 {"Interval", reportParams.interval().count()},
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000362 {"ReadingParameters", reportParams.metricParameters()}};
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100363};
364
365TEST_F(TestReportManagerStorage, reportManagerCtorAddReportFromStorage)
366{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000367 reportFactoryMock.expectMake(reportParams, _, Ref(storageMock));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100368
369 makeReportManager();
370}
371
372TEST_F(TestReportManagerStorage,
373 reportManagerCtorRemoveFileIfVersionDoesNotMatch)
374{
375 data["Version"] = Report::reportVersion - 1;
376
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100377 EXPECT_CALL(storageMock, remove(FilePath("report1")));
378
379 makeReportManager();
380}
381
382TEST_F(TestReportManagerStorage,
383 reportManagerCtorRemoveFileIfIntervalHasWrongType)
384{
385 data["Interval"] = "1000";
386
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100387 EXPECT_CALL(storageMock, remove(FilePath("report1")));
388
389 makeReportManager();
390}