blob: d05620be7f12ee5d4a25c9355a916c85c9745dcb [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"
Szymon Dompke1cdd7e42022-06-08 14:43:13 +020017#include "utils/dbus_path_utils.hpp"
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010018#include "utils/messanger.hpp"
Szymon Dompke32305f12022-07-05 15:37:21 +020019#include "utils/string_utils.hpp"
Krzysztof Grobelny51497a02021-11-09 14:56:22 +010020#include "utils/transform.hpp"
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000021#include "utils/tstring.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020022
23#include <sdbusplus/exception.hpp>
24
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +020025#include <ranges>
26
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020027using namespace testing;
28using namespace std::literals::string_literals;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020029using namespace std::chrono_literals;
Szymon Dompke1cdd7e42022-06-08 14:43:13 +020030using sdbusplus::message::object_path;
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000031namespace tstring = utils::tstring;
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020032
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +020033using ErrorMessageDbusType = std::tuple<std::string, std::string>;
34using ErrorMessagesDbusType = std::vector<ErrorMessageDbusType>;
35
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010036constexpr Milliseconds systemTimestamp = 55ms;
37
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +010038namespace
39{
40
41ReportParams defaultParams()
42{
43 return ReportParams();
44}
45
46ReportParams defaultOnChangeParams()
47{
48 return defaultParams().reportingType(ReportingType::onChange);
49}
50
51} // namespace
52
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020053class TestReport : public Test
54{
55 public:
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020056 std::unique_ptr<ReportManagerMock> reportManagerMock =
Wludzik, Jozefe2362792020-10-27 17:23:55 +010057 std::make_unique<NiceMock<ReportManagerMock>>();
Szymon Dompkefdb06a12022-02-11 11:04:44 +010058 std::unique_ptr<ReportFactoryMock> reportFactoryMock =
59 std::make_unique<NiceMock<ReportFactoryMock>>();
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +010060 nlohmann::json storedConfiguration;
Szymon Dompkefdb06a12022-02-11 11:04:44 +010061 NiceMock<StorageMock> storageMock;
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000062 std::vector<std::shared_ptr<MetricMock>> metricMocks;
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010063 std::unique_ptr<ClockFake> clockFakePtr = std::make_unique<ClockFake>();
64 ClockFake& clockFake = *clockFakePtr;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020065 std::unique_ptr<Report> sut;
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010066 utils::Messanger messanger;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020067
Wludzik, Jozefe2362792020-10-27 17:23:55 +010068 MockFunction<void()> checkPoint;
69
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010070 TestReport() : messanger(DbusEnvironment::getIoc())
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010071 {
72 clockFake.system.set(systemTimestamp);
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +010073 ON_CALL(storageMock, store(to_file_path(ReportParams().reportId()), _))
74 .WillByDefault(SaveArg<1>(&storedConfiguration));
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010075 }
76
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000077 void initMetricMocks(
78 const std::vector<LabeledMetricParameters>& metricParameters)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010079 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000080 for (auto i = metricMocks.size(); i < metricParameters.size(); ++i)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010081 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000082 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>());
83 }
84 metricMocks.resize(metricParameters.size());
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000085
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000086 std::vector<MetricValue> readings{{MetricValue{"a", "b", 17.1, 114},
87 MetricValue{"aa", "bb", 42.0, 74}}};
Szymon Dompkebcf045a2022-09-16 15:23:30 +020088
89 ASSERT_THAT(readings.size(), Ge(metricParameters.size()));
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000090
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000091 for (size_t i = 0; i < metricParameters.size(); ++i)
92 {
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +010093 ON_CALL(*metricMocks[i], getUpdatedReadings())
94 .WillByDefault(ReturnRefOfCopy(std::vector({readings[i]})));
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000095 ON_CALL(*metricMocks[i], dumpConfiguration())
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000096 .WillByDefault(Return(metricParameters[i]));
Wludzik, Jozefe2362792020-10-27 17:23:55 +010097 }
98 }
99
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100100 std::vector<std::shared_ptr<interfaces::Metric>>
101 getMetricsFromReadingParams(const ReadingParameters& params)
102 {
103 const auto metricParameters =
104 reportFactoryMock->convertMetricParams(params);
105 std::vector<std::shared_ptr<MetricMock>> metricMocks;
106
107 for (size_t i = 0; i < metricParameters.size(); ++i)
108 {
109 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>());
110 ON_CALL(*metricMocks[i], dumpConfiguration())
111 .WillByDefault(Return(metricParameters[i]));
112 }
113
114 return utils::convContainer<std::shared_ptr<interfaces::Metric>>(
115 metricMocks);
116 }
117
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200118 void SetUp() override
119 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100120 sut = makeReport(defaultParams());
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200121 }
122
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100123 static interfaces::JsonStorage::FilePath to_file_path(std::string id)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100124 {
125 return interfaces::JsonStorage::FilePath(
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100126 std::to_string(std::hash<std::string>{}(id)));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100127 }
128
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200129 std::unique_ptr<Report> makeReport(const ReportParams& params)
130 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000131 initMetricMocks(params.metricParameters());
132
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200133 return std::make_unique<Report>(
134 DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100135 params.reportId(), params.reportName(), params.reportingType(),
136 params.reportActions(), params.interval(), params.appendLimit(),
137 params.reportUpdates(), *reportManagerMock, storageMock,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200138 utils::convContainer<std::shared_ptr<interfaces::Metric>>(
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200139 metricMocks),
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100140 *reportFactoryMock, params.enabled(), std::move(clockFakePtr),
141 params.readings());
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200142 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200143
144 template <class T>
145 static T getProperty(const std::string& path, const std::string& property)
146 {
Szymon Dompkee28aa532021-10-27 12:33:12 +0200147 return DbusEnvironment::getProperty<T>(path, Report::reportIfaceName,
148 property);
149 }
150
151 template <class T>
152 static boost::system::error_code setProperty(const std::string& path,
153 const std::string& property,
154 const T& newValue)
155 {
156 return DbusEnvironment::setProperty<T>(path, Report::reportIfaceName,
157 property, newValue);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100158 }
159
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200160 template <class T>
161 struct ChangePropertyParams
162 {
163 Matcher<T> valueBefore = _;
164 T newValue;
165 Matcher<boost::system::error_code> ec =
166 Eq(boost::system::errc::success);
167 Matcher<T> valueAfter = Eq(newValue);
168 };
169
170 template <class T>
171 static void changeProperty(const std::string& path,
172 const std::string& property,
173 ChangePropertyParams<T> p)
174 {
175 ASSERT_THAT(getProperty<T>(path, property), p.valueBefore);
176 ASSERT_THAT(setProperty<T>(path, property, p.newValue), p.ec);
177 EXPECT_THAT(getProperty<T>(path, property), p.valueAfter);
178 }
179
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100180 boost::system::error_code call(const std::string& path,
181 const std::string& interface,
182 const std::string& method)
183 {
184 std::promise<boost::system::error_code> methodPromise;
185 DbusEnvironment::getBus()->async_method_call(
186 [&methodPromise](boost::system::error_code ec) {
187 methodPromise.set_value(ec);
188 },
189 DbusEnvironment::serviceName(), path, interface, method);
190 return DbusEnvironment::waitForFuture(methodPromise.get_future());
191 }
192
193 boost::system::error_code update(const std::string& path)
194 {
195 return call(path, Report::reportIfaceName, "Update");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200196 }
197
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200198 boost::system::error_code deleteReport(const std::string& path)
199 {
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100200 return call(path, Report::deleteIfaceName, "Delete");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200201 }
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200202
203 static std::pair<std::string, std::vector<std::string>>
204 makeStateDetail(const std::string& detailType,
205 std::vector<std::string> detailArgs)
206 {
207 return make_pair(detailType, detailArgs);
208 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200209};
210
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100211TEST_F(TestReport, returnsId)
212{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100213 EXPECT_THAT(sut->getId(), Eq(defaultParams().reportId()));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100214}
215
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200216TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
217{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200218 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100219 Eq(defaultParams().enabled()));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200220 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100221 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100222 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100223 EXPECT_THAT(
224 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100225 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100226 return utils::enumToString(v);
227 })));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200228 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100229 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100230 ReportAction::emitsReadingsUpdate)));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200231 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "AppendLimit"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100232 Eq(defaultParams().appendLimit()));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100233 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100234 Eq(utils::enumToString(defaultParams().reportingType())));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200235 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportUpdates"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100236 Eq(utils::enumToString(defaultParams().reportUpdates())));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200237 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200238 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100239 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100240 ReportAction::logToMetricReportsCollection)));
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000241 EXPECT_THAT(getProperty<ReadingParameters>(
242 sut->getPath(), "ReadingParametersFutureVersion"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100243 Eq(toReadingParameters(defaultParams().metricParameters())));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100244 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100245 Eq(defaultParams().reportName()));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100246 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200247 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200248 IsEmpty());
249 EXPECT_THAT(
250 getProperty<ErrorMessagesDbusType>(sut->getPath(), "ErrorMessages"),
251 IsEmpty());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200252}
253
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200254TEST_F(TestReport, readingsAreInitialyEmpty)
255{
256 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
257 Eq(Readings{}));
258}
259
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100260TEST_F(TestReport, setReadingParametersWithNewParams)
261{
262 ReadingParameters newParams = toReadingParameters(
263 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
264 {LabeledSensorInfo{"Service",
265 "/xyz/openbmc_project/sensors/power/psu",
266 "NewMetadata123"}},
267 OperationType::avg,
268 "NewMetricId123",
269 CollectionTimeScope::startup,
270 CollectionDuration(250ms)}}});
271 auto metrics = getMetricsFromReadingParams(newParams);
272
273 EXPECT_CALL(*reportFactoryMock, updateMetrics(_, _, _))
274 .WillOnce(SetArgReferee<0>(metrics));
275 EXPECT_THAT(
276 setProperty(sut->getPath(), "ReadingParametersFutureVersion", newParams)
277 .value(),
278 Eq(boost::system::errc::success));
279 EXPECT_THAT(getProperty<ReadingParameters>(
280 sut->getPath(), "ReadingParametersFutureVersion"),
281 Eq(newParams));
282}
283
Szymon Dompke32305f12022-07-05 15:37:21 +0200284TEST_F(TestReport, setReadingParametersWithTooLongMetricId)
285{
286 const ReadingParameters currentValue =
287 toReadingParameters(defaultParams().metricParameters());
288
289 ReadingParameters newParams = toReadingParameters(
290 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
291 {LabeledSensorInfo{"Service",
292 "/xyz/openbmc_project/sensors/power/psu",
293 "NewMetadata123"}},
294 OperationType::avg,
295 utils::string_utils::getTooLongId(),
296 CollectionTimeScope::startup,
297 CollectionDuration(250ms)}}});
298
299 changeProperty<ReadingParameters>(
300 sut->getPath(), "ReadingParametersFutureVersion",
301 {.valueBefore = Eq(currentValue),
302 .newValue = newParams,
303 .ec = Eq(boost::system::errc::invalid_argument),
304 .valueAfter = Eq(currentValue)});
305}
306
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100307TEST_F(TestReport, setReportingTypeWithValidNewType)
308{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200309 changeProperty<std::string>(
310 sut->getPath(), "ReportingType",
311 {.valueBefore = Not(Eq(utils::enumToString(ReportingType::onRequest))),
312 .newValue = utils::enumToString(ReportingType::onRequest)});
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100313}
314
315TEST_F(TestReport, setReportingTypeWithInvalidType)
316{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200317 const std::string currentValue =
318 utils::enumToString(defaultParams().reportingType());
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100319
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200320 changeProperty<std::string>(
321 sut->getPath(), "ReportingType",
322 {.valueBefore = Eq(currentValue),
323 .newValue = "Periodic_ABC",
324 .ec = Eq(boost::system::errc::invalid_argument),
325 .valueAfter = Eq(currentValue)});
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100326}
327
328TEST_F(TestReport, setReportActionsWithValidNewActions)
329{
330 std::vector<std::string> newActions = {"EmitsReadingsUpdate"};
331 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100332 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100333 [](const auto v) { return utils::enumToString(v); });
334
335 EXPECT_THAT(newActions, Ne(currActions));
336 EXPECT_THAT(
337 setProperty(sut->getPath(), "ReportActions", newActions).value(),
338 Eq(boost::system::errc::success));
339 EXPECT_THAT(
340 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
341 UnorderedElementsAre("EmitsReadingsUpdate",
342 "LogToMetricReportsCollection"));
343}
344
345TEST_F(TestReport, setReportActionsWithValidUnsortedActions)
346{
347 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
348 "EmitsReadingsUpdate"};
349 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
350 "LogToMetricReportsCollection"};
351 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100352 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100353 [](const auto v) { return utils::enumToString(v); });
354
355 EXPECT_THAT(newActions, Ne(currActions));
356 EXPECT_THAT(
357 setProperty(sut->getPath(), "ReportActions", newActions).value(),
358 Eq(boost::system::errc::success));
359 EXPECT_THAT(
360 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
361 Eq(expectedActions));
362}
363
364TEST_F(TestReport, setReportActionsWithEmptyActions)
365{
366 std::vector<std::string> newActions = {};
367 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
368 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100369 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100370 [](const auto v) { return utils::enumToString(v); });
371
372 EXPECT_THAT(newActions, Ne(currActions));
373 EXPECT_THAT(
374 setProperty(sut->getPath(), "ReportActions", newActions).value(),
375 Eq(boost::system::errc::success));
376 EXPECT_THAT(
377 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
378 Eq(expectedActions));
379}
380
381TEST_F(TestReport, setReportActionsWithInvalidActions)
382{
383 std::vector<std::string> invalidActions = {"EmitsReadingsUpdate_1"};
384 EXPECT_THAT(
385 setProperty(sut->getPath(), "ReportActions", invalidActions).value(),
386 Eq(boost::system::errc::invalid_argument));
387 EXPECT_THAT(
388 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100389 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100390 return utils::enumToString(v);
391 })));
392}
393
394TEST_F(TestReport, createReportWithEmptyActions)
395{
396 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
397
398 sut = makeReport(ReportParams().reportId("TestId_1").reportActions({}));
399 EXPECT_THAT(
400 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
401 Eq(expectedActions));
402}
403
404TEST_F(TestReport, createReportWithValidUnsortedActions)
405{
406 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
407 "EmitsReadingsUpdate"};
408 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
409 "LogToMetricReportsCollection"};
410
411 sut = makeReport(
412 ReportParams()
413 .reportId("TestId_1")
414 .reportActions(utils::transform(newActions, [](const auto& action) {
415 return utils::toReportAction(action);
416 })));
417 EXPECT_THAT(
418 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
419 Eq(expectedActions));
420}
421
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200422TEST_F(TestReport, setEnabledWithNewValue)
423{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100424 bool newValue = !defaultParams().enabled();
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200425 EXPECT_THAT(setProperty(sut->getPath(), "Enabled", newValue).value(),
426 Eq(boost::system::errc::success));
427 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(newValue));
428}
429
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200430TEST_F(TestReport, setIntervalWithValidValue)
431{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200432 uint64_t newValue = ReportManager::minInterval.count() * 42;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200433 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200434 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200435 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
436 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200437}
438
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100439TEST_F(
440 TestReport,
441 settingIntervalWithInvalidValueDoesNotChangePropertyAndReturnsInvalidArgument)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200442{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200443 uint64_t newValue = ReportManager::minInterval.count() - 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200444 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100445 Eq(boost::system::errc::invalid_argument));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200446 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100447 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100448}
449
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200450TEST_F(TestReport, settingInvalidReportingTypeCreatesErrorMessage)
451{
452 auto report = makeReport(defaultParams()
453 .reportId("report2")
454 .reportingType(ReportingType::onRequest)
455 .interval(Milliseconds{0}));
456
457 EXPECT_THAT(
458 setProperty<std::string>(report->getPath(), "ReportingType", "Periodic")
459 .value(),
460 Eq(boost::system::errc::success));
461
462 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
463 Eq("Periodic"));
464 EXPECT_THAT(
465 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
466 UnorderedElementsAre(
467 ErrorMessageDbusType(
468 utils::enumToString(ErrorType::propertyConflict), "Interval"),
469 ErrorMessageDbusType(
470 utils::enumToString(ErrorType::propertyConflict),
471 "ReportingType")));
472}
473
474TEST_F(TestReport, settingValidReportingTypeRemovesErrors)
475{
476 auto report = makeReport(defaultParams()
477 .reportId("report2")
478 .reportingType(ReportingType::onRequest)
479 .interval(Milliseconds{0}));
480
481 EXPECT_THAT(
482 setProperty<std::string>(report->getPath(), "ReportingType", "Periodic")
483 .value(),
484 Eq(boost::system::errc::success));
485 EXPECT_THAT(setProperty<std::string>(report->getPath(), "ReportingType",
486 "OnRequest")
487 .value(),
488 Eq(boost::system::errc::success));
489
490 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
491 Eq("OnRequest"));
492 EXPECT_THAT(
493 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
494 IsEmpty());
495}
496
497TEST_F(TestReport, settingInvalidIntervalDisablesReport)
498{
499 auto report = makeReport(defaultParams()
500 .reportId("report2")
501 .reportingType(ReportingType::periodic)
502 .interval(ReportManager::minInterval));
503
504 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval", 0).value(),
505 Eq(boost::system::errc::success));
506
507 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"), Eq(0u));
508 EXPECT_THAT(
509 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
510 UnorderedElementsAre(
511 ErrorMessageDbusType(
512 utils::enumToString(ErrorType::propertyConflict), "Interval"),
513 ErrorMessageDbusType(
514 utils::enumToString(ErrorType::propertyConflict),
515 "ReportingType")));
516}
517
518TEST_F(TestReport, settingValidIntervalEnablesReport)
519{
520 auto report = makeReport(defaultParams()
521 .reportId("report2")
522 .reportingType(ReportingType::periodic)
523 .interval(ReportManager::minInterval));
524
525 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval", 0).value(),
526 Eq(boost::system::errc::success));
527 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval",
528 ReportManager::minInterval.count())
529 .value(),
530 Eq(boost::system::errc::success));
531
532 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"),
533 Eq(ReportManager::minInterval.count()));
534 EXPECT_THAT(
535 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
536 IsEmpty());
537}
538
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200539TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
540{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100541 EXPECT_THAT(
542 setProperty(sut->getPath(), "EmitsReadingsUpdate", true).value(),
543 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200544 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100545 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100546 ReportAction::emitsReadingsUpdate)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200547}
548
549TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
550{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100551 EXPECT_THAT(
552 setProperty(sut->getPath(), "LogToMetricReportsCollection", true)
553 .value(),
554 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200555 EXPECT_THAT(
556 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100557 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100558 ReportAction::logToMetricReportsCollection)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200559}
560
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100561TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
562{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100563 EXPECT_CALL(storageMock, store(_, _)).Times(0);
564 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
565 .Times(AtLeast(1));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100566
567 bool persistency = false;
568 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
569 Eq(boost::system::errc::success));
570 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
571 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200572}
573
574TEST_F(TestReport, deleteReport)
575{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200576 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
577 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200578 EXPECT_THAT(ec, Eq(boost::system::errc::success));
579}
580
581TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
582{
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200583 auto ec =
584 deleteReport(utils::constants::reportDirPath.str + "NonExisting"s);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200585 EXPECT_THAT(ec.value(), Eq(EBADR));
586}
587
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100588TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
589{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100590 EXPECT_CALL(storageMock, store(_, _)).Times(0);
591 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
592 .Times(AtLeast(1));
593
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100594 auto ec = deleteReport(sut->getPath());
595 EXPECT_THAT(ec, Eq(boost::system::errc::success));
596}
597
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100598TEST_F(TestReport, updatesTriggerIdWhenTriggerIsAdded)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100599{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100600 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100601
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100602 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100603 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100604 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100605 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100606 messanger.send(messages::TriggerPresenceChangedInd{
607 messages::Presence::Exist, "trigger2", {"someOtherReport"}});
608 messanger.send(messages::TriggerPresenceChangedInd{
609 messages::Presence::Exist,
610 "trigger3",
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100611 {"someOtherReport", defaultParams().reportId()}});
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100612
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100613 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200614 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
615 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
616 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100617}
618
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100619TEST_F(TestReport, updatesTriggerIdWhenTriggerIsRemoved)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100620{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100621 utils::Messanger messanger(DbusEnvironment::getIoc());
622
623 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100624 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100625 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100626 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100627 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100628 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100629
630 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100631 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100632 messanger.send(messages::TriggerPresenceChangedInd{
633 messages::Presence::Removed, "trigger2", {}});
634 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100635 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100636
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100637 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200638 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
639 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100640}
641
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100642TEST_F(TestReport, updatesTriggerIdWhenTriggerIsModified)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100643{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100644 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100645
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100646 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100647 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100648 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100649 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100650 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100651 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100652
653 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100654 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100655 messanger.send(messages::TriggerPresenceChangedInd{
656 messages::Presence::Exist, "trigger2", {}});
657 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100658 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100659
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100660 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200661 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
662 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
663 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100664}
665
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100666class TestReportStore :
667 public TestReport,
668 public WithParamInterface<std::pair<std::string, nlohmann::json>>
669{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100670 void SetUp() override
671 {}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100672};
673
674INSTANTIATE_TEST_SUITE_P(
675 _, TestReportStore,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100676 Values(
677 std::make_pair("Enabled"s, nlohmann::json(defaultParams().enabled())),
678 std::make_pair("Version"s, nlohmann::json(6)),
679 std::make_pair("Id"s, nlohmann::json(defaultParams().reportId())),
680 std::make_pair("Name"s, nlohmann::json(defaultParams().reportName())),
681 std::make_pair("ReportingType",
682 nlohmann::json(defaultParams().reportingType())),
683 std::make_pair("ReportActions", nlohmann::json(utils::transform(
684 defaultParams().reportActions(),
685 [](const auto v) {
686 return utils::toUnderlying(v);
687 }))),
688 std::make_pair("Interval",
689 nlohmann::json(defaultParams().interval().count())),
690 std::make_pair("AppendLimit",
691 nlohmann::json(ReportParams().appendLimit())),
692 std::make_pair(
693 "ReadingParameters",
694 nlohmann::json(
695 {{{tstring::SensorPath::str(),
696 {{{tstring::Service::str(), "Service"},
697 {tstring::Path::str(),
698 "/xyz/openbmc_project/sensors/power/p1"},
699 {tstring::Metadata::str(), "metadata1"}}}},
700 {tstring::OperationType::str(), OperationType::avg},
701 {tstring::Id::str(), "MetricId1"},
702 {tstring::CollectionTimeScope::str(),
703 CollectionTimeScope::point},
704 {tstring::CollectionDuration::str(), 0}},
705 {{tstring::SensorPath::str(),
706 {{{tstring::Service::str(), "Service"},
707 {tstring::Path::str(),
708 "/xyz/openbmc_project/sensors/power/p2"},
709 {tstring::Metadata::str(), "metadata2"}}}},
710 {tstring::OperationType::str(), OperationType::avg},
711 {tstring::Id::str(), "MetricId2"},
712 {tstring::CollectionTimeScope::str(),
713 CollectionTimeScope::point},
714 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100715
716TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
717{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100718 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100719
720 {
721 InSequence seq;
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100722 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100723 EXPECT_CALL(checkPoint, Call());
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100724 EXPECT_CALL(storageMock, store(to_file_path(sut->getId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100725 }
726
727 setProperty(sut->getPath(), "Persistency", false);
728 checkPoint.Call();
729 setProperty(sut->getPath(), "Persistency", true);
730
731 const auto& [key, value] = GetParam();
732
733 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
734}
735
736TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
737{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100738 EXPECT_CALL(storageMock,
739 store(to_file_path(defaultParams().reportId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100740
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100741 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100742
743 const auto& [key, value] = GetParam();
744
745 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
746}
747
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200748class TestReportValidNames :
749 public TestReport,
750 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200751{
752 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200753 void SetUp() override
754 {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200755};
756
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200757INSTANTIATE_TEST_SUITE_P(
758 ValidNames, TestReportValidNames,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100759 Values(defaultParams().reportName("Valid_1"),
760 defaultParams().reportName("Valid_1/Valid_2"),
761 defaultParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200762
763TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
764{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200765 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200766}
767
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100768class TestReportInvalidIds :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200769 public TestReport,
770 public WithParamInterface<ReportParams>
771{
772 public:
773 void SetUp() override
774 {}
775};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200776
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100777INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidIds,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100778 Values(defaultParams().reportId("/"),
779 defaultParams().reportId("/Invalid"),
780 defaultParams().reportId("Invalid/"),
781 defaultParams().reportId("Invalid/Invalid/"),
782 defaultParams().reportId("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200783
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100784TEST_P(TestReportInvalidIds, failsToCreateReportWithInvalidName)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100785{
786 EXPECT_CALL(storageMock, store).Times(0);
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100787
788 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100789}
790
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200791class TestReportAllReportTypes :
792 public TestReport,
793 public WithParamInterface<ReportParams>
794{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200795 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200796 void SetUp() override
797 {
798 sut = makeReport(GetParam());
799 }
800};
801
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100802INSTANTIATE_TEST_SUITE_P(
803 _, TestReportAllReportTypes,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100804 Values(defaultParams().reportingType(ReportingType::onRequest),
805 defaultParams().reportingType(ReportingType::onChange),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200806 defaultParams()
807 .reportingType(ReportingType::periodic)
808 .interval(ReportManager::minInterval)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200809
810TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
811{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100812 EXPECT_THAT(utils::toReportingType(
813 getProperty<std::string>(sut->getPath(), "ReportingType")),
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200814 Eq(GetParam().reportingType()));
815}
816
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100817TEST_P(TestReportAllReportTypes, readingsAreUpdated)
818{
819 clockFake.system.advance(10ms);
820
821 messanger.send(messages::UpdateReportInd{{sut->getId()}});
822 const auto [timestamp, readings] =
823 getProperty<Readings>(sut->getPath(), "Readings");
824
825 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
826}
827
828TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIsDisabled)
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200829{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100830 clockFake.system.advance(10ms);
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200831
832 setProperty(sut->getPath(), "Enabled", false);
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100833 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200834 const auto [timestamp, readings] =
835 getProperty<Readings>(sut->getPath(), "Readings");
836
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100837 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200838}
839
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100840TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIdDiffers)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100841{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100842 clockFake.system.advance(10ms);
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100843
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100844 messanger.send(messages::UpdateReportInd{{sut->getId() + "x"s}});
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100845 const auto [timestamp, readings] =
846 getProperty<Readings>(sut->getPath(), "Readings");
847
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100848 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100849}
850
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100851class TestReportOnRequestType : public TestReport
852{
853 void SetUp() override
854 {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100855 sut =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100856 makeReport(defaultParams().reportingType(ReportingType::onRequest));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100857 }
858};
859
860TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
861{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100862 clockFake.system.advance(10ms);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100863
864 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
865
866 const auto [timestamp, readings] =
867 getProperty<Readings>(sut->getPath(), "Readings");
868
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100869 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100870}
871
872TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
873{
874 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
875
876 const auto [timestamp, readings] =
877 getProperty<Readings>(sut->getPath(), "Readings");
878
879 EXPECT_THAT(readings,
880 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000881 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100882}
883
884class TestReportNonOnRequestType :
885 public TestReport,
886 public WithParamInterface<ReportParams>
887{
888 void SetUp() override
889 {
890 sut = makeReport(GetParam());
891 }
892};
893
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100894INSTANTIATE_TEST_SUITE_P(
895 _, TestReportNonOnRequestType,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100896 Values(defaultParams().reportingType(ReportingType::periodic),
897 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100898
899TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
900{
901 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
902
903 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
904 Eq(Readings{}));
905}
906
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200907class TestReportNonPeriodicReport :
908 public TestReport,
909 public WithParamInterface<ReportParams>
910{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200911 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200912 void SetUp() override
913 {
914 sut = makeReport(GetParam());
915 }
916};
917
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100918INSTANTIATE_TEST_SUITE_P(
919 _, TestReportNonPeriodicReport,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100920 Values(defaultParams().reportingType(ReportingType::onRequest),
921 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200922
923TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
924{
925 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
926
927 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
928 Eq(Readings{}));
929}
930
931class TestReportPeriodicReport : public TestReport
932{
933 void SetUp() override
934 {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200935 sut = makeReport(defaultParams()
936 .reportingType(ReportingType::periodic)
937 .interval(ReportManager::minInterval));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200938 }
939};
940
941TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
942{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100943 clockFake.system.advance(10ms);
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200944 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
945
946 const auto [timestamp, readings] =
947 getProperty<Readings>(sut->getPath(), "Readings");
948
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100949 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200950}
951
952TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
953{
954 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
955
956 const auto [timestamp, readings] =
957 getProperty<Readings>(sut->getPath(), "Readings");
958
959 EXPECT_THAT(readings,
960 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000961 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200962}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100963
Szymon Dompke3eb56862021-09-20 15:32:04 +0200964struct ReportUpdatesReportParams
965{
966 ReportParams reportParams;
967 std::vector<ReadingData> expectedReadings;
968 bool expectedEnabled;
969};
970
971class TestReportWithReportUpdatesAndLimit :
972 public TestReport,
973 public WithParamInterface<ReportUpdatesReportParams>
974{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200975 public:
Szymon Dompke3eb56862021-09-20 15:32:04 +0200976 void SetUp() override
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200977 {}
978
979 void changeReport(ReportingType rt, Milliseconds interval)
Szymon Dompke3eb56862021-09-20 15:32:04 +0200980 {
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200981 setProperty<std::string>(sut->getPath(), "ReportingType",
982 utils::enumToString(rt));
983 setProperty<uint64_t>(sut->getPath(), "Interval", interval.count());
984 }
985
986 auto readings()
987 {
988 auto [timestamp, readings] =
989 getProperty<Readings>(sut->getPath(), "Readings");
990 return readings;
991 }
992
993 void updateReportFourTimes()
994 {
995 for (int i = 0; i < 4; i++)
996 {
997 messanger.send(messages::UpdateReportInd{{sut->getId()}});
998 }
Szymon Dompke3eb56862021-09-20 15:32:04 +0200999 }
1000};
1001
1002INSTANTIATE_TEST_SUITE_P(
1003 _, TestReportWithReportUpdatesAndLimit,
1004 Values(
1005 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001006 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001007 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1008 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001009 std::vector<ReadingData>{{std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1010 std::make_tuple("a"s, "b"s, 17.1, 114u),
1011 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1012 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1013 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
1014 true},
1015 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001016 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001017 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1018 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001019 std::vector<ReadingData>{
1020 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1021 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1022 std::make_tuple("a"s, "b"s, 17.1, 114u),
1023 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1024 true},
1025 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001026 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001027 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1028 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001029 std::vector<ReadingData>{}, true},
1030 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001031 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001032 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1033 .appendLimit(10),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001034 std::vector<ReadingData>{
1035 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1036 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1037 std::make_tuple("a"s, "b"s, 17.1, 114u),
1038 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1039 std::make_tuple("a"s, "b"s, 17.1, 114u),
1040 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1041 std::make_tuple("a"s, "b"s, 17.1, 114u),
1042 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1043 true},
1044 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001045 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001046 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1047 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001048 std::vector<ReadingData>{{std::make_tuple("a"s, "b"s, 17.1, 114u),
1049 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1050 std::make_tuple("a"s, "b"s, 17.1, 114u),
1051 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1052 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
1053 false},
1054 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001055 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001056 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1057 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001058 std::vector<ReadingData>{
1059 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1060 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1061 std::make_tuple("a"s, "b"s, 17.1, 114u),
1062 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1063 false},
1064 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001065 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001066 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1067 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001068 std::vector<ReadingData>{}, false},
1069 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001070 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001071 .reportUpdates(ReportUpdates::overwrite)
1072 .appendLimit(500),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001073 std::vector<ReadingData>{
1074 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1075 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1076 true},
1077 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001078 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001079 .reportUpdates(ReportUpdates::overwrite)
1080 .appendLimit(1),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001081 std::vector<ReadingData>{
1082 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1083 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1084 true},
1085 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001086 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001087 .reportUpdates(ReportUpdates::overwrite)
1088 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001089 std::vector<ReadingData>{
1090 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1091 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001092 true},
1093 ReportUpdatesReportParams{
1094 defaultParams()
1095 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1096 .appendLimit(std::numeric_limits<uint64_t>::max()),
1097 std::vector<ReadingData>{
1098 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1099 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1100 false}));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001101
1102TEST_P(TestReportWithReportUpdatesAndLimit,
1103 readingsAreUpdatedAfterIntervalExpires)
1104{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001105 sut = makeReport(ReportParams(GetParam().reportParams)
1106 .reportingType(ReportingType::periodic)
1107 .interval(std::chrono::hours(1000)));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001108
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001109 updateReportFourTimes();
Szymon Dompke3eb56862021-09-20 15:32:04 +02001110
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001111 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1112 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1113 Eq(GetParam().expectedEnabled));
1114}
1115
1116TEST_P(TestReportWithReportUpdatesAndLimit,
1117 appendLimitIsRespectedAfterChangingToPeriodic)
1118{
1119 sut = makeReport(ReportParams(GetParam().reportParams)
1120 .reportingType(ReportingType::onRequest)
1121 .interval(std::chrono::hours(0)));
1122
1123 changeReport(ReportingType::periodic, std::chrono::hours(1000));
1124 updateReportFourTimes();
1125
1126 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1127 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1128 Eq(GetParam().expectedEnabled));
1129}
1130
1131TEST_P(TestReportWithReportUpdatesAndLimit,
1132 appendLimitIsIgnoredAfterChangingToOnRequest)
1133{
1134 sut = makeReport(ReportParams(GetParam().reportParams)
1135 .reportingType(ReportingType::periodic)
1136 .interval(std::chrono::hours(1000)));
1137
1138 changeReport(ReportingType::onRequest, Milliseconds{0});
1139 updateReportFourTimes();
1140
1141 EXPECT_THAT(readings(), SizeIs(2u));
1142 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(true));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001143}
1144
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001145class TestReportInitialization : public TestReport
1146{
1147 public:
1148 void SetUp() override
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001149 {
1150 initMetricMocks(defaultParams().metricParameters());
1151 }
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001152
Patrick Williams39cc6ac2022-07-22 19:26:56 -05001153 void monitorProc(sdbusplus::message_t& msg)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001154 {
1155 std::string iface;
1156 std::vector<std::pair<std::string, std::variant<Readings>>>
1157 changed_properties;
1158 std::vector<std::string> invalidated_properties;
1159
1160 msg.read(iface, changed_properties, invalidated_properties);
1161
1162 if (iface == Report::reportIfaceName)
1163 {
1164 for (const auto& [name, value] : changed_properties)
1165 {
1166 if (name == "Readings")
1167 {
1168 readingsUpdated.Call();
1169 }
1170 }
1171 }
1172 }
1173
1174 void makeMonitor()
1175 {
Patrick Williams3a62ee12021-12-03 10:13:25 -06001176 monitor = std::make_unique<sdbusplus::bus::match_t>(
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001177 *DbusEnvironment::getBus(),
1178 sdbusplus::bus::match::rules::propertiesChanged(
1179 sut->getPath(), Report::reportIfaceName),
1180 [this](auto& msg) { monitorProc(msg); });
1181 }
1182
Patrick Williams3a62ee12021-12-03 10:13:25 -06001183 std::unique_ptr<sdbusplus::bus::match_t> monitor;
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001184 MockFunction<void()> readingsUpdated;
1185};
1186
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001187TEST_F(TestReportInitialization,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001188 registersForMetricUpdatesWhenOnChangeReportCreated)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001189{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001190 std::vector<const interfaces::MetricListener*> args;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001191 for (auto& metric : metricMocks)
1192 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001193 EXPECT_CALL(*metric, registerForUpdates(_))
1194 .WillOnce(Invoke([&args](const interfaces::MetricListener& report) {
1195 args.emplace_back(&report);
1196 }));
1197 ;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001198 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001199
1200 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1201
1202 EXPECT_THAT(args, SizeIs(metricMocks.size()));
1203 for (const auto* reportPtr : args)
1204 {
1205 EXPECT_THAT(reportPtr, Eq(sut.get()));
1206 }
1207}
1208
1209TEST_F(TestReportInitialization,
1210 deregistersForMetricUpdatesWhenOnChangeReportDestroyed)
1211{
1212 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1213
1214 for (auto& metric : metricMocks)
1215 {
1216 EXPECT_CALL(*metric,
1217 unregisterFromUpdates(Ref(
1218 static_cast<interfaces::MetricListener&>(*sut.get()))));
1219 }
1220
1221 sut = nullptr;
1222}
1223
1224TEST_F(TestReportInitialization,
1225 metricsAreInitializedWhenEnabledReportConstructed)
1226{
1227 for (auto& metric : metricMocks)
1228 {
1229 EXPECT_CALL(*metric, initialize());
1230 }
1231 sut = makeReport(defaultParams().enabled(true));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001232}
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001233
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001234TEST_F(TestReportInitialization,
1235 metricsAreNotInitializedWhenDisabledReportConstructed)
1236{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001237 for (auto& metric : metricMocks)
1238 {
1239 EXPECT_CALL(*metric, initialize()).Times(0);
1240 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001241 sut = makeReport(defaultParams().enabled(false));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001242}
1243
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001244TEST_F(TestReportInitialization,
1245 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001246{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001247 EXPECT_CALL(readingsUpdated, Call())
1248 .WillOnce(
1249 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
1250
1251 const auto elapsed = DbusEnvironment::measureTime([this] {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001252 sut = makeReport(defaultParams()
1253 .reportingType(ReportingType::periodic)
1254 .reportActions({ReportAction::emitsReadingsUpdate})
1255 .interval(ReportManager::minInterval));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001256 makeMonitor();
1257 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
1258 });
1259
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001260 EXPECT_THAT(elapsed, AllOf(Ge(ReportManager::minInterval),
1261 Lt(ReportManager::minInterval * 2)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001262}
1263
1264TEST_F(TestReportInitialization,
1265 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
1266{
1267 EXPECT_CALL(readingsUpdated, Call()).Times(0);
1268
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001269 sut = makeReport(defaultParams()
1270 .reportingType(ReportingType::periodic)
1271 .reportActions({}));
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001272 makeMonitor();
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001273 DbusEnvironment::sleepFor(defaultParams().interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001274}
Szymon Dompke3eb56862021-09-20 15:32:04 +02001275
1276TEST_F(TestReportInitialization, appendLimitDeducedProperly)
1277{
1278 sut = makeReport(
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001279 defaultParams().appendLimit(std::numeric_limits<uint64_t>::max()));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001280 auto appendLimit = getProperty<uint64_t>(sut->getPath(), "AppendLimit");
1281 EXPECT_EQ(appendLimit, 2ull);
1282}
Krzysztof Grobelnye6c417c2022-02-02 17:25:53 +01001283
1284TEST_F(TestReportInitialization, appendLimitSetToUintMaxIsStoredCorrectly)
1285{
Krzysztof Grobelnye6c417c2022-02-02 17:25:53 +01001286 sut = makeReport(
1287 ReportParams().appendLimit(std::numeric_limits<uint64_t>::max()));
1288
1289 ASSERT_THAT(storedConfiguration.at("AppendLimit"),
1290 Eq(std::numeric_limits<uint64_t>::max()));
1291}
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001292
1293TEST_F(TestReportInitialization, triggerIdsPropertyIsInitialzed)
1294{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001295 for (const auto& triggerId : {"trigger1", "trigger2"})
1296 {
1297 messanger.on_receive<messages::CollectTriggerIdReq>(
Szymon Dompkee0ed5082022-05-20 10:54:25 +02001298 [this, triggerId](const auto& msg) {
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001299 messanger.send(messages::CollectTriggerIdResp{triggerId});
1300 });
1301 }
1302
1303 sut = makeReport(ReportParams());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001304
1305 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +02001306 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
1307 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
1308 utils::constants::triggerDirPath / "trigger2"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001309}
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001310
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +01001311TEST_F(TestReportInitialization,
1312 metricValuesAreNotStoredForReportUpdatesDifferentThanAppendStopsWhenFull)
1313{
1314 sut = makeReport(ReportParams()
1315 .reportingType(ReportingType::periodic)
1316 .interval(1h)
1317 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1318 .readings(Readings{{}, {{}}}));
1319
1320 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1321 Eq(storedConfiguration.end()));
1322}
1323
1324TEST_F(TestReportInitialization, metricValuesAreNotStoredForOnRequestReport)
1325{
1326 sut = makeReport(ReportParams()
1327 .reportingType(ReportingType::onRequest)
1328 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1329 .readings(Readings{{}, {{}}}));
1330
1331 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1332 Eq(storedConfiguration.end()));
1333}
1334
1335TEST_F(TestReportInitialization,
1336 metricValuesAreStoredForNonOnRequestReportWithAppendStopsWhenFull)
1337{
1338 const auto readings = Readings{{}, {{}}};
1339
1340 sut = makeReport(ReportParams()
1341 .reportingType(ReportingType::periodic)
1342 .interval(1h)
1343 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1344 .readings(readings));
1345
1346 ASSERT_THAT(storedConfiguration.at("MetricValues").get<LabeledReadings>(),
1347 Eq(utils::toLabeledReadings(readings)));
1348}
1349
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001350class TestReportInitializationOnChangeReport : public TestReportInitialization
1351{
1352 public:
1353 void SetUp() override
1354 {
1355 initMetricMocks(params.metricParameters());
1356 }
1357
1358 ReportParams params = defaultOnChangeParams();
1359};
1360
1361TEST_F(TestReportInitializationOnChangeReport,
1362 doesntUpdateReadingsWhenNotRequired)
1363{
1364 EXPECT_CALL(*metricMocks[0], updateReadings(_)).Times(0);
1365
1366 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(false));
1367
1368 sut = makeReport(params);
1369
1370 DbusEnvironment::sleepFor(500ms);
1371}
1372
1373TEST_F(TestReportInitializationOnChangeReport, updatesReadingsWhenRequired)
1374{
1375 EXPECT_CALL(*metricMocks[0], updateReadings(_))
1376 .WillOnce(Return())
1377 .WillOnce(
1378 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")))
1379 .WillRepeatedly(Return());
1380
1381 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(true));
1382
1383 sut = makeReport(params);
1384
1385 DbusEnvironment::waitForFuture("readingsUpdated");
1386}