blob: 65e48f41ce838a500542d03b343ccf3e299a8c10 [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 {
38 sut = std::make_unique<ReportManager>(std::move(reportFactoryMockPtr),
39 std::move(storageMockPtr),
40 DbusEnvironment::getObjServer());
41 }
42
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020043 void TearDown() override
44 {
45 DbusEnvironment::synchronizeIoc();
46 }
47
48 std::pair<boost::system::error_code, std::string>
Wludzik, Jozefe2362792020-10-27 17:23:55 +010049 addReport(const ReportParams& params)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020050 {
51 std::promise<std::pair<boost::system::error_code, std::string>>
52 addReportPromise;
53 DbusEnvironment::getBus()->async_method_call(
54 [&addReportPromise](boost::system::error_code ec,
55 const std::string& path) {
56 addReportPromise.set_value({ec, path});
57 },
58 DbusEnvironment::serviceName(), ReportManager::reportManagerPath,
Wludzik, Jozefe2362792020-10-27 17:23:55 +010059 ReportManager::reportManagerIfaceName, "AddReport",
60 params.reportName(), params.reportingType(),
61 params.emitReadingUpdate(), params.logToMetricReportCollection(),
62 static_cast<uint64_t>(params.interval().count()),
63 params.readingParameters());
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +010064 return DbusEnvironment::waitForFuture(addReportPromise.get_future());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020065 }
66
67 template <class T>
68 static T getProperty(std::string property)
69 {
70 std::promise<T> propertyPromise;
71 sdbusplus::asio::getProperty<T>(
72 *DbusEnvironment::getBus(), DbusEnvironment::serviceName(),
73 ReportManager::reportManagerPath,
74 ReportManager::reportManagerIfaceName, property,
75 [&propertyPromise](boost::system::error_code ec) {
76 EXPECT_THAT(static_cast<bool>(ec), ::testing::Eq(false));
77 propertyPromise.set_value(T{});
78 },
79 [&propertyPromise](T t) { propertyPromise.set_value(t); });
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +010080 return DbusEnvironment::waitForFuture(propertyPromise.get_future());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020081 }
82};
83
84TEST_F(TestReportManager, minInterval)
85{
86 EXPECT_THAT(getProperty<uint64_t>("MinInterval"),
87 Eq(static_cast<uint64_t>(ReportManager::minInterval.count())));
88}
89
90TEST_F(TestReportManager, maxReports)
91{
Wludzik, Jozef503c1582020-12-11 14:48:01 +010092 EXPECT_THAT(getProperty<size_t>("MaxReports"),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020093 Eq(ReportManager::maxReports));
94}
95
96TEST_F(TestReportManager, addReport)
97{
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000098 reportFactoryMock.expectMake(_, reportParams, Ref(*sut), Ref(storageMock))
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020099 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
100
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100101 auto [ec, path] = addReport(reportParams);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200102 EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
103 EXPECT_THAT(path, Eq(reportMock.getPath()));
104}
105
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100106TEST_F(TestReportManager, DISABLED_failToAddReportTwice)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200107{
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000108 reportFactoryMock.expectMake(_, reportParams, Ref(*sut), Ref(storageMock))
109 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200110
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100111 addReport(reportParams);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200112
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100113 auto [ec, path] = addReport(reportParams);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200114 EXPECT_THAT(ec.value(), Eq(boost::system::errc::file_exists));
115 EXPECT_THAT(path, Eq(std::string()));
116}
117
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100118TEST_F(TestReportManager, DISABLED_failToAddReportWithInvalidInterval)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200119{
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000120 reportFactoryMock.expectMake(_, std::nullopt, Ref(*sut), Ref(storageMock))
121 .Times(0);
122 reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock), _)
123 .Times(0);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200124
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100125 reportParams.reportingType("Periodic");
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100126 reportParams.interval(reportParams.interval() - 1ms);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200127
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100128 auto [ec, path] = addReport(reportParams);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200129 EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
130 EXPECT_THAT(path, Eq(std::string()));
131}
132
Wludzik, Jozefbc766b42020-12-08 16:06:22 +0100133TEST_F(TestReportManager, DISABLED_failToAddReportWithInvalidReportingType)
134{
135 reportFactoryMock.expectMake(_, std::nullopt, Ref(*sut), Ref(storageMock))
136 .Times(0);
137 reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock), _)
138 .Times(0);
139
140 reportParams.reportingType("Invalid");
141
142 auto [ec, path] = addReport(reportParams);
143 EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
144 EXPECT_THAT(path, Eq(std::string()));
145}
146
147TEST_F(TestReportManager, DISABLED_failToAddReportWithMoreSensorsThanExpected)
148{
149 reportFactoryMock.expectMake(_, std::nullopt, Ref(*sut), Ref(storageMock))
150 .Times(0);
151 reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock), _)
152 .Times(0);
153
154 auto readingParams = reportParams.readingParameters();
155 for (size_t i = 0; i < ReportManager::maxReadingParams + 1; i++)
156 {
157 readingParams.push_back(readingParams.front());
158 }
159 reportParams.readingParameters(std::move(readingParams));
160
161 auto [ec, path] = addReport(reportParams);
162 EXPECT_THAT(ec.value(), Eq(boost::system::errc::argument_list_too_long));
163 EXPECT_THAT(path, Eq(std::string()));
164}
165
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100166TEST_F(TestReportManager, DISABLED_failToAddReportWhenMaxReportIsReached)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200167{
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000168 reportFactoryMock.expectMake(_, std::nullopt, Ref(*sut), Ref(storageMock))
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200169 .Times(ReportManager::maxReports);
170
171 for (size_t i = 0; i < ReportManager::maxReports; i++)
172 {
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100173 reportParams.reportName(reportParams.reportName() + std::to_string(i));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200174
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100175 auto [ec, path] = addReport(reportParams);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200176 EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
177 }
178
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100179 reportParams.reportName(reportParams.reportName() +
180 std::to_string(ReportManager::maxReports));
181 auto [ec, path] = addReport(reportParams);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200182 EXPECT_THAT(ec.value(), Eq(boost::system::errc::too_many_files_open));
183 EXPECT_THAT(path, Eq(std::string()));
184}
185
186TEST_F(TestReportManager, removeReport)
187{
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200188 {
189 InSequence seq;
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000190 reportFactoryMock
191 .expectMake(_, reportParams, Ref(*sut), Ref(storageMock))
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200192 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
193 EXPECT_CALL(reportMock, Die());
194 EXPECT_CALL(checkPoint, Call("end"));
195 }
196
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100197 addReport(reportParams);
198 sut->removeReport(&reportMock);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200199 checkPoint.Call("end");
200}
201
202TEST_F(TestReportManager, removingReportThatIsNotInContainerHasNoEffect)
203{
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200204 {
205 InSequence seq;
206 EXPECT_CALL(checkPoint, Call("end"));
207 EXPECT_CALL(reportMock, Die());
208 }
209
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100210 sut->removeReport(&reportMock);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200211 checkPoint.Call("end");
212}
213
214TEST_F(TestReportManager, removingSameReportTwiceHasNoSideEffect)
215{
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200216 {
217 InSequence seq;
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000218 reportFactoryMock
219 .expectMake(_, reportParams, Ref(*sut), Ref(storageMock))
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200220 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
221 EXPECT_CALL(reportMock, Die());
222 EXPECT_CALL(checkPoint, Call("end"));
223 }
224
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100225 addReport(reportParams);
226 sut->removeReport(&reportMock);
227 sut->removeReport(&reportMock);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200228 checkPoint.Call("end");
229}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100230
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100231TEST_F(TestReportManager, updateReportCallsUpdateReadingsForExistReport)
232{
233 reportFactoryMock.expectMake(_, reportParams, Ref(*sut), Ref(storageMock))
234 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
235 EXPECT_CALL(reportMock, updateReadings());
236
237 addReport(reportParams);
238 sut->updateReport(reportParams.reportName());
239}
240
241TEST_F(TestReportManager, updateReportDoNothingIfReportDoesNotExist)
242{
243 reportFactoryMock.expectMake(_, reportParams, Ref(*sut), Ref(storageMock))
244 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
245 EXPECT_CALL(reportMock, updateReadings()).Times(0);
246
247 addReport(reportParams);
248 sut->updateReport("NotAReport");
249}
250
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000251class TestReportManagerWithAggregationOperationType :
252 public TestReportManager,
253 public WithParamInterface<OperationType>
254{
255 public:
256 OperationType operationType = GetParam();
257};
258
259INSTANTIATE_TEST_SUITE_P(_, TestReportManagerWithAggregationOperationType,
260 Values(OperationType::single, OperationType::max,
261 OperationType::min, OperationType::avg,
262 OperationType::sum));
263
264TEST_P(TestReportManagerWithAggregationOperationType,
265 addReportWithDifferentOperationTypes)
266{
267 reportParams.readingParameters(
268 {{{sdbusplus::message::object_path(
269 "/xyz/openbmc_project/sensors/power/p1")},
270 utils::enumToString(operationType),
271 "MetricId1",
272 "Metadata1"}});
273
274 reportFactoryMock.expectMake(_, reportParams, Ref(*sut), Ref(storageMock))
275 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
276
277 auto [ec, path] = addReport(reportParams);
278 EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
279 EXPECT_THAT(path, Eq("/"s + reportParams.reportName()));
280}
281
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100282class TestReportManagerStorage : public TestReportManager
283{
284 public:
285 using FilePath = interfaces::JsonStorage::FilePath;
286 using DirectoryPath = interfaces::JsonStorage::DirectoryPath;
287
288 void SetUp() override
289 {
290 ON_CALL(storageMock, list())
291 .WillByDefault(Return(std::vector<FilePath>{FilePath("report1")}));
292 ON_CALL(storageMock, load(FilePath("report1")))
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100293 .WillByDefault(InvokeWithoutArgs([this] { return data; }));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100294 }
295
296 void makeReportManager()
297 {
298 sut = std::make_unique<ReportManager>(std::move(reportFactoryMockPtr),
299 std::move(storageMockPtr),
300 DbusEnvironment::getObjServer());
301 }
302
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000303 static std::vector<LabeledMetricParameters>
304 convertToLabeled(const ReadingParameters& params)
305 {
306 return utils::transform(params, [](const auto& item) {
307 return LabeledMetricParameters(
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000308 LabeledSensorParameters("service", std::get<0>(item)),
309 utils::stringToOperationType(std::get<1>(item)),
310 std::get<2>(item), std::get<3>(item));
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000311 });
312 }
313
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100314 nlohmann::json data = nlohmann::json{
315 {"Version", Report::reportVersion},
316 {"Name", reportParams.reportName()},
317 {"ReportingType", reportParams.reportingType()},
318 {"EmitsReadingsUpdate", reportParams.emitReadingUpdate()},
319 {"LogToMetricReportsCollection",
320 reportParams.logToMetricReportCollection()},
321 {"Interval", reportParams.interval().count()},
322 {"ReadingParameters",
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000323 convertToLabeled(reportParams.readingParameters())}};
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100324};
325
326TEST_F(TestReportManagerStorage, reportManagerCtorAddReportFromStorage)
327{
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000328 reportFactoryMock.expectMake(
329 reportParams, _, Ref(storageMock),
330 ElementsAreArray(convertToLabeled(reportParams.readingParameters())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100331
332 makeReportManager();
333}
334
335TEST_F(TestReportManagerStorage,
336 reportManagerCtorRemoveFileIfVersionDoesNotMatch)
337{
338 data["Version"] = Report::reportVersion - 1;
339
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100340 EXPECT_CALL(storageMock, remove(FilePath("report1")));
341
342 makeReportManager();
343}
344
345TEST_F(TestReportManagerStorage,
346 reportManagerCtorRemoveFileIfIntervalHasWrongType)
347{
348 data["Interval"] = "1000";
349
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100350 EXPECT_CALL(storageMock, remove(FilePath("report1")));
351
352 makeReportManager();
353}