blob: 76462301b101f99612dd01a5ec7a307bc5977470 [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
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +010030namespace
31{
32
33ReportParams defaultParams()
34{
35 return ReportParams();
36}
37
38ReportParams defaultOnChangeParams()
39{
40 return defaultParams().reportingType(ReportingType::onChange);
41}
42
43} // namespace
44
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020045class TestReport : public Test
46{
47 public:
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020048 std::unique_ptr<ReportManagerMock> reportManagerMock =
Wludzik, Jozefe2362792020-10-27 17:23:55 +010049 std::make_unique<NiceMock<ReportManagerMock>>();
Szymon Dompkefdb06a12022-02-11 11:04:44 +010050 std::unique_ptr<ReportFactoryMock> reportFactoryMock =
51 std::make_unique<NiceMock<ReportFactoryMock>>();
52 NiceMock<StorageMock> storageMock;
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000053 std::vector<std::shared_ptr<MetricMock>> metricMocks;
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010054 std::unique_ptr<ClockFake> clockFakePtr = std::make_unique<ClockFake>();
55 ClockFake& clockFake = *clockFakePtr;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020056 std::unique_ptr<Report> sut;
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010057 utils::Messanger messanger;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020058
Wludzik, Jozefe2362792020-10-27 17:23:55 +010059 MockFunction<void()> checkPoint;
60
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010061 TestReport() : messanger(DbusEnvironment::getIoc())
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010062 {
63 clockFake.system.set(systemTimestamp);
64 }
65
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000066 void initMetricMocks(
67 const std::vector<LabeledMetricParameters>& metricParameters)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010068 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000069 for (auto i = metricMocks.size(); i < metricParameters.size(); ++i)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010070 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000071 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>());
72 }
73 metricMocks.resize(metricParameters.size());
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000074
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000075 std::vector<MetricValue> readings{{MetricValue{"a", "b", 17.1, 114},
76 MetricValue{"aa", "bb", 42.0, 74}}};
77 readings.resize(metricParameters.size());
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000078
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000079 for (size_t i = 0; i < metricParameters.size(); ++i)
80 {
81 ON_CALL(*metricMocks[i], getReadings())
Krzysztof Grobelny80697712021-03-04 09:49:27 +000082 .WillByDefault(Return(std::vector({readings[i]})));
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000083 ON_CALL(*metricMocks[i], dumpConfiguration())
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000084 .WillByDefault(Return(metricParameters[i]));
Wludzik, Jozefe2362792020-10-27 17:23:55 +010085 }
86 }
87
Szymon Dompkefdb06a12022-02-11 11:04:44 +010088 std::vector<std::shared_ptr<interfaces::Metric>>
89 getMetricsFromReadingParams(const ReadingParameters& params)
90 {
91 const auto metricParameters =
92 reportFactoryMock->convertMetricParams(params);
93 std::vector<std::shared_ptr<MetricMock>> metricMocks;
94
95 for (size_t i = 0; i < metricParameters.size(); ++i)
96 {
97 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>());
98 ON_CALL(*metricMocks[i], dumpConfiguration())
99 .WillByDefault(Return(metricParameters[i]));
100 }
101
102 return utils::convContainer<std::shared_ptr<interfaces::Metric>>(
103 metricMocks);
104 }
105
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200106 void SetUp() override
107 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100108 sut = makeReport(defaultParams());
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200109 }
110
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100111 static interfaces::JsonStorage::FilePath to_file_path(std::string id)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100112 {
113 return interfaces::JsonStorage::FilePath(
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100114 std::to_string(std::hash<std::string>{}(id)));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100115 }
116
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200117 std::unique_ptr<Report> makeReport(const ReportParams& params)
118 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000119 initMetricMocks(params.metricParameters());
120
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200121 return std::make_unique<Report>(
122 DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100123 params.reportId(), params.reportName(), params.reportingType(),
124 params.reportActions(), params.interval(), params.appendLimit(),
125 params.reportUpdates(), *reportManagerMock, storageMock,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200126 utils::convContainer<std::shared_ptr<interfaces::Metric>>(
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200127 metricMocks),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100128 *reportFactoryMock, params.enabled(), std::move(clockFakePtr));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200129 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200130
131 template <class T>
132 static T getProperty(const std::string& path, const std::string& property)
133 {
Szymon Dompkee28aa532021-10-27 12:33:12 +0200134 return DbusEnvironment::getProperty<T>(path, Report::reportIfaceName,
135 property);
136 }
137
138 template <class T>
139 static boost::system::error_code setProperty(const std::string& path,
140 const std::string& property,
141 const T& newValue)
142 {
143 return DbusEnvironment::setProperty<T>(path, Report::reportIfaceName,
144 property, newValue);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100145 }
146
147 boost::system::error_code call(const std::string& path,
148 const std::string& interface,
149 const std::string& method)
150 {
151 std::promise<boost::system::error_code> methodPromise;
152 DbusEnvironment::getBus()->async_method_call(
153 [&methodPromise](boost::system::error_code ec) {
154 methodPromise.set_value(ec);
155 },
156 DbusEnvironment::serviceName(), path, interface, method);
157 return DbusEnvironment::waitForFuture(methodPromise.get_future());
158 }
159
160 boost::system::error_code update(const std::string& path)
161 {
162 return call(path, Report::reportIfaceName, "Update");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200163 }
164
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200165 boost::system::error_code deleteReport(const std::string& path)
166 {
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100167 return call(path, Report::deleteIfaceName, "Delete");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200168 }
169};
170
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100171TEST_F(TestReport, returnsId)
172{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100173 EXPECT_THAT(sut->getId(), Eq(defaultParams().reportId()));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100174}
175
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200176TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
177{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200178 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100179 Eq(defaultParams().enabled()));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200180 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100181 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100182 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100183 EXPECT_THAT(
184 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100185 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100186 return utils::enumToString(v);
187 })));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200188 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100189 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100190 ReportAction::emitsReadingsUpdate)));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200191 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "AppendLimit"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100192 Eq(defaultParams().appendLimit()));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100193 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100194 Eq(utils::enumToString(defaultParams().reportingType())));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200195 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportUpdates"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100196 Eq(utils::enumToString(defaultParams().reportUpdates())));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200197 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200198 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100199 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100200 ReportAction::logToMetricReportsCollection)));
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000201 EXPECT_THAT(getProperty<ReadingParameters>(
202 sut->getPath(), "ReadingParametersFutureVersion"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100203 Eq(toReadingParameters(defaultParams().metricParameters())));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100204 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100205 Eq(defaultParams().reportName()));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100206 EXPECT_THAT(
207 getProperty<std::vector<std::string>>(sut->getPath(), "TriggerIds"),
208 Eq(std::vector<std::string>()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200209}
210
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200211TEST_F(TestReport, readingsAreInitialyEmpty)
212{
213 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
214 Eq(Readings{}));
215}
216
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100217TEST_F(TestReport, setReadingParametersWithNewParams)
218{
219 ReadingParameters newParams = toReadingParameters(
220 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
221 {LabeledSensorInfo{"Service",
222 "/xyz/openbmc_project/sensors/power/psu",
223 "NewMetadata123"}},
224 OperationType::avg,
225 "NewMetricId123",
226 CollectionTimeScope::startup,
227 CollectionDuration(250ms)}}});
228 auto metrics = getMetricsFromReadingParams(newParams);
229
230 EXPECT_CALL(*reportFactoryMock, updateMetrics(_, _, _))
231 .WillOnce(SetArgReferee<0>(metrics));
232 EXPECT_THAT(
233 setProperty(sut->getPath(), "ReadingParametersFutureVersion", newParams)
234 .value(),
235 Eq(boost::system::errc::success));
236 EXPECT_THAT(getProperty<ReadingParameters>(
237 sut->getPath(), "ReadingParametersFutureVersion"),
238 Eq(newParams));
239}
240
241TEST_F(TestReport, setReportingTypeWithValidNewType)
242{
243 std::string newType = "Periodic";
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100244 std::string currType = utils::enumToString(defaultParams().reportingType());
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100245
246 EXPECT_THAT(newType, Ne(currType));
247 EXPECT_THAT(setProperty(sut->getPath(), "ReportingType", newType).value(),
248 Eq(boost::system::errc::success));
249 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
250 Eq(newType));
251}
252
253TEST_F(TestReport, setReportingTypeWithInvalidType)
254{
255 std::string newType = "Periodic_ABC";
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100256 std::string prevType = utils::enumToString(defaultParams().reportingType());
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100257
258 EXPECT_THAT(setProperty(sut->getPath(), "ReportingType", newType).value(),
259 Eq(boost::system::errc::invalid_argument));
260 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
261 Eq(prevType));
262}
263
264TEST_F(TestReport, setReportActionsWithValidNewActions)
265{
266 std::vector<std::string> newActions = {"EmitsReadingsUpdate"};
267 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100268 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100269 [](const auto v) { return utils::enumToString(v); });
270
271 EXPECT_THAT(newActions, Ne(currActions));
272 EXPECT_THAT(
273 setProperty(sut->getPath(), "ReportActions", newActions).value(),
274 Eq(boost::system::errc::success));
275 EXPECT_THAT(
276 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
277 UnorderedElementsAre("EmitsReadingsUpdate",
278 "LogToMetricReportsCollection"));
279}
280
281TEST_F(TestReport, setReportActionsWithValidUnsortedActions)
282{
283 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
284 "EmitsReadingsUpdate"};
285 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
286 "LogToMetricReportsCollection"};
287 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100288 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100289 [](const auto v) { return utils::enumToString(v); });
290
291 EXPECT_THAT(newActions, Ne(currActions));
292 EXPECT_THAT(
293 setProperty(sut->getPath(), "ReportActions", newActions).value(),
294 Eq(boost::system::errc::success));
295 EXPECT_THAT(
296 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
297 Eq(expectedActions));
298}
299
300TEST_F(TestReport, setReportActionsWithEmptyActions)
301{
302 std::vector<std::string> newActions = {};
303 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
304 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100305 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100306 [](const auto v) { return utils::enumToString(v); });
307
308 EXPECT_THAT(newActions, Ne(currActions));
309 EXPECT_THAT(
310 setProperty(sut->getPath(), "ReportActions", newActions).value(),
311 Eq(boost::system::errc::success));
312 EXPECT_THAT(
313 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
314 Eq(expectedActions));
315}
316
317TEST_F(TestReport, setReportActionsWithInvalidActions)
318{
319 std::vector<std::string> invalidActions = {"EmitsReadingsUpdate_1"};
320 EXPECT_THAT(
321 setProperty(sut->getPath(), "ReportActions", invalidActions).value(),
322 Eq(boost::system::errc::invalid_argument));
323 EXPECT_THAT(
324 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100325 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100326 return utils::enumToString(v);
327 })));
328}
329
330TEST_F(TestReport, createReportWithEmptyActions)
331{
332 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
333
334 sut = makeReport(ReportParams().reportId("TestId_1").reportActions({}));
335 EXPECT_THAT(
336 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
337 Eq(expectedActions));
338}
339
340TEST_F(TestReport, createReportWithValidUnsortedActions)
341{
342 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
343 "EmitsReadingsUpdate"};
344 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
345 "LogToMetricReportsCollection"};
346
347 sut = makeReport(
348 ReportParams()
349 .reportId("TestId_1")
350 .reportActions(utils::transform(newActions, [](const auto& action) {
351 return utils::toReportAction(action);
352 })));
353 EXPECT_THAT(
354 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
355 Eq(expectedActions));
356}
357
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200358TEST_F(TestReport, setEnabledWithNewValue)
359{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100360 bool newValue = !defaultParams().enabled();
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200361 EXPECT_THAT(setProperty(sut->getPath(), "Enabled", newValue).value(),
362 Eq(boost::system::errc::success));
363 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(newValue));
364}
365
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200366TEST_F(TestReport, setIntervalWithValidValue)
367{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100368 uint64_t newValue = defaultParams().interval().count() + 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200369 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200370 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200371 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
372 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200373}
374
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100375TEST_F(
376 TestReport,
377 settingIntervalWithInvalidValueDoesNotChangePropertyAndReturnsInvalidArgument)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200378{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100379 uint64_t newValue = defaultParams().interval().count() - 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200380 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100381 Eq(boost::system::errc::invalid_argument));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200382 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100383 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100384}
385
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200386TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
387{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100388 EXPECT_THAT(
389 setProperty(sut->getPath(), "EmitsReadingsUpdate", true).value(),
390 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200391 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100392 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100393 ReportAction::emitsReadingsUpdate)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200394}
395
396TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
397{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100398 EXPECT_THAT(
399 setProperty(sut->getPath(), "LogToMetricReportsCollection", true)
400 .value(),
401 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200402 EXPECT_THAT(
403 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100404 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100405 ReportAction::logToMetricReportsCollection)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200406}
407
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100408TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
409{
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100410 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100411
412 bool persistency = false;
413 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
414 Eq(boost::system::errc::success));
415 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
416 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200417}
418
419TEST_F(TestReport, deleteReport)
420{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200421 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
422 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200423 EXPECT_THAT(ec, Eq(boost::system::errc::success));
424}
425
426TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
427{
428 auto ec = deleteReport(Report::reportDir + "NonExisting"s);
429 EXPECT_THAT(ec.value(), Eq(EBADR));
430}
431
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100432TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
433{
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100434 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100435 auto ec = deleteReport(sut->getPath());
436 EXPECT_THAT(ec, Eq(boost::system::errc::success));
437}
438
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100439TEST_F(TestReport, updatesTriggerIdWhenTriggerIsAdded)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100440{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100441 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100442
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100443 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100444 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100445 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100446 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100447 messanger.send(messages::TriggerPresenceChangedInd{
448 messages::Presence::Exist, "trigger2", {"someOtherReport"}});
449 messanger.send(messages::TriggerPresenceChangedInd{
450 messages::Presence::Exist,
451 "trigger3",
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100452 {"someOtherReport", defaultParams().reportId()}});
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100453
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100454 EXPECT_THAT(
455 getProperty<std::vector<std::string>>(sut->getPath(), "TriggerIds"),
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100456 UnorderedElementsAre("trigger1", "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100457}
458
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100459TEST_F(TestReport, updatesTriggerIdWhenTriggerIsRemoved)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100460{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100461 utils::Messanger messanger(DbusEnvironment::getIoc());
462
463 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100464 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100465 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100466 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100467 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100468 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100469
470 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100471 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100472 messanger.send(messages::TriggerPresenceChangedInd{
473 messages::Presence::Removed, "trigger2", {}});
474 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100475 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100476
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100477 EXPECT_THAT(
478 getProperty<std::vector<std::string>>(sut->getPath(), "TriggerIds"),
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100479 UnorderedElementsAre("trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100480}
481
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100482TEST_F(TestReport, updatesTriggerIdWhenTriggerIsModified)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100483{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100484 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100485
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100486 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100487 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100488 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100489 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100490 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100491 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100492
493 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100494 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100495 messanger.send(messages::TriggerPresenceChangedInd{
496 messages::Presence::Exist, "trigger2", {}});
497 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100498 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100499
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100500 EXPECT_THAT(
501 getProperty<std::vector<std::string>>(sut->getPath(), "TriggerIds"),
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100502 UnorderedElementsAre("trigger1", "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100503}
504
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100505class TestReportStore :
506 public TestReport,
507 public WithParamInterface<std::pair<std::string, nlohmann::json>>
508{
509 public:
510 void SetUp() override
511 {}
512
513 nlohmann::json storedConfiguration;
514};
515
516INSTANTIATE_TEST_SUITE_P(
517 _, TestReportStore,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100518 Values(
519 std::make_pair("Enabled"s, nlohmann::json(defaultParams().enabled())),
520 std::make_pair("Version"s, nlohmann::json(6)),
521 std::make_pair("Id"s, nlohmann::json(defaultParams().reportId())),
522 std::make_pair("Name"s, nlohmann::json(defaultParams().reportName())),
523 std::make_pair("ReportingType",
524 nlohmann::json(defaultParams().reportingType())),
525 std::make_pair("ReportActions", nlohmann::json(utils::transform(
526 defaultParams().reportActions(),
527 [](const auto v) {
528 return utils::toUnderlying(v);
529 }))),
530 std::make_pair("Interval",
531 nlohmann::json(defaultParams().interval().count())),
532 std::make_pair("AppendLimit",
533 nlohmann::json(ReportParams().appendLimit())),
534 std::make_pair(
535 "ReadingParameters",
536 nlohmann::json(
537 {{{tstring::SensorPath::str(),
538 {{{tstring::Service::str(), "Service"},
539 {tstring::Path::str(),
540 "/xyz/openbmc_project/sensors/power/p1"},
541 {tstring::Metadata::str(), "metadata1"}}}},
542 {tstring::OperationType::str(), OperationType::avg},
543 {tstring::Id::str(), "MetricId1"},
544 {tstring::CollectionTimeScope::str(),
545 CollectionTimeScope::point},
546 {tstring::CollectionDuration::str(), 0}},
547 {{tstring::SensorPath::str(),
548 {{{tstring::Service::str(), "Service"},
549 {tstring::Path::str(),
550 "/xyz/openbmc_project/sensors/power/p2"},
551 {tstring::Metadata::str(), "metadata2"}}}},
552 {tstring::OperationType::str(), OperationType::avg},
553 {tstring::Id::str(), "MetricId2"},
554 {tstring::CollectionTimeScope::str(),
555 CollectionTimeScope::point},
556 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100557
558TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
559{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100560 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100561
562 {
563 InSequence seq;
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100564 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100565 EXPECT_CALL(checkPoint, Call());
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100566 EXPECT_CALL(storageMock, store(to_file_path(sut->getId()), _))
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100567 .WillOnce(SaveArg<1>(&storedConfiguration));
568 }
569
570 setProperty(sut->getPath(), "Persistency", false);
571 checkPoint.Call();
572 setProperty(sut->getPath(), "Persistency", true);
573
574 const auto& [key, value] = GetParam();
575
576 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
577}
578
579TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
580{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100581 EXPECT_CALL(storageMock, store(to_file_path(defaultParams().reportId()), _))
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100582 .WillOnce(SaveArg<1>(&storedConfiguration));
583
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100584 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100585
586 const auto& [key, value] = GetParam();
587
588 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
589}
590
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200591class TestReportValidNames :
592 public TestReport,
593 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200594{
595 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200596 void SetUp() override
597 {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200598};
599
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200600INSTANTIATE_TEST_SUITE_P(
601 ValidNames, TestReportValidNames,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100602 Values(defaultParams().reportName("Valid_1"),
603 defaultParams().reportName("Valid_1/Valid_2"),
604 defaultParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200605
606TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
607{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200608 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200609}
610
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100611class TestReportInvalidIds :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200612 public TestReport,
613 public WithParamInterface<ReportParams>
614{
615 public:
616 void SetUp() override
617 {}
618};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200619
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100620INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidIds,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100621 Values(defaultParams().reportId("/"),
622 defaultParams().reportId("/Invalid"),
623 defaultParams().reportId("Invalid/"),
624 defaultParams().reportId("Invalid/Invalid/"),
625 defaultParams().reportId("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200626
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100627TEST_P(TestReportInvalidIds, failsToCreateReportWithInvalidName)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100628{
629 EXPECT_CALL(storageMock, store).Times(0);
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100630
631 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100632}
633
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200634class TestReportAllReportTypes :
635 public TestReport,
636 public WithParamInterface<ReportParams>
637{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200638 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200639 void SetUp() override
640 {
641 sut = makeReport(GetParam());
642 }
643};
644
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100645INSTANTIATE_TEST_SUITE_P(
646 _, TestReportAllReportTypes,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100647 Values(defaultParams().reportingType(ReportingType::onRequest),
648 defaultParams().reportingType(ReportingType::onChange),
649 defaultParams().reportingType(ReportingType::periodic)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200650
651TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
652{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100653 EXPECT_THAT(utils::toReportingType(
654 getProperty<std::string>(sut->getPath(), "ReportingType")),
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200655 Eq(GetParam().reportingType()));
656}
657
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100658TEST_P(TestReportAllReportTypes, readingsAreUpdated)
659{
660 clockFake.system.advance(10ms);
661
662 messanger.send(messages::UpdateReportInd{{sut->getId()}});
663 const auto [timestamp, readings] =
664 getProperty<Readings>(sut->getPath(), "Readings");
665
666 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
667}
668
669TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIsDisabled)
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200670{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100671 clockFake.system.advance(10ms);
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200672
673 setProperty(sut->getPath(), "Enabled", false);
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100674 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200675 const auto [timestamp, readings] =
676 getProperty<Readings>(sut->getPath(), "Readings");
677
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100678 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200679}
680
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100681TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIdDiffers)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100682{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100683 clockFake.system.advance(10ms);
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100684
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100685 messanger.send(messages::UpdateReportInd{{sut->getId() + "x"s}});
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100686 const auto [timestamp, readings] =
687 getProperty<Readings>(sut->getPath(), "Readings");
688
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100689 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100690}
691
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100692class TestReportOnRequestType : public TestReport
693{
694 void SetUp() override
695 {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100696 sut =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100697 makeReport(defaultParams().reportingType(ReportingType::onRequest));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100698 }
699};
700
701TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
702{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100703 clockFake.system.advance(10ms);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100704
705 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
706
707 const auto [timestamp, readings] =
708 getProperty<Readings>(sut->getPath(), "Readings");
709
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100710 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100711}
712
713TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
714{
715 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
716
717 const auto [timestamp, readings] =
718 getProperty<Readings>(sut->getPath(), "Readings");
719
720 EXPECT_THAT(readings,
721 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000722 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100723}
724
725class TestReportNonOnRequestType :
726 public TestReport,
727 public WithParamInterface<ReportParams>
728{
729 void SetUp() override
730 {
731 sut = makeReport(GetParam());
732 }
733};
734
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100735INSTANTIATE_TEST_SUITE_P(
736 _, TestReportNonOnRequestType,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100737 Values(defaultParams().reportingType(ReportingType::periodic),
738 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100739
740TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
741{
742 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
743
744 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
745 Eq(Readings{}));
746}
747
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200748class TestReportNonPeriodicReport :
749 public TestReport,
750 public WithParamInterface<ReportParams>
751{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200752 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200753 void SetUp() override
754 {
755 sut = makeReport(GetParam());
756 }
757};
758
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100759INSTANTIATE_TEST_SUITE_P(
760 _, TestReportNonPeriodicReport,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100761 Values(defaultParams().reportingType(ReportingType::onRequest),
762 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200763
764TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
765{
766 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
767
768 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
769 Eq(Readings{}));
770}
771
772class TestReportPeriodicReport : public TestReport
773{
774 void SetUp() override
775 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100776 sut =
777 makeReport(defaultParams().reportingType(ReportingType::periodic));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200778 }
779};
780
781TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
782{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100783 clockFake.system.advance(10ms);
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200784 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
785
786 const auto [timestamp, readings] =
787 getProperty<Readings>(sut->getPath(), "Readings");
788
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100789 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200790}
791
792TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
793{
794 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
795
796 const auto [timestamp, readings] =
797 getProperty<Readings>(sut->getPath(), "Readings");
798
799 EXPECT_THAT(readings,
800 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000801 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200802}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100803
Szymon Dompke3eb56862021-09-20 15:32:04 +0200804struct ReportUpdatesReportParams
805{
806 ReportParams reportParams;
807 std::vector<ReadingData> expectedReadings;
808 bool expectedEnabled;
809};
810
811class TestReportWithReportUpdatesAndLimit :
812 public TestReport,
813 public WithParamInterface<ReportUpdatesReportParams>
814{
815 void SetUp() override
816 {
817 sut = makeReport(ReportParams(GetParam().reportParams)
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100818 .reportingType(ReportingType::periodic)
Szymon Dompke3eb56862021-09-20 15:32:04 +0200819 .interval(std::chrono::hours(1000)));
820 }
821};
822
823INSTANTIATE_TEST_SUITE_P(
824 _, TestReportWithReportUpdatesAndLimit,
825 Values(
826 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100827 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100828 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
829 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200830 std::vector<ReadingData>{{std::make_tuple("aa"s, "bb"s, 42.0, 74u),
831 std::make_tuple("a"s, "b"s, 17.1, 114u),
832 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
833 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
834 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
835 true},
836 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100837 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100838 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
839 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200840 std::vector<ReadingData>{
841 {std::make_tuple("a"s, "b"s, 17.1, 114u),
842 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
843 std::make_tuple("a"s, "b"s, 17.1, 114u),
844 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
845 true},
846 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100847 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100848 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
849 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200850 std::vector<ReadingData>{}, true},
851 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100852 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100853 .reportUpdates(ReportUpdates::appendStopsWhenFull)
854 .appendLimit(10),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200855 std::vector<ReadingData>{
856 {std::make_tuple("a"s, "b"s, 17.1, 114u),
857 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
858 std::make_tuple("a"s, "b"s, 17.1, 114u),
859 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
860 std::make_tuple("a"s, "b"s, 17.1, 114u),
861 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
862 std::make_tuple("a"s, "b"s, 17.1, 114u),
863 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
864 true},
865 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100866 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100867 .reportUpdates(ReportUpdates::appendStopsWhenFull)
868 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200869 std::vector<ReadingData>{{std::make_tuple("a"s, "b"s, 17.1, 114u),
870 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
871 std::make_tuple("a"s, "b"s, 17.1, 114u),
872 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
873 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
874 false},
875 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100876 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100877 .reportUpdates(ReportUpdates::appendStopsWhenFull)
878 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200879 std::vector<ReadingData>{
880 {std::make_tuple("a"s, "b"s, 17.1, 114u),
881 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
882 std::make_tuple("a"s, "b"s, 17.1, 114u),
883 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
884 false},
885 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100886 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100887 .reportUpdates(ReportUpdates::appendStopsWhenFull)
888 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200889 std::vector<ReadingData>{}, false},
890 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100891 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100892 .reportUpdates(ReportUpdates::overwrite)
893 .appendLimit(500),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200894 std::vector<ReadingData>{
895 {std::make_tuple("a"s, "b"s, 17.1, 114u),
896 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
897 true},
898 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100899 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100900 .reportUpdates(ReportUpdates::overwrite)
901 .appendLimit(1),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200902 std::vector<ReadingData>{
903 {std::make_tuple("a"s, "b"s, 17.1, 114u),
904 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
905 true},
906 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100907 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100908 .reportUpdates(ReportUpdates::overwrite)
909 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200910 std::vector<ReadingData>{
911 {std::make_tuple("a"s, "b"s, 17.1, 114u),
912 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
913 true}));
914
915TEST_P(TestReportWithReportUpdatesAndLimit,
916 readingsAreUpdatedAfterIntervalExpires)
917{
918 for (int i = 0; i < 4; i++)
919 {
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100920 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Szymon Dompke3eb56862021-09-20 15:32:04 +0200921 }
922
923 const auto [timestamp, readings] =
924 getProperty<Readings>(sut->getPath(), "Readings");
925 const auto enabled = getProperty<bool>(sut->getPath(), "Enabled");
926
927 EXPECT_THAT(readings, ElementsAreArray(GetParam().expectedReadings));
928 EXPECT_EQ(enabled, GetParam().expectedEnabled);
929}
930
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100931class TestReportInitialization : public TestReport
932{
933 public:
934 void SetUp() override
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100935 {
936 initMetricMocks(defaultParams().metricParameters());
937 }
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100938
939 void monitorProc(sdbusplus::message::message& msg)
940 {
941 std::string iface;
942 std::vector<std::pair<std::string, std::variant<Readings>>>
943 changed_properties;
944 std::vector<std::string> invalidated_properties;
945
946 msg.read(iface, changed_properties, invalidated_properties);
947
948 if (iface == Report::reportIfaceName)
949 {
950 for (const auto& [name, value] : changed_properties)
951 {
952 if (name == "Readings")
953 {
954 readingsUpdated.Call();
955 }
956 }
957 }
958 }
959
960 void makeMonitor()
961 {
Patrick Williams3a62ee12021-12-03 10:13:25 -0600962 monitor = std::make_unique<sdbusplus::bus::match_t>(
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100963 *DbusEnvironment::getBus(),
964 sdbusplus::bus::match::rules::propertiesChanged(
965 sut->getPath(), Report::reportIfaceName),
966 [this](auto& msg) { monitorProc(msg); });
967 }
968
Patrick Williams3a62ee12021-12-03 10:13:25 -0600969 std::unique_ptr<sdbusplus::bus::match_t> monitor;
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100970 MockFunction<void()> readingsUpdated;
971};
972
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200973TEST_F(TestReportInitialization,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100974 registersForMetricUpdatesWhenOnChangeReportCreated)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100975{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100976 std::vector<const interfaces::MetricListener*> args;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100977 for (auto& metric : metricMocks)
978 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100979 EXPECT_CALL(*metric, registerForUpdates(_))
980 .WillOnce(Invoke([&args](const interfaces::MetricListener& report) {
981 args.emplace_back(&report);
982 }));
983 ;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100984 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100985
986 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
987
988 EXPECT_THAT(args, SizeIs(metricMocks.size()));
989 for (const auto* reportPtr : args)
990 {
991 EXPECT_THAT(reportPtr, Eq(sut.get()));
992 }
993}
994
995TEST_F(TestReportInitialization,
996 deregistersForMetricUpdatesWhenOnChangeReportDestroyed)
997{
998 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
999
1000 for (auto& metric : metricMocks)
1001 {
1002 EXPECT_CALL(*metric,
1003 unregisterFromUpdates(Ref(
1004 static_cast<interfaces::MetricListener&>(*sut.get()))));
1005 }
1006
1007 sut = nullptr;
1008}
1009
1010TEST_F(TestReportInitialization,
1011 metricsAreInitializedWhenEnabledReportConstructed)
1012{
1013 for (auto& metric : metricMocks)
1014 {
1015 EXPECT_CALL(*metric, initialize());
1016 }
1017 sut = makeReport(defaultParams().enabled(true));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001018}
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001019
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001020TEST_F(TestReportInitialization,
1021 metricsAreNotInitializedWhenDisabledReportConstructed)
1022{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001023 for (auto& metric : metricMocks)
1024 {
1025 EXPECT_CALL(*metric, initialize()).Times(0);
1026 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001027 sut = makeReport(defaultParams().enabled(false));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001028}
1029
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001030TEST_F(TestReportInitialization,
1031 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001032{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001033 EXPECT_CALL(readingsUpdated, Call())
1034 .WillOnce(
1035 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
1036
1037 const auto elapsed = DbusEnvironment::measureTime([this] {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001038 sut =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001039 makeReport(defaultParams()
1040 .reportingType(ReportingType::periodic)
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001041 .reportActions({ReportAction::emitsReadingsUpdate}));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001042 makeMonitor();
1043 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
1044 });
1045
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001046 EXPECT_THAT(elapsed, AllOf(Ge(defaultParams().interval()),
1047 Lt(defaultParams().interval() * 2)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001048}
1049
1050TEST_F(TestReportInitialization,
1051 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
1052{
1053 EXPECT_CALL(readingsUpdated, Call()).Times(0);
1054
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001055 sut = makeReport(defaultParams()
1056 .reportingType(ReportingType::periodic)
1057 .reportActions({}));
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001058 makeMonitor();
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001059 DbusEnvironment::sleepFor(defaultParams().interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001060}
Szymon Dompke3eb56862021-09-20 15:32:04 +02001061
1062TEST_F(TestReportInitialization, appendLimitDeducedProperly)
1063{
1064 sut = makeReport(
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001065 defaultParams().appendLimit(std::numeric_limits<uint64_t>::max()));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001066 auto appendLimit = getProperty<uint64_t>(sut->getPath(), "AppendLimit");
1067 EXPECT_EQ(appendLimit, 2ull);
1068}
Krzysztof Grobelnye6c417c2022-02-02 17:25:53 +01001069
1070TEST_F(TestReportInitialization, appendLimitSetToUintMaxIsStoredCorrectly)
1071{
1072 nlohmann::json storedConfiguration;
1073
1074 EXPECT_CALL(storageMock, store(to_file_path(ReportParams().reportId()), _))
1075 .WillOnce(SaveArg<1>(&storedConfiguration));
1076
1077 sut = makeReport(
1078 ReportParams().appendLimit(std::numeric_limits<uint64_t>::max()));
1079
1080 ASSERT_THAT(storedConfiguration.at("AppendLimit"),
1081 Eq(std::numeric_limits<uint64_t>::max()));
1082}
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001083
1084TEST_F(TestReportInitialization, triggerIdsPropertyIsInitialzed)
1085{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001086 for (const auto& triggerId : {"trigger1", "trigger2"})
1087 {
1088 messanger.on_receive<messages::CollectTriggerIdReq>(
1089 [&](const auto& msg) {
1090 messanger.send(messages::CollectTriggerIdResp{triggerId});
1091 });
1092 }
1093
1094 sut = makeReport(ReportParams());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001095
1096 EXPECT_THAT(
1097 getProperty<std::vector<std::string>>(sut->getPath(), "TriggerIds"),
1098 UnorderedElementsAre("trigger1", "trigger2"));
1099}
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001100
1101class TestReportInitializationOnChangeReport : public TestReportInitialization
1102{
1103 public:
1104 void SetUp() override
1105 {
1106 initMetricMocks(params.metricParameters());
1107 }
1108
1109 ReportParams params = defaultOnChangeParams();
1110};
1111
1112TEST_F(TestReportInitializationOnChangeReport,
1113 doesntUpdateReadingsWhenNotRequired)
1114{
1115 EXPECT_CALL(*metricMocks[0], updateReadings(_)).Times(0);
1116
1117 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(false));
1118
1119 sut = makeReport(params);
1120
1121 DbusEnvironment::sleepFor(500ms);
1122}
1123
1124TEST_F(TestReportInitializationOnChangeReport, updatesReadingsWhenRequired)
1125{
1126 EXPECT_CALL(*metricMocks[0], updateReadings(_))
1127 .WillOnce(Return())
1128 .WillOnce(
1129 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")))
1130 .WillRepeatedly(Return());
1131
1132 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(true));
1133
1134 sut = makeReport(params);
1135
1136 DbusEnvironment::waitForFuture("readingsUpdated");
1137}