blob: 9afa421f3b3bb641e4dcd53e523e8b8e3faa82d1 [file] [log] [blame]
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +02001#include "dbus_environment.hpp"
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +01002#include "fakes/clock_fake.hpp"
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +00003#include "helpers.hpp"
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01004#include "messages/collect_trigger_id.hpp"
5#include "messages/trigger_presence_changed_ind.hpp"
6#include "messages/update_report_ind.hpp"
Wludzik, Jozefe2362792020-10-27 17:23:55 +01007#include "mocks/json_storage_mock.hpp"
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +02008#include "mocks/metric_mock.hpp"
Szymon Dompkefdb06a12022-02-11 11:04:44 +01009#include "mocks/report_factory_mock.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020010#include "mocks/report_manager_mock.hpp"
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020011#include "params/report_params.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020012#include "report.hpp"
13#include "report_manager.hpp"
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +010014#include "utils/clock.hpp"
Krzysztof Grobelny51497a02021-11-09 14:56:22 +010015#include "utils/contains.hpp"
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020016#include "utils/conv_container.hpp"
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010017#include "utils/messanger.hpp"
Krzysztof Grobelny51497a02021-11-09 14:56:22 +010018#include "utils/transform.hpp"
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000019#include "utils/tstring.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020020
21#include <sdbusplus/exception.hpp>
22
23using namespace testing;
24using namespace std::literals::string_literals;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020025using namespace std::chrono_literals;
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000026namespace tstring = utils::tstring;
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020027
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010028constexpr Milliseconds systemTimestamp = 55ms;
29
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020030class TestReport : public Test
31{
32 public:
Wludzik, Jozefe2362792020-10-27 17:23:55 +010033 ReportParams defaultParams;
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020034
35 std::unique_ptr<ReportManagerMock> reportManagerMock =
Wludzik, Jozefe2362792020-10-27 17:23:55 +010036 std::make_unique<NiceMock<ReportManagerMock>>();
Szymon Dompkefdb06a12022-02-11 11:04:44 +010037 std::unique_ptr<ReportFactoryMock> reportFactoryMock =
38 std::make_unique<NiceMock<ReportFactoryMock>>();
39 NiceMock<StorageMock> storageMock;
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000040 std::vector<std::shared_ptr<MetricMock>> metricMocks;
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010041 std::unique_ptr<ClockFake> clockFakePtr = std::make_unique<ClockFake>();
42 ClockFake& clockFake = *clockFakePtr;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020043 std::unique_ptr<Report> sut;
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010044 utils::Messanger messanger;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020045
Wludzik, Jozefe2362792020-10-27 17:23:55 +010046 MockFunction<void()> checkPoint;
47
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010048 TestReport() : messanger(DbusEnvironment::getIoc())
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010049 {
50 clockFake.system.set(systemTimestamp);
51 }
52
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000053 void initMetricMocks(
54 const std::vector<LabeledMetricParameters>& metricParameters)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010055 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000056 for (auto i = metricMocks.size(); i < metricParameters.size(); ++i)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010057 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000058 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>());
59 }
60 metricMocks.resize(metricParameters.size());
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000061
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000062 std::vector<MetricValue> readings{{MetricValue{"a", "b", 17.1, 114},
63 MetricValue{"aa", "bb", 42.0, 74}}};
64 readings.resize(metricParameters.size());
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000065
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000066 for (size_t i = 0; i < metricParameters.size(); ++i)
67 {
68 ON_CALL(*metricMocks[i], getReadings())
Krzysztof Grobelny80697712021-03-04 09:49:27 +000069 .WillByDefault(Return(std::vector({readings[i]})));
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000070 ON_CALL(*metricMocks[i], dumpConfiguration())
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000071 .WillByDefault(Return(metricParameters[i]));
Wludzik, Jozefe2362792020-10-27 17:23:55 +010072 }
73 }
74
Szymon Dompkefdb06a12022-02-11 11:04:44 +010075 std::vector<std::shared_ptr<interfaces::Metric>>
76 getMetricsFromReadingParams(const ReadingParameters& params)
77 {
78 const auto metricParameters =
79 reportFactoryMock->convertMetricParams(params);
80 std::vector<std::shared_ptr<MetricMock>> metricMocks;
81
82 for (size_t i = 0; i < metricParameters.size(); ++i)
83 {
84 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>());
85 ON_CALL(*metricMocks[i], dumpConfiguration())
86 .WillByDefault(Return(metricParameters[i]));
87 }
88
89 return utils::convContainer<std::shared_ptr<interfaces::Metric>>(
90 metricMocks);
91 }
92
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020093 void SetUp() override
94 {
95 sut = makeReport(ReportParams());
96 }
97
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +010098 static interfaces::JsonStorage::FilePath to_file_path(std::string id)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010099 {
100 return interfaces::JsonStorage::FilePath(
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100101 std::to_string(std::hash<std::string>{}(id)));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100102 }
103
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200104 std::unique_ptr<Report> makeReport(const ReportParams& params)
105 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000106 initMetricMocks(params.metricParameters());
107
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200108 return std::make_unique<Report>(
109 DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100110 params.reportId(), params.reportName(), params.reportingType(),
111 params.reportActions(), params.interval(), params.appendLimit(),
112 params.reportUpdates(), *reportManagerMock, storageMock,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200113 utils::convContainer<std::shared_ptr<interfaces::Metric>>(
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200114 metricMocks),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100115 *reportFactoryMock, params.enabled(), std::move(clockFakePtr));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200116 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200117
118 template <class T>
119 static T getProperty(const std::string& path, const std::string& property)
120 {
Szymon Dompkee28aa532021-10-27 12:33:12 +0200121 return DbusEnvironment::getProperty<T>(path, Report::reportIfaceName,
122 property);
123 }
124
125 template <class T>
126 static boost::system::error_code setProperty(const std::string& path,
127 const std::string& property,
128 const T& newValue)
129 {
130 return DbusEnvironment::setProperty<T>(path, Report::reportIfaceName,
131 property, newValue);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100132 }
133
134 boost::system::error_code call(const std::string& path,
135 const std::string& interface,
136 const std::string& method)
137 {
138 std::promise<boost::system::error_code> methodPromise;
139 DbusEnvironment::getBus()->async_method_call(
140 [&methodPromise](boost::system::error_code ec) {
141 methodPromise.set_value(ec);
142 },
143 DbusEnvironment::serviceName(), path, interface, method);
144 return DbusEnvironment::waitForFuture(methodPromise.get_future());
145 }
146
147 boost::system::error_code update(const std::string& path)
148 {
149 return call(path, Report::reportIfaceName, "Update");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200150 }
151
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200152 boost::system::error_code deleteReport(const std::string& path)
153 {
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100154 return call(path, Report::deleteIfaceName, "Delete");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200155 }
156};
157
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100158TEST_F(TestReport, returnsId)
159{
160 EXPECT_THAT(sut->getId(), Eq(defaultParams.reportId()));
161}
162
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200163TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
164{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200165 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
166 Eq(defaultParams.enabled()));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200167 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100168 Eq(defaultParams.interval().count()));
169 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100170 EXPECT_THAT(
171 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
172 Eq(utils::transform(defaultParams.reportActions(), [](const auto v) {
173 return utils::enumToString(v);
174 })));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200175 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100176 Eq(utils::contains(defaultParams.reportActions(),
177 ReportAction::emitsReadingsUpdate)));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200178 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "AppendLimit"),
179 Eq(defaultParams.appendLimit()));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100180 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
181 Eq(utils::enumToString(defaultParams.reportingType())));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200182 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportUpdates"),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100183 Eq(utils::enumToString(defaultParams.reportUpdates())));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200184 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200185 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100186 Eq(utils::contains(defaultParams.reportActions(),
187 ReportAction::logToMetricReportsCollection)));
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000188 EXPECT_THAT(getProperty<ReadingParameters>(
189 sut->getPath(), "ReadingParametersFutureVersion"),
190 Eq(toReadingParameters(defaultParams.metricParameters())));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100191 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"),
192 Eq(defaultParams.reportName()));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100193 EXPECT_THAT(
194 getProperty<std::vector<std::string>>(sut->getPath(), "TriggerIds"),
195 Eq(std::vector<std::string>()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200196}
197
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200198TEST_F(TestReport, readingsAreInitialyEmpty)
199{
200 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
201 Eq(Readings{}));
202}
203
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100204TEST_F(TestReport, setReadingParametersWithNewParams)
205{
206 ReadingParameters newParams = toReadingParameters(
207 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
208 {LabeledSensorInfo{"Service",
209 "/xyz/openbmc_project/sensors/power/psu",
210 "NewMetadata123"}},
211 OperationType::avg,
212 "NewMetricId123",
213 CollectionTimeScope::startup,
214 CollectionDuration(250ms)}}});
215 auto metrics = getMetricsFromReadingParams(newParams);
216
217 EXPECT_CALL(*reportFactoryMock, updateMetrics(_, _, _))
218 .WillOnce(SetArgReferee<0>(metrics));
219 EXPECT_THAT(
220 setProperty(sut->getPath(), "ReadingParametersFutureVersion", newParams)
221 .value(),
222 Eq(boost::system::errc::success));
223 EXPECT_THAT(getProperty<ReadingParameters>(
224 sut->getPath(), "ReadingParametersFutureVersion"),
225 Eq(newParams));
226}
227
228TEST_F(TestReport, setReportingTypeWithValidNewType)
229{
230 std::string newType = "Periodic";
231 std::string currType = utils::enumToString(defaultParams.reportingType());
232
233 EXPECT_THAT(newType, Ne(currType));
234 EXPECT_THAT(setProperty(sut->getPath(), "ReportingType", newType).value(),
235 Eq(boost::system::errc::success));
236 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
237 Eq(newType));
238}
239
240TEST_F(TestReport, setReportingTypeWithInvalidType)
241{
242 std::string newType = "Periodic_ABC";
243 std::string prevType = utils::enumToString(defaultParams.reportingType());
244
245 EXPECT_THAT(setProperty(sut->getPath(), "ReportingType", newType).value(),
246 Eq(boost::system::errc::invalid_argument));
247 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
248 Eq(prevType));
249}
250
251TEST_F(TestReport, setReportActionsWithValidNewActions)
252{
253 std::vector<std::string> newActions = {"EmitsReadingsUpdate"};
254 std::vector<std::string> currActions =
255 utils::transform(defaultParams.reportActions(),
256 [](const auto v) { return utils::enumToString(v); });
257
258 EXPECT_THAT(newActions, Ne(currActions));
259 EXPECT_THAT(
260 setProperty(sut->getPath(), "ReportActions", newActions).value(),
261 Eq(boost::system::errc::success));
262 EXPECT_THAT(
263 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
264 UnorderedElementsAre("EmitsReadingsUpdate",
265 "LogToMetricReportsCollection"));
266}
267
268TEST_F(TestReport, setReportActionsWithValidUnsortedActions)
269{
270 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
271 "EmitsReadingsUpdate"};
272 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
273 "LogToMetricReportsCollection"};
274 std::vector<std::string> currActions =
275 utils::transform(defaultParams.reportActions(),
276 [](const auto v) { return utils::enumToString(v); });
277
278 EXPECT_THAT(newActions, Ne(currActions));
279 EXPECT_THAT(
280 setProperty(sut->getPath(), "ReportActions", newActions).value(),
281 Eq(boost::system::errc::success));
282 EXPECT_THAT(
283 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
284 Eq(expectedActions));
285}
286
287TEST_F(TestReport, setReportActionsWithEmptyActions)
288{
289 std::vector<std::string> newActions = {};
290 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
291 std::vector<std::string> currActions =
292 utils::transform(defaultParams.reportActions(),
293 [](const auto v) { return utils::enumToString(v); });
294
295 EXPECT_THAT(newActions, Ne(currActions));
296 EXPECT_THAT(
297 setProperty(sut->getPath(), "ReportActions", newActions).value(),
298 Eq(boost::system::errc::success));
299 EXPECT_THAT(
300 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
301 Eq(expectedActions));
302}
303
304TEST_F(TestReport, setReportActionsWithInvalidActions)
305{
306 std::vector<std::string> invalidActions = {"EmitsReadingsUpdate_1"};
307 EXPECT_THAT(
308 setProperty(sut->getPath(), "ReportActions", invalidActions).value(),
309 Eq(boost::system::errc::invalid_argument));
310 EXPECT_THAT(
311 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
312 Eq(utils::transform(defaultParams.reportActions(), [](const auto v) {
313 return utils::enumToString(v);
314 })));
315}
316
317TEST_F(TestReport, createReportWithEmptyActions)
318{
319 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
320
321 sut = makeReport(ReportParams().reportId("TestId_1").reportActions({}));
322 EXPECT_THAT(
323 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
324 Eq(expectedActions));
325}
326
327TEST_F(TestReport, createReportWithValidUnsortedActions)
328{
329 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
330 "EmitsReadingsUpdate"};
331 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
332 "LogToMetricReportsCollection"};
333
334 sut = makeReport(
335 ReportParams()
336 .reportId("TestId_1")
337 .reportActions(utils::transform(newActions, [](const auto& action) {
338 return utils::toReportAction(action);
339 })));
340 EXPECT_THAT(
341 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
342 Eq(expectedActions));
343}
344
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200345TEST_F(TestReport, setEnabledWithNewValue)
346{
347 bool newValue = !defaultParams.enabled();
348 EXPECT_THAT(setProperty(sut->getPath(), "Enabled", newValue).value(),
349 Eq(boost::system::errc::success));
350 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(newValue));
351}
352
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200353TEST_F(TestReport, setIntervalWithValidValue)
354{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100355 uint64_t newValue = defaultParams.interval().count() + 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200356 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200357 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200358 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
359 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200360}
361
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100362TEST_F(
363 TestReport,
364 settingIntervalWithInvalidValueDoesNotChangePropertyAndReturnsInvalidArgument)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200365{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100366 uint64_t newValue = defaultParams.interval().count() - 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200367 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100368 Eq(boost::system::errc::invalid_argument));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200369 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100370 Eq(defaultParams.interval().count()));
371}
372
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200373TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
374{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100375 EXPECT_THAT(
376 setProperty(sut->getPath(), "EmitsReadingsUpdate", true).value(),
377 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200378 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100379 Eq(utils::contains(defaultParams.reportActions(),
380 ReportAction::emitsReadingsUpdate)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200381}
382
383TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
384{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100385 EXPECT_THAT(
386 setProperty(sut->getPath(), "LogToMetricReportsCollection", true)
387 .value(),
388 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200389 EXPECT_THAT(
390 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100391 Eq(utils::contains(defaultParams.reportActions(),
392 ReportAction::logToMetricReportsCollection)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200393}
394
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100395TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
396{
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100397 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100398
399 bool persistency = false;
400 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
401 Eq(boost::system::errc::success));
402 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
403 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200404}
405
406TEST_F(TestReport, deleteReport)
407{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200408 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
409 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200410 EXPECT_THAT(ec, Eq(boost::system::errc::success));
411}
412
413TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
414{
415 auto ec = deleteReport(Report::reportDir + "NonExisting"s);
416 EXPECT_THAT(ec.value(), Eq(EBADR));
417}
418
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100419TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
420{
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100421 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100422 auto ec = deleteReport(sut->getPath());
423 EXPECT_THAT(ec, Eq(boost::system::errc::success));
424}
425
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100426TEST_F(TestReport, updatesTriggerIdWhenTriggerIsAdded)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100427{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100428 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100429
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100430 messanger.send(messages::TriggerPresenceChangedInd{
431 messages::Presence::Exist, "trigger1", {defaultParams.reportId()}});
432 messanger.send(messages::TriggerPresenceChangedInd{
433 messages::Presence::Exist, "trigger1", {defaultParams.reportId()}});
434 messanger.send(messages::TriggerPresenceChangedInd{
435 messages::Presence::Exist, "trigger2", {"someOtherReport"}});
436 messanger.send(messages::TriggerPresenceChangedInd{
437 messages::Presence::Exist,
438 "trigger3",
439 {"someOtherReport", defaultParams.reportId()}});
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100440
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100441 EXPECT_THAT(
442 getProperty<std::vector<std::string>>(sut->getPath(), "TriggerIds"),
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100443 UnorderedElementsAre("trigger1", "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100444}
445
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100446TEST_F(TestReport, updatesTriggerIdWhenTriggerIsRemoved)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100447{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100448 utils::Messanger messanger(DbusEnvironment::getIoc());
449
450 messanger.send(messages::TriggerPresenceChangedInd{
451 messages::Presence::Exist, "trigger1", {defaultParams.reportId()}});
452 messanger.send(messages::TriggerPresenceChangedInd{
453 messages::Presence::Exist, "trigger2", {defaultParams.reportId()}});
454 messanger.send(messages::TriggerPresenceChangedInd{
455 messages::Presence::Exist, "trigger3", {defaultParams.reportId()}});
456
457 messanger.send(messages::TriggerPresenceChangedInd{
458 messages::Presence::Removed, "trigger1", {defaultParams.reportId()}});
459 messanger.send(messages::TriggerPresenceChangedInd{
460 messages::Presence::Removed, "trigger2", {}});
461 messanger.send(messages::TriggerPresenceChangedInd{
462 messages::Presence::Removed, "trigger1", {defaultParams.reportId()}});
463
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100464 EXPECT_THAT(
465 getProperty<std::vector<std::string>>(sut->getPath(), "TriggerIds"),
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100466 UnorderedElementsAre("trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100467}
468
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100469TEST_F(TestReport, updatesTriggerIdWhenTriggerIsModified)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100470{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100471 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100472
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100473 messanger.send(messages::TriggerPresenceChangedInd{
474 messages::Presence::Exist, "trigger1", {defaultParams.reportId()}});
475 messanger.send(messages::TriggerPresenceChangedInd{
476 messages::Presence::Exist, "trigger2", {defaultParams.reportId()}});
477 messanger.send(messages::TriggerPresenceChangedInd{
478 messages::Presence::Exist, "trigger3", {defaultParams.reportId()}});
479
480 messanger.send(messages::TriggerPresenceChangedInd{
481 messages::Presence::Exist, "trigger1", {defaultParams.reportId()}});
482 messanger.send(messages::TriggerPresenceChangedInd{
483 messages::Presence::Exist, "trigger2", {}});
484 messanger.send(messages::TriggerPresenceChangedInd{
485 messages::Presence::Exist, "trigger3", {defaultParams.reportId()}});
486
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100487 EXPECT_THAT(
488 getProperty<std::vector<std::string>>(sut->getPath(), "TriggerIds"),
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100489 UnorderedElementsAre("trigger1", "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100490}
491
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100492class TestReportStore :
493 public TestReport,
494 public WithParamInterface<std::pair<std::string, nlohmann::json>>
495{
496 public:
497 void SetUp() override
498 {}
499
500 nlohmann::json storedConfiguration;
501};
502
503INSTANTIATE_TEST_SUITE_P(
504 _, TestReportStore,
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200505 Values(std::make_pair("Enabled"s, nlohmann::json(ReportParams().enabled())),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100506 std::make_pair("Version"s, nlohmann::json(6)),
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100507 std::make_pair("Id"s, nlohmann::json(ReportParams().reportId())),
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000508 std::make_pair("Name"s, nlohmann::json(ReportParams().reportName())),
509 std::make_pair("ReportingType",
510 nlohmann::json(ReportParams().reportingType())),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100511 std::make_pair("ReportActions", nlohmann::json(utils::transform(
512 ReportParams().reportActions(),
513 [](const auto v) {
514 return utils::toUnderlying(
515 v);
516 }))),
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000517 std::make_pair("Interval",
518 nlohmann::json(ReportParams().interval().count())),
Krzysztof Grobelnye6c417c2022-02-02 17:25:53 +0100519 std::make_pair("AppendLimit",
520 nlohmann::json(ReportParams().appendLimit())),
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000521 std::make_pair(
522 "ReadingParameters",
523 nlohmann::json(
524 {{{tstring::SensorPath::str(),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000525 {{{tstring::Service::str(), "Service"},
526 {tstring::Path::str(),
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100527 "/xyz/openbmc_project/sensors/power/p1"},
528 {tstring::Metadata::str(), "metadata1"}}}},
Krzysztof Grobelny60fee072022-01-13 16:25:04 +0100529 {tstring::OperationType::str(), OperationType::avg},
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000530 {tstring::Id::str(), "MetricId1"},
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000531 {tstring::CollectionTimeScope::str(),
532 CollectionTimeScope::point},
533 {tstring::CollectionDuration::str(), 0}},
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000534 {{tstring::SensorPath::str(),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000535 {{{tstring::Service::str(), "Service"},
536 {tstring::Path::str(),
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100537 "/xyz/openbmc_project/sensors/power/p2"},
538 {tstring::Metadata::str(), "metadata2"}}}},
Krzysztof Grobelny60fee072022-01-13 16:25:04 +0100539 {tstring::OperationType::str(), OperationType::avg},
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000540 {tstring::Id::str(), "MetricId2"},
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000541 {tstring::CollectionTimeScope::str(),
542 CollectionTimeScope::point},
543 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100544
545TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
546{
547 sut = makeReport(ReportParams());
548
549 {
550 InSequence seq;
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100551 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100552 EXPECT_CALL(checkPoint, Call());
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100553 EXPECT_CALL(storageMock, store(to_file_path(sut->getId()), _))
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100554 .WillOnce(SaveArg<1>(&storedConfiguration));
555 }
556
557 setProperty(sut->getPath(), "Persistency", false);
558 checkPoint.Call();
559 setProperty(sut->getPath(), "Persistency", true);
560
561 const auto& [key, value] = GetParam();
562
563 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
564}
565
566TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
567{
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100568 EXPECT_CALL(storageMock, store(to_file_path(ReportParams().reportId()), _))
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100569 .WillOnce(SaveArg<1>(&storedConfiguration));
570
571 sut = makeReport(ReportParams());
572
573 const auto& [key, value] = GetParam();
574
575 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
576}
577
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200578class TestReportValidNames :
579 public TestReport,
580 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200581{
582 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200583 void SetUp() override
584 {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200585};
586
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200587INSTANTIATE_TEST_SUITE_P(
588 ValidNames, TestReportValidNames,
589 Values(ReportParams().reportName("Valid_1"),
590 ReportParams().reportName("Valid_1/Valid_2"),
591 ReportParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200592
593TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
594{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200595 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200596}
597
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100598class TestReportInvalidIds :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200599 public TestReport,
600 public WithParamInterface<ReportParams>
601{
602 public:
603 void SetUp() override
604 {}
605};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200606
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100607INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidIds,
608 Values(ReportParams().reportId("/"),
609 ReportParams().reportId("/Invalid"),
610 ReportParams().reportId("Invalid/"),
611 ReportParams().reportId("Invalid/Invalid/"),
612 ReportParams().reportId("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200613
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100614TEST_P(TestReportInvalidIds, failsToCreateReportWithInvalidName)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100615{
616 EXPECT_CALL(storageMock, store).Times(0);
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100617
618 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100619}
620
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200621class TestReportAllReportTypes :
622 public TestReport,
623 public WithParamInterface<ReportParams>
624{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200625 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200626 void SetUp() override
627 {
628 sut = makeReport(GetParam());
629 }
630};
631
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100632INSTANTIATE_TEST_SUITE_P(
633 _, TestReportAllReportTypes,
634 Values(ReportParams().reportingType(ReportingType::onRequest),
635 ReportParams().reportingType(ReportingType::onChange),
636 ReportParams().reportingType(ReportingType::periodic)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200637
638TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
639{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100640 EXPECT_THAT(utils::toReportingType(
641 getProperty<std::string>(sut->getPath(), "ReportingType")),
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200642 Eq(GetParam().reportingType()));
643}
644
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100645TEST_P(TestReportAllReportTypes, readingsAreUpdated)
646{
647 clockFake.system.advance(10ms);
648
649 messanger.send(messages::UpdateReportInd{{sut->getId()}});
650 const auto [timestamp, readings] =
651 getProperty<Readings>(sut->getPath(), "Readings");
652
653 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
654}
655
656TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIsDisabled)
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200657{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100658 clockFake.system.advance(10ms);
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200659
660 setProperty(sut->getPath(), "Enabled", false);
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100661 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200662 const auto [timestamp, readings] =
663 getProperty<Readings>(sut->getPath(), "Readings");
664
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100665 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200666}
667
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100668TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIdDiffers)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100669{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100670 clockFake.system.advance(10ms);
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100671
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100672 messanger.send(messages::UpdateReportInd{{sut->getId() + "x"s}});
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100673 const auto [timestamp, readings] =
674 getProperty<Readings>(sut->getPath(), "Readings");
675
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100676 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100677}
678
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100679class TestReportOnRequestType : public TestReport
680{
681 void SetUp() override
682 {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100683 sut =
684 makeReport(ReportParams().reportingType(ReportingType::onRequest));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100685 }
686};
687
688TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
689{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100690 clockFake.system.advance(10ms);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100691
692 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
693
694 const auto [timestamp, readings] =
695 getProperty<Readings>(sut->getPath(), "Readings");
696
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100697 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100698}
699
700TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
701{
702 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
703
704 const auto [timestamp, readings] =
705 getProperty<Readings>(sut->getPath(), "Readings");
706
707 EXPECT_THAT(readings,
708 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000709 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100710}
711
712class TestReportNonOnRequestType :
713 public TestReport,
714 public WithParamInterface<ReportParams>
715{
716 void SetUp() override
717 {
718 sut = makeReport(GetParam());
719 }
720};
721
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100722INSTANTIATE_TEST_SUITE_P(
723 _, TestReportNonOnRequestType,
724 Values(ReportParams().reportingType(ReportingType::periodic),
725 ReportParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100726
727TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
728{
729 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
730
731 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
732 Eq(Readings{}));
733}
734
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200735class TestReportNonPeriodicReport :
736 public TestReport,
737 public WithParamInterface<ReportParams>
738{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200739 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200740 void SetUp() override
741 {
742 sut = makeReport(GetParam());
743 }
744};
745
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100746INSTANTIATE_TEST_SUITE_P(
747 _, TestReportNonPeriodicReport,
748 Values(ReportParams().reportingType(ReportingType::onRequest),
749 ReportParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200750
751TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
752{
753 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
754
755 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
756 Eq(Readings{}));
757}
758
759class TestReportPeriodicReport : public TestReport
760{
761 void SetUp() override
762 {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100763 sut = makeReport(ReportParams().reportingType(ReportingType::periodic));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200764 }
765};
766
767TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
768{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100769 clockFake.system.advance(10ms);
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200770 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
771
772 const auto [timestamp, readings] =
773 getProperty<Readings>(sut->getPath(), "Readings");
774
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100775 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200776}
777
778TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
779{
780 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
781
782 const auto [timestamp, readings] =
783 getProperty<Readings>(sut->getPath(), "Readings");
784
785 EXPECT_THAT(readings,
786 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000787 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200788}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100789
Szymon Dompke3eb56862021-09-20 15:32:04 +0200790struct ReportUpdatesReportParams
791{
792 ReportParams reportParams;
793 std::vector<ReadingData> expectedReadings;
794 bool expectedEnabled;
795};
796
797class TestReportWithReportUpdatesAndLimit :
798 public TestReport,
799 public WithParamInterface<ReportUpdatesReportParams>
800{
801 void SetUp() override
802 {
803 sut = makeReport(ReportParams(GetParam().reportParams)
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100804 .reportingType(ReportingType::periodic)
Szymon Dompke3eb56862021-09-20 15:32:04 +0200805 .interval(std::chrono::hours(1000)));
806 }
807};
808
809INSTANTIATE_TEST_SUITE_P(
810 _, TestReportWithReportUpdatesAndLimit,
811 Values(
812 ReportUpdatesReportParams{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100813 ReportParams()
814 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
815 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200816 std::vector<ReadingData>{{std::make_tuple("aa"s, "bb"s, 42.0, 74u),
817 std::make_tuple("a"s, "b"s, 17.1, 114u),
818 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
819 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
820 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
821 true},
822 ReportUpdatesReportParams{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100823 ReportParams()
824 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
825 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200826 std::vector<ReadingData>{
827 {std::make_tuple("a"s, "b"s, 17.1, 114u),
828 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
829 std::make_tuple("a"s, "b"s, 17.1, 114u),
830 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
831 true},
832 ReportUpdatesReportParams{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100833 ReportParams()
834 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
835 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200836 std::vector<ReadingData>{}, true},
837 ReportUpdatesReportParams{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100838 ReportParams()
839 .reportUpdates(ReportUpdates::appendStopsWhenFull)
840 .appendLimit(10),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200841 std::vector<ReadingData>{
842 {std::make_tuple("a"s, "b"s, 17.1, 114u),
843 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
844 std::make_tuple("a"s, "b"s, 17.1, 114u),
845 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
846 std::make_tuple("a"s, "b"s, 17.1, 114u),
847 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
848 std::make_tuple("a"s, "b"s, 17.1, 114u),
849 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
850 true},
851 ReportUpdatesReportParams{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100852 ReportParams()
853 .reportUpdates(ReportUpdates::appendStopsWhenFull)
854 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200855 std::vector<ReadingData>{{std::make_tuple("a"s, "b"s, 17.1, 114u),
856 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
857 std::make_tuple("a"s, "b"s, 17.1, 114u),
858 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
859 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
860 false},
861 ReportUpdatesReportParams{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100862 ReportParams()
863 .reportUpdates(ReportUpdates::appendStopsWhenFull)
864 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200865 std::vector<ReadingData>{
866 {std::make_tuple("a"s, "b"s, 17.1, 114u),
867 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
868 std::make_tuple("a"s, "b"s, 17.1, 114u),
869 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
870 false},
871 ReportUpdatesReportParams{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100872 ReportParams()
873 .reportUpdates(ReportUpdates::appendStopsWhenFull)
874 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200875 std::vector<ReadingData>{}, false},
876 ReportUpdatesReportParams{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100877 ReportParams()
878 .reportUpdates(ReportUpdates::overwrite)
879 .appendLimit(500),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200880 std::vector<ReadingData>{
881 {std::make_tuple("a"s, "b"s, 17.1, 114u),
882 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
883 true},
884 ReportUpdatesReportParams{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100885 ReportParams()
886 .reportUpdates(ReportUpdates::overwrite)
887 .appendLimit(1),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200888 std::vector<ReadingData>{
889 {std::make_tuple("a"s, "b"s, 17.1, 114u),
890 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
891 true},
892 ReportUpdatesReportParams{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100893 ReportParams()
894 .reportUpdates(ReportUpdates::overwrite)
895 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200896 std::vector<ReadingData>{
897 {std::make_tuple("a"s, "b"s, 17.1, 114u),
898 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
899 true}));
900
901TEST_P(TestReportWithReportUpdatesAndLimit,
902 readingsAreUpdatedAfterIntervalExpires)
903{
904 for (int i = 0; i < 4; i++)
905 {
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100906 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Szymon Dompke3eb56862021-09-20 15:32:04 +0200907 }
908
909 const auto [timestamp, readings] =
910 getProperty<Readings>(sut->getPath(), "Readings");
911 const auto enabled = getProperty<bool>(sut->getPath(), "Enabled");
912
913 EXPECT_THAT(readings, ElementsAreArray(GetParam().expectedReadings));
914 EXPECT_EQ(enabled, GetParam().expectedEnabled);
915}
916
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100917class TestReportInitialization : public TestReport
918{
919 public:
920 void SetUp() override
921 {}
922
923 void monitorProc(sdbusplus::message::message& msg)
924 {
925 std::string iface;
926 std::vector<std::pair<std::string, std::variant<Readings>>>
927 changed_properties;
928 std::vector<std::string> invalidated_properties;
929
930 msg.read(iface, changed_properties, invalidated_properties);
931
932 if (iface == Report::reportIfaceName)
933 {
934 for (const auto& [name, value] : changed_properties)
935 {
936 if (name == "Readings")
937 {
938 readingsUpdated.Call();
939 }
940 }
941 }
942 }
943
944 void makeMonitor()
945 {
Patrick Williams3a62ee12021-12-03 10:13:25 -0600946 monitor = std::make_unique<sdbusplus::bus::match_t>(
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100947 *DbusEnvironment::getBus(),
948 sdbusplus::bus::match::rules::propertiesChanged(
949 sut->getPath(), Report::reportIfaceName),
950 [this](auto& msg) { monitorProc(msg); });
951 }
952
Patrick Williams3a62ee12021-12-03 10:13:25 -0600953 std::unique_ptr<sdbusplus::bus::match_t> monitor;
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100954 MockFunction<void()> readingsUpdated;
955};
956
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200957TEST_F(TestReportInitialization,
958 metricsAreInitializedWhenEnabledReportConstructed)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100959{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200960 initMetricMocks(defaultParams.metricParameters());
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100961 for (auto& metric : metricMocks)
962 {
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200963 EXPECT_CALL(*metric, initialize()).Times(1);
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100964 }
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200965 sut = makeReport(defaultParams.enabled(true));
966}
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100967
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200968TEST_F(TestReportInitialization,
969 metricsAreNotInitializedWhenDisabledReportConstructed)
970{
971 initMetricMocks(defaultParams.metricParameters());
972 for (auto& metric : metricMocks)
973 {
974 EXPECT_CALL(*metric, initialize()).Times(0);
975 }
976 sut = makeReport(defaultParams.enabled(false));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100977}
978
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200979TEST_F(TestReportInitialization,
980 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100981{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200982 EXPECT_CALL(readingsUpdated, Call())
983 .WillOnce(
984 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
985
986 const auto elapsed = DbusEnvironment::measureTime([this] {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100987 sut =
988 makeReport(defaultParams.reportingType(ReportingType::periodic)
989 .reportActions({ReportAction::emitsReadingsUpdate}));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200990 makeMonitor();
991 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
992 });
993
994 EXPECT_THAT(elapsed, AllOf(Ge(defaultParams.interval()),
995 Lt(defaultParams.interval() * 2)));
996}
997
998TEST_F(TestReportInitialization,
999 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
1000{
1001 EXPECT_CALL(readingsUpdated, Call()).Times(0);
1002
1003 sut = makeReport(
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001004 defaultParams.reportingType(ReportingType::periodic).reportActions({}));
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001005 makeMonitor();
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001006 DbusEnvironment::sleepFor(defaultParams.interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001007}
Szymon Dompke3eb56862021-09-20 15:32:04 +02001008
1009TEST_F(TestReportInitialization, appendLimitDeducedProperly)
1010{
1011 sut = makeReport(
1012 ReportParams().appendLimit(std::numeric_limits<uint64_t>::max()));
1013 auto appendLimit = getProperty<uint64_t>(sut->getPath(), "AppendLimit");
1014 EXPECT_EQ(appendLimit, 2ull);
1015}
Krzysztof Grobelnye6c417c2022-02-02 17:25:53 +01001016
1017TEST_F(TestReportInitialization, appendLimitSetToUintMaxIsStoredCorrectly)
1018{
1019 nlohmann::json storedConfiguration;
1020
1021 EXPECT_CALL(storageMock, store(to_file_path(ReportParams().reportId()), _))
1022 .WillOnce(SaveArg<1>(&storedConfiguration));
1023
1024 sut = makeReport(
1025 ReportParams().appendLimit(std::numeric_limits<uint64_t>::max()));
1026
1027 ASSERT_THAT(storedConfiguration.at("AppendLimit"),
1028 Eq(std::numeric_limits<uint64_t>::max()));
1029}
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001030
1031TEST_F(TestReportInitialization, triggerIdsPropertyIsInitialzed)
1032{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001033 for (const auto& triggerId : {"trigger1", "trigger2"})
1034 {
1035 messanger.on_receive<messages::CollectTriggerIdReq>(
1036 [&](const auto& msg) {
1037 messanger.send(messages::CollectTriggerIdResp{triggerId});
1038 });
1039 }
1040
1041 sut = makeReport(ReportParams());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001042
1043 EXPECT_THAT(
1044 getProperty<std::vector<std::string>>(sut->getPath(), "TriggerIds"),
1045 UnorderedElementsAre("trigger1", "trigger2"));
1046}