blob: 19760fe73d1032a0dd55b31b9b3734febf9cfef2 [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,
Krzysztof Grobelny753e4b32021-02-11 12:58:58 +000059 ReportManager::reportManagerIfaceName, "AddReportFutureVersion",
Wludzik, Jozefe2362792020-10-27 17:23:55 +010060 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",
Krzysztof Grobelny753e4b32021-02-11 12:58:58 +0000272 "Metadata1",
273 utils::enumToString(CollectionTimeScope::point),
274 0u}});
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000275
276 reportFactoryMock.expectMake(_, reportParams, Ref(*sut), Ref(storageMock))
277 .WillOnce(Return(ByMove(std::move(reportMockPtr))));
278
279 auto [ec, path] = addReport(reportParams);
280 EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
281 EXPECT_THAT(path, Eq("/"s + reportParams.reportName()));
282}
283
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100284class TestReportManagerStorage : public TestReportManager
285{
286 public:
287 using FilePath = interfaces::JsonStorage::FilePath;
288 using DirectoryPath = interfaces::JsonStorage::DirectoryPath;
289
290 void SetUp() override
291 {
292 ON_CALL(storageMock, list())
293 .WillByDefault(Return(std::vector<FilePath>{FilePath("report1")}));
294 ON_CALL(storageMock, load(FilePath("report1")))
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100295 .WillByDefault(InvokeWithoutArgs([this] { return data; }));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100296 }
297
298 void makeReportManager()
299 {
300 sut = std::make_unique<ReportManager>(std::move(reportFactoryMockPtr),
301 std::move(storageMockPtr),
302 DbusEnvironment::getObjServer());
303 }
304
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000305 static std::vector<LabeledMetricParameters>
306 convertToLabeled(const ReadingParameters& params)
307 {
308 return utils::transform(params, [](const auto& item) {
309 return LabeledMetricParameters(
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000310 LabeledSensorParameters("service", std::get<0>(item)),
311 utils::stringToOperationType(std::get<1>(item)),
Krzysztof Grobelny753e4b32021-02-11 12:58:58 +0000312 std::get<2>(item), std::get<3>(item),
313 utils::stringToCollectionTimeScope(std::get<4>(item)),
314 CollectionDuration(
315 std::chrono::milliseconds(std::get<5>(item))));
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000316 });
317 }
318
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100319 nlohmann::json data = nlohmann::json{
320 {"Version", Report::reportVersion},
321 {"Name", reportParams.reportName()},
322 {"ReportingType", reportParams.reportingType()},
323 {"EmitsReadingsUpdate", reportParams.emitReadingUpdate()},
324 {"LogToMetricReportsCollection",
325 reportParams.logToMetricReportCollection()},
326 {"Interval", reportParams.interval().count()},
327 {"ReadingParameters",
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000328 convertToLabeled(reportParams.readingParameters())}};
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100329};
330
331TEST_F(TestReportManagerStorage, reportManagerCtorAddReportFromStorage)
332{
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000333 reportFactoryMock.expectMake(
334 reportParams, _, Ref(storageMock),
335 ElementsAreArray(convertToLabeled(reportParams.readingParameters())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100336
337 makeReportManager();
338}
339
340TEST_F(TestReportManagerStorage,
341 reportManagerCtorRemoveFileIfVersionDoesNotMatch)
342{
343 data["Version"] = Report::reportVersion - 1;
344
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100345 EXPECT_CALL(storageMock, remove(FilePath("report1")));
346
347 makeReportManager();
348}
349
350TEST_F(TestReportManagerStorage,
351 reportManagerCtorRemoveFileIfIntervalHasWrongType)
352{
353 data["Interval"] = "1000";
354
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100355 EXPECT_CALL(storageMock, remove(FilePath("report1")));
356
357 makeReportManager();
358}