blob: ea3b4f854a8e5392eec48c451700a40c7b4676c0 [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]));
Szymon Dompke892f7c82022-10-12 09:54:22 +0200112 ON_CALL(*metricMocks[i], sensorCount())
113 .WillByDefault(Return(metricParameters[i]
114 .at_label<tstring::SensorPath>()
115 .size()));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100116 }
117
118 return utils::convContainer<std::shared_ptr<interfaces::Metric>>(
119 metricMocks);
120 }
121
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200122 void SetUp() override
123 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100124 sut = makeReport(defaultParams());
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200125 }
126
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100127 static interfaces::JsonStorage::FilePath to_file_path(std::string id)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100128 {
129 return interfaces::JsonStorage::FilePath(
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100130 std::to_string(std::hash<std::string>{}(id)));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100131 }
132
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200133 std::unique_ptr<Report> makeReport(const ReportParams& params)
134 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000135 initMetricMocks(params.metricParameters());
136
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200137 return std::make_unique<Report>(
138 DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100139 params.reportId(), params.reportName(), params.reportingType(),
140 params.reportActions(), params.interval(), params.appendLimit(),
141 params.reportUpdates(), *reportManagerMock, storageMock,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200142 utils::convContainer<std::shared_ptr<interfaces::Metric>>(
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200143 metricMocks),
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100144 *reportFactoryMock, params.enabled(), std::move(clockFakePtr),
145 params.readings());
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200146 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200147
148 template <class T>
149 static T getProperty(const std::string& path, const std::string& property)
150 {
Szymon Dompkee28aa532021-10-27 12:33:12 +0200151 return DbusEnvironment::getProperty<T>(path, Report::reportIfaceName,
152 property);
153 }
154
155 template <class T>
156 static boost::system::error_code setProperty(const std::string& path,
157 const std::string& property,
158 const T& newValue)
159 {
160 return DbusEnvironment::setProperty<T>(path, Report::reportIfaceName,
161 property, newValue);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100162 }
163
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200164 template <class T>
165 struct ChangePropertyParams
166 {
167 Matcher<T> valueBefore = _;
168 T newValue;
169 Matcher<boost::system::error_code> ec =
170 Eq(boost::system::errc::success);
171 Matcher<T> valueAfter = Eq(newValue);
172 };
173
174 template <class T>
175 static void changeProperty(const std::string& path,
176 const std::string& property,
177 ChangePropertyParams<T> p)
178 {
179 ASSERT_THAT(getProperty<T>(path, property), p.valueBefore);
180 ASSERT_THAT(setProperty<T>(path, property, p.newValue), p.ec);
181 EXPECT_THAT(getProperty<T>(path, property), p.valueAfter);
182 }
183
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100184 boost::system::error_code call(const std::string& path,
185 const std::string& interface,
186 const std::string& method)
187 {
188 std::promise<boost::system::error_code> methodPromise;
189 DbusEnvironment::getBus()->async_method_call(
190 [&methodPromise](boost::system::error_code ec) {
191 methodPromise.set_value(ec);
192 },
193 DbusEnvironment::serviceName(), path, interface, method);
194 return DbusEnvironment::waitForFuture(methodPromise.get_future());
195 }
196
197 boost::system::error_code update(const std::string& path)
198 {
199 return call(path, Report::reportIfaceName, "Update");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200200 }
201
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200202 boost::system::error_code deleteReport(const std::string& path)
203 {
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100204 return call(path, Report::deleteIfaceName, "Delete");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200205 }
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200206
207 static std::pair<std::string, std::vector<std::string>>
208 makeStateDetail(const std::string& detailType,
209 std::vector<std::string> detailArgs)
210 {
211 return make_pair(detailType, detailArgs);
212 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200213};
214
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100215TEST_F(TestReport, returnsId)
216{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100217 EXPECT_THAT(sut->getId(), Eq(defaultParams().reportId()));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100218}
219
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200220TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
221{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200222 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100223 Eq(defaultParams().enabled()));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200224 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100225 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100226 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100227 EXPECT_THAT(
228 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100229 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100230 return utils::enumToString(v);
231 })));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200232 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100233 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100234 ReportAction::emitsReadingsUpdate)));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200235 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "AppendLimit"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100236 Eq(defaultParams().appendLimit()));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100237 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100238 Eq(utils::enumToString(defaultParams().reportingType())));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200239 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportUpdates"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100240 Eq(utils::enumToString(defaultParams().reportUpdates())));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200241 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200242 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100243 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100244 ReportAction::logToMetricReportsCollection)));
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000245 EXPECT_THAT(getProperty<ReadingParameters>(
246 sut->getPath(), "ReadingParametersFutureVersion"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100247 Eq(toReadingParameters(defaultParams().metricParameters())));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100248 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100249 Eq(defaultParams().reportName()));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100250 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200251 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200252 IsEmpty());
253 EXPECT_THAT(
254 getProperty<ErrorMessagesDbusType>(sut->getPath(), "ErrorMessages"),
255 IsEmpty());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200256}
257
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200258TEST_F(TestReport, readingsAreInitialyEmpty)
259{
260 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
261 Eq(Readings{}));
262}
263
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100264TEST_F(TestReport, setReadingParametersWithNewParams)
265{
266 ReadingParameters newParams = toReadingParameters(
267 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
268 {LabeledSensorInfo{"Service",
269 "/xyz/openbmc_project/sensors/power/psu",
270 "NewMetadata123"}},
271 OperationType::avg,
272 "NewMetricId123",
273 CollectionTimeScope::startup,
274 CollectionDuration(250ms)}}});
275 auto metrics = getMetricsFromReadingParams(newParams);
276
277 EXPECT_CALL(*reportFactoryMock, updateMetrics(_, _, _))
278 .WillOnce(SetArgReferee<0>(metrics));
279 EXPECT_THAT(
280 setProperty(sut->getPath(), "ReadingParametersFutureVersion", newParams)
281 .value(),
282 Eq(boost::system::errc::success));
283 EXPECT_THAT(getProperty<ReadingParameters>(
284 sut->getPath(), "ReadingParametersFutureVersion"),
285 Eq(newParams));
286}
287
Szymon Dompke892f7c82022-10-12 09:54:22 +0200288TEST_F(TestReport, setReadingParametersWithNewParamsUpdatesSensorCount)
289{
290 auto report =
291 makeReport(ReportParams()
292 .appendLimit(std::numeric_limits<uint64_t>::max())
293 .reportId("DefaultAppendLimit"));
294
295 ReadingParameters newParams = toReadingParameters(
296 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
297 {LabeledSensorInfo{"Service",
298 "/xyz/openbmc_project/sensors/power/psu",
299 "NewMetadata123"}},
300 OperationType::avg,
301 "NewMetricId123",
302 CollectionTimeScope::startup,
303 CollectionDuration(250ms)}}});
304 auto metrics = getMetricsFromReadingParams(newParams);
305
306 EXPECT_CALL(*reportFactoryMock, updateMetrics(_, _, _))
307 .WillOnce(SetArgReferee<0>(metrics));
308 EXPECT_THAT(setProperty(report->getPath(), "ReadingParametersFutureVersion",
309 newParams)
310 .value(),
311 Eq(boost::system::errc::success));
312 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "AppendLimit"),
313 Eq(1ull));
314}
315
Szymon Dompke32305f12022-07-05 15:37:21 +0200316TEST_F(TestReport, setReadingParametersWithTooLongMetricId)
317{
318 const ReadingParameters currentValue =
319 toReadingParameters(defaultParams().metricParameters());
320
321 ReadingParameters newParams = toReadingParameters(
322 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
323 {LabeledSensorInfo{"Service",
324 "/xyz/openbmc_project/sensors/power/psu",
325 "NewMetadata123"}},
326 OperationType::avg,
327 utils::string_utils::getTooLongId(),
328 CollectionTimeScope::startup,
329 CollectionDuration(250ms)}}});
330
331 changeProperty<ReadingParameters>(
332 sut->getPath(), "ReadingParametersFutureVersion",
333 {.valueBefore = Eq(currentValue),
334 .newValue = newParams,
335 .ec = Eq(boost::system::errc::invalid_argument),
336 .valueAfter = Eq(currentValue)});
337}
338
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100339TEST_F(TestReport, setReportingTypeWithValidNewType)
340{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200341 changeProperty<std::string>(
342 sut->getPath(), "ReportingType",
343 {.valueBefore = Not(Eq(utils::enumToString(ReportingType::onRequest))),
344 .newValue = utils::enumToString(ReportingType::onRequest)});
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100345}
346
347TEST_F(TestReport, setReportingTypeWithInvalidType)
348{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200349 const std::string currentValue =
350 utils::enumToString(defaultParams().reportingType());
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100351
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200352 changeProperty<std::string>(
353 sut->getPath(), "ReportingType",
354 {.valueBefore = Eq(currentValue),
355 .newValue = "Periodic_ABC",
356 .ec = Eq(boost::system::errc::invalid_argument),
357 .valueAfter = Eq(currentValue)});
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100358}
359
360TEST_F(TestReport, setReportActionsWithValidNewActions)
361{
362 std::vector<std::string> newActions = {"EmitsReadingsUpdate"};
363 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100364 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100365 [](const auto v) { return utils::enumToString(v); });
366
367 EXPECT_THAT(newActions, Ne(currActions));
368 EXPECT_THAT(
369 setProperty(sut->getPath(), "ReportActions", newActions).value(),
370 Eq(boost::system::errc::success));
371 EXPECT_THAT(
372 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
373 UnorderedElementsAre("EmitsReadingsUpdate",
374 "LogToMetricReportsCollection"));
375}
376
377TEST_F(TestReport, setReportActionsWithValidUnsortedActions)
378{
379 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
380 "EmitsReadingsUpdate"};
381 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
382 "LogToMetricReportsCollection"};
383 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100384 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100385 [](const auto v) { return utils::enumToString(v); });
386
387 EXPECT_THAT(newActions, Ne(currActions));
388 EXPECT_THAT(
389 setProperty(sut->getPath(), "ReportActions", newActions).value(),
390 Eq(boost::system::errc::success));
391 EXPECT_THAT(
392 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
393 Eq(expectedActions));
394}
395
396TEST_F(TestReport, setReportActionsWithEmptyActions)
397{
398 std::vector<std::string> newActions = {};
399 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
400 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100401 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100402 [](const auto v) { return utils::enumToString(v); });
403
404 EXPECT_THAT(newActions, Ne(currActions));
405 EXPECT_THAT(
406 setProperty(sut->getPath(), "ReportActions", newActions).value(),
407 Eq(boost::system::errc::success));
408 EXPECT_THAT(
409 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
410 Eq(expectedActions));
411}
412
413TEST_F(TestReport, setReportActionsWithInvalidActions)
414{
415 std::vector<std::string> invalidActions = {"EmitsReadingsUpdate_1"};
416 EXPECT_THAT(
417 setProperty(sut->getPath(), "ReportActions", invalidActions).value(),
418 Eq(boost::system::errc::invalid_argument));
419 EXPECT_THAT(
420 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100421 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100422 return utils::enumToString(v);
423 })));
424}
425
426TEST_F(TestReport, createReportWithEmptyActions)
427{
428 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
429
430 sut = makeReport(ReportParams().reportId("TestId_1").reportActions({}));
431 EXPECT_THAT(
432 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
433 Eq(expectedActions));
434}
435
436TEST_F(TestReport, createReportWithValidUnsortedActions)
437{
438 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
439 "EmitsReadingsUpdate"};
440 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
441 "LogToMetricReportsCollection"};
442
443 sut = makeReport(
444 ReportParams()
445 .reportId("TestId_1")
446 .reportActions(utils::transform(newActions, [](const auto& action) {
447 return utils::toReportAction(action);
448 })));
449 EXPECT_THAT(
450 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
451 Eq(expectedActions));
452}
453
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200454TEST_F(TestReport, setEnabledWithNewValue)
455{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100456 bool newValue = !defaultParams().enabled();
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200457 EXPECT_THAT(setProperty(sut->getPath(), "Enabled", newValue).value(),
458 Eq(boost::system::errc::success));
459 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(newValue));
460}
461
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200462TEST_F(TestReport, setIntervalWithValidValue)
463{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200464 uint64_t newValue = ReportManager::minInterval.count() * 42;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200465 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200466 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200467 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
468 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200469}
470
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100471TEST_F(
472 TestReport,
473 settingIntervalWithInvalidValueDoesNotChangePropertyAndReturnsInvalidArgument)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200474{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200475 uint64_t newValue = ReportManager::minInterval.count() - 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200476 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100477 Eq(boost::system::errc::invalid_argument));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200478 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100479 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100480}
481
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200482TEST_F(TestReport, settingInvalidReportingTypeCreatesErrorMessage)
483{
484 auto report = makeReport(defaultParams()
485 .reportId("report2")
486 .reportingType(ReportingType::onRequest)
487 .interval(Milliseconds{0}));
488
489 EXPECT_THAT(
490 setProperty<std::string>(report->getPath(), "ReportingType", "Periodic")
491 .value(),
492 Eq(boost::system::errc::success));
493
494 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
495 Eq("Periodic"));
496 EXPECT_THAT(
497 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
498 UnorderedElementsAre(
499 ErrorMessageDbusType(
500 utils::enumToString(ErrorType::propertyConflict), "Interval"),
501 ErrorMessageDbusType(
502 utils::enumToString(ErrorType::propertyConflict),
503 "ReportingType")));
504}
505
506TEST_F(TestReport, settingValidReportingTypeRemovesErrors)
507{
508 auto report = makeReport(defaultParams()
509 .reportId("report2")
510 .reportingType(ReportingType::onRequest)
511 .interval(Milliseconds{0}));
512
513 EXPECT_THAT(
514 setProperty<std::string>(report->getPath(), "ReportingType", "Periodic")
515 .value(),
516 Eq(boost::system::errc::success));
517 EXPECT_THAT(setProperty<std::string>(report->getPath(), "ReportingType",
518 "OnRequest")
519 .value(),
520 Eq(boost::system::errc::success));
521
522 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
523 Eq("OnRequest"));
524 EXPECT_THAT(
525 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
526 IsEmpty());
527}
528
529TEST_F(TestReport, settingInvalidIntervalDisablesReport)
530{
531 auto report = makeReport(defaultParams()
532 .reportId("report2")
533 .reportingType(ReportingType::periodic)
534 .interval(ReportManager::minInterval));
535
536 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval", 0).value(),
537 Eq(boost::system::errc::success));
538
539 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"), Eq(0u));
540 EXPECT_THAT(
541 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
542 UnorderedElementsAre(
543 ErrorMessageDbusType(
544 utils::enumToString(ErrorType::propertyConflict), "Interval"),
545 ErrorMessageDbusType(
546 utils::enumToString(ErrorType::propertyConflict),
547 "ReportingType")));
548}
549
550TEST_F(TestReport, settingValidIntervalEnablesReport)
551{
552 auto report = makeReport(defaultParams()
553 .reportId("report2")
554 .reportingType(ReportingType::periodic)
555 .interval(ReportManager::minInterval));
556
557 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval", 0).value(),
558 Eq(boost::system::errc::success));
559 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval",
560 ReportManager::minInterval.count())
561 .value(),
562 Eq(boost::system::errc::success));
563
564 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"),
565 Eq(ReportManager::minInterval.count()));
566 EXPECT_THAT(
567 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
568 IsEmpty());
569}
570
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200571TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
572{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100573 EXPECT_THAT(
574 setProperty(sut->getPath(), "EmitsReadingsUpdate", true).value(),
575 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200576 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100577 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100578 ReportAction::emitsReadingsUpdate)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200579}
580
581TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
582{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100583 EXPECT_THAT(
584 setProperty(sut->getPath(), "LogToMetricReportsCollection", true)
585 .value(),
586 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200587 EXPECT_THAT(
588 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100589 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100590 ReportAction::logToMetricReportsCollection)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200591}
592
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100593TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
594{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100595 EXPECT_CALL(storageMock, store(_, _)).Times(0);
596 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
597 .Times(AtLeast(1));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100598
599 bool persistency = false;
600 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
601 Eq(boost::system::errc::success));
602 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
603 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200604}
605
606TEST_F(TestReport, deleteReport)
607{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200608 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
609 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200610 EXPECT_THAT(ec, Eq(boost::system::errc::success));
611}
612
613TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
614{
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200615 auto ec =
616 deleteReport(utils::constants::reportDirPath.str + "NonExisting"s);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200617 EXPECT_THAT(ec.value(), Eq(EBADR));
618}
619
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100620TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
621{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100622 EXPECT_CALL(storageMock, store(_, _)).Times(0);
623 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
624 .Times(AtLeast(1));
625
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100626 auto ec = deleteReport(sut->getPath());
627 EXPECT_THAT(ec, Eq(boost::system::errc::success));
628}
629
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100630TEST_F(TestReport, updatesTriggerIdWhenTriggerIsAdded)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100631{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100632 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100633
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100634 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100635 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100636 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100637 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100638 messanger.send(messages::TriggerPresenceChangedInd{
639 messages::Presence::Exist, "trigger2", {"someOtherReport"}});
640 messanger.send(messages::TriggerPresenceChangedInd{
641 messages::Presence::Exist,
642 "trigger3",
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100643 {"someOtherReport", defaultParams().reportId()}});
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100644
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100645 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200646 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
647 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
648 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100649}
650
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100651TEST_F(TestReport, updatesTriggerIdWhenTriggerIsRemoved)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100652{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100653 utils::Messanger messanger(DbusEnvironment::getIoc());
654
655 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100656 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100657 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100658 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100659 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100660 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100661
662 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100663 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100664 messanger.send(messages::TriggerPresenceChangedInd{
665 messages::Presence::Removed, "trigger2", {}});
666 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100667 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100668
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100669 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200670 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
671 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100672}
673
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100674TEST_F(TestReport, updatesTriggerIdWhenTriggerIsModified)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100675{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100676 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100677
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100678 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100679 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100680 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100681 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100682 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100683 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100684
685 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100686 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100687 messanger.send(messages::TriggerPresenceChangedInd{
688 messages::Presence::Exist, "trigger2", {}});
689 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100690 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100691
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100692 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200693 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
694 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
695 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100696}
697
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100698class TestReportStore :
699 public TestReport,
700 public WithParamInterface<std::pair<std::string, nlohmann::json>>
701{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100702 void SetUp() override
703 {}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100704};
705
706INSTANTIATE_TEST_SUITE_P(
707 _, TestReportStore,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100708 Values(
709 std::make_pair("Enabled"s, nlohmann::json(defaultParams().enabled())),
710 std::make_pair("Version"s, nlohmann::json(6)),
711 std::make_pair("Id"s, nlohmann::json(defaultParams().reportId())),
712 std::make_pair("Name"s, nlohmann::json(defaultParams().reportName())),
713 std::make_pair("ReportingType",
714 nlohmann::json(defaultParams().reportingType())),
715 std::make_pair("ReportActions", nlohmann::json(utils::transform(
716 defaultParams().reportActions(),
717 [](const auto v) {
718 return utils::toUnderlying(v);
719 }))),
720 std::make_pair("Interval",
721 nlohmann::json(defaultParams().interval().count())),
722 std::make_pair("AppendLimit",
723 nlohmann::json(ReportParams().appendLimit())),
724 std::make_pair(
725 "ReadingParameters",
726 nlohmann::json(
727 {{{tstring::SensorPath::str(),
728 {{{tstring::Service::str(), "Service"},
729 {tstring::Path::str(),
730 "/xyz/openbmc_project/sensors/power/p1"},
731 {tstring::Metadata::str(), "metadata1"}}}},
732 {tstring::OperationType::str(), OperationType::avg},
733 {tstring::Id::str(), "MetricId1"},
734 {tstring::CollectionTimeScope::str(),
735 CollectionTimeScope::point},
736 {tstring::CollectionDuration::str(), 0}},
737 {{tstring::SensorPath::str(),
738 {{{tstring::Service::str(), "Service"},
739 {tstring::Path::str(),
740 "/xyz/openbmc_project/sensors/power/p2"},
741 {tstring::Metadata::str(), "metadata2"}}}},
742 {tstring::OperationType::str(), OperationType::avg},
743 {tstring::Id::str(), "MetricId2"},
744 {tstring::CollectionTimeScope::str(),
745 CollectionTimeScope::point},
746 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100747
748TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
749{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100750 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100751
752 {
753 InSequence seq;
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100754 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100755 EXPECT_CALL(checkPoint, Call());
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100756 EXPECT_CALL(storageMock, store(to_file_path(sut->getId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100757 }
758
759 setProperty(sut->getPath(), "Persistency", false);
760 checkPoint.Call();
761 setProperty(sut->getPath(), "Persistency", true);
762
763 const auto& [key, value] = GetParam();
764
765 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
766}
767
768TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
769{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100770 EXPECT_CALL(storageMock,
771 store(to_file_path(defaultParams().reportId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100772
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100773 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100774
775 const auto& [key, value] = GetParam();
776
777 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
778}
779
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200780class TestReportValidNames :
781 public TestReport,
782 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200783{
784 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200785 void SetUp() override
786 {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200787};
788
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200789INSTANTIATE_TEST_SUITE_P(
790 ValidNames, TestReportValidNames,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100791 Values(defaultParams().reportName("Valid_1"),
792 defaultParams().reportName("Valid_1/Valid_2"),
793 defaultParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200794
795TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
796{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200797 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200798}
799
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100800class TestReportInvalidIds :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200801 public TestReport,
802 public WithParamInterface<ReportParams>
803{
804 public:
805 void SetUp() override
806 {}
807};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200808
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100809INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidIds,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100810 Values(defaultParams().reportId("/"),
811 defaultParams().reportId("/Invalid"),
812 defaultParams().reportId("Invalid/"),
813 defaultParams().reportId("Invalid/Invalid/"),
814 defaultParams().reportId("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200815
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100816TEST_P(TestReportInvalidIds, failsToCreateReportWithInvalidName)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100817{
818 EXPECT_CALL(storageMock, store).Times(0);
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100819
820 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100821}
822
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200823class TestReportAllReportTypes :
824 public TestReport,
825 public WithParamInterface<ReportParams>
826{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200827 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200828 void SetUp() override
829 {
830 sut = makeReport(GetParam());
831 }
832};
833
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100834INSTANTIATE_TEST_SUITE_P(
835 _, TestReportAllReportTypes,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100836 Values(defaultParams().reportingType(ReportingType::onRequest),
837 defaultParams().reportingType(ReportingType::onChange),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200838 defaultParams()
839 .reportingType(ReportingType::periodic)
840 .interval(ReportManager::minInterval)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200841
842TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
843{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100844 EXPECT_THAT(utils::toReportingType(
845 getProperty<std::string>(sut->getPath(), "ReportingType")),
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200846 Eq(GetParam().reportingType()));
847}
848
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100849TEST_P(TestReportAllReportTypes, readingsAreUpdated)
850{
851 clockFake.system.advance(10ms);
852
853 messanger.send(messages::UpdateReportInd{{sut->getId()}});
854 const auto [timestamp, readings] =
855 getProperty<Readings>(sut->getPath(), "Readings");
856
857 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
858}
859
860TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIsDisabled)
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200861{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100862 clockFake.system.advance(10ms);
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200863
864 setProperty(sut->getPath(), "Enabled", false);
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100865 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200866 const auto [timestamp, readings] =
867 getProperty<Readings>(sut->getPath(), "Readings");
868
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100869 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200870}
871
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100872TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIdDiffers)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100873{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100874 clockFake.system.advance(10ms);
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100875
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100876 messanger.send(messages::UpdateReportInd{{sut->getId() + "x"s}});
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100877 const auto [timestamp, readings] =
878 getProperty<Readings>(sut->getPath(), "Readings");
879
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100880 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100881}
882
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100883class TestReportOnRequestType : public TestReport
884{
885 void SetUp() override
886 {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100887 sut =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100888 makeReport(defaultParams().reportingType(ReportingType::onRequest));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100889 }
890};
891
892TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
893{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100894 clockFake.system.advance(10ms);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100895
896 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
897
898 const auto [timestamp, readings] =
899 getProperty<Readings>(sut->getPath(), "Readings");
900
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100901 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100902}
903
904TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
905{
906 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
907
908 const auto [timestamp, readings] =
909 getProperty<Readings>(sut->getPath(), "Readings");
910
911 EXPECT_THAT(readings,
912 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000913 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100914}
915
916class TestReportNonOnRequestType :
917 public TestReport,
918 public WithParamInterface<ReportParams>
919{
920 void SetUp() override
921 {
922 sut = makeReport(GetParam());
923 }
924};
925
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100926INSTANTIATE_TEST_SUITE_P(
927 _, TestReportNonOnRequestType,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100928 Values(defaultParams().reportingType(ReportingType::periodic),
929 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100930
931TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
932{
933 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
934
935 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
936 Eq(Readings{}));
937}
938
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200939class TestReportNonPeriodicReport :
940 public TestReport,
941 public WithParamInterface<ReportParams>
942{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200943 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200944 void SetUp() override
945 {
946 sut = makeReport(GetParam());
947 }
948};
949
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100950INSTANTIATE_TEST_SUITE_P(
951 _, TestReportNonPeriodicReport,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100952 Values(defaultParams().reportingType(ReportingType::onRequest),
953 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200954
955TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
956{
957 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
958
959 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
960 Eq(Readings{}));
961}
962
963class TestReportPeriodicReport : public TestReport
964{
965 void SetUp() override
966 {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200967 sut = makeReport(defaultParams()
968 .reportingType(ReportingType::periodic)
969 .interval(ReportManager::minInterval));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200970 }
971};
972
973TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
974{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100975 clockFake.system.advance(10ms);
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200976 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
977
978 const auto [timestamp, readings] =
979 getProperty<Readings>(sut->getPath(), "Readings");
980
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100981 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200982}
983
984TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
985{
986 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
987
988 const auto [timestamp, readings] =
989 getProperty<Readings>(sut->getPath(), "Readings");
990
991 EXPECT_THAT(readings,
992 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000993 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200994}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100995
Szymon Dompke3eb56862021-09-20 15:32:04 +0200996struct ReportUpdatesReportParams
997{
998 ReportParams reportParams;
999 std::vector<ReadingData> expectedReadings;
1000 bool expectedEnabled;
1001};
1002
1003class TestReportWithReportUpdatesAndLimit :
1004 public TestReport,
1005 public WithParamInterface<ReportUpdatesReportParams>
1006{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001007 public:
Szymon Dompke3eb56862021-09-20 15:32:04 +02001008 void SetUp() override
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001009 {}
1010
1011 void changeReport(ReportingType rt, Milliseconds interval)
Szymon Dompke3eb56862021-09-20 15:32:04 +02001012 {
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001013 setProperty<std::string>(sut->getPath(), "ReportingType",
1014 utils::enumToString(rt));
1015 setProperty<uint64_t>(sut->getPath(), "Interval", interval.count());
1016 }
1017
1018 auto readings()
1019 {
1020 auto [timestamp, readings] =
1021 getProperty<Readings>(sut->getPath(), "Readings");
1022 return readings;
1023 }
1024
1025 void updateReportFourTimes()
1026 {
1027 for (int i = 0; i < 4; i++)
1028 {
1029 messanger.send(messages::UpdateReportInd{{sut->getId()}});
1030 }
Szymon Dompke3eb56862021-09-20 15:32:04 +02001031 }
1032};
1033
1034INSTANTIATE_TEST_SUITE_P(
1035 _, TestReportWithReportUpdatesAndLimit,
1036 Values(
1037 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001038 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001039 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1040 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001041 std::vector<ReadingData>{{std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1042 std::make_tuple("a"s, "b"s, 17.1, 114u),
1043 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1044 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1045 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
1046 true},
1047 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001048 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001049 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1050 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001051 std::vector<ReadingData>{
1052 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1053 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1054 std::make_tuple("a"s, "b"s, 17.1, 114u),
1055 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1056 true},
1057 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001058 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001059 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1060 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001061 std::vector<ReadingData>{}, true},
1062 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001063 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001064 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1065 .appendLimit(10),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001066 std::vector<ReadingData>{
1067 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1068 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1069 std::make_tuple("a"s, "b"s, 17.1, 114u),
1070 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1071 std::make_tuple("a"s, "b"s, 17.1, 114u),
1072 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1073 std::make_tuple("a"s, "b"s, 17.1, 114u),
1074 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1075 true},
1076 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001077 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001078 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1079 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001080 std::vector<ReadingData>{{std::make_tuple("a"s, "b"s, 17.1, 114u),
1081 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1082 std::make_tuple("a"s, "b"s, 17.1, 114u),
1083 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1084 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
1085 false},
1086 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001087 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001088 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1089 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001090 std::vector<ReadingData>{
1091 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1092 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1093 std::make_tuple("a"s, "b"s, 17.1, 114u),
1094 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1095 false},
1096 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001097 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001098 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1099 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001100 std::vector<ReadingData>{}, false},
1101 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001102 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001103 .reportUpdates(ReportUpdates::overwrite)
1104 .appendLimit(500),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001105 std::vector<ReadingData>{
1106 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1107 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1108 true},
1109 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001110 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001111 .reportUpdates(ReportUpdates::overwrite)
1112 .appendLimit(1),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001113 std::vector<ReadingData>{
1114 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1115 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1116 true},
1117 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001118 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001119 .reportUpdates(ReportUpdates::overwrite)
1120 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001121 std::vector<ReadingData>{
1122 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1123 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001124 true},
1125 ReportUpdatesReportParams{
1126 defaultParams()
1127 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1128 .appendLimit(std::numeric_limits<uint64_t>::max()),
1129 std::vector<ReadingData>{
1130 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1131 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1132 false}));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001133
1134TEST_P(TestReportWithReportUpdatesAndLimit,
1135 readingsAreUpdatedAfterIntervalExpires)
1136{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001137 sut = makeReport(ReportParams(GetParam().reportParams)
1138 .reportingType(ReportingType::periodic)
1139 .interval(std::chrono::hours(1000)));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001140
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001141 updateReportFourTimes();
Szymon Dompke3eb56862021-09-20 15:32:04 +02001142
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001143 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1144 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1145 Eq(GetParam().expectedEnabled));
1146}
1147
1148TEST_P(TestReportWithReportUpdatesAndLimit,
1149 appendLimitIsRespectedAfterChangingToPeriodic)
1150{
1151 sut = makeReport(ReportParams(GetParam().reportParams)
1152 .reportingType(ReportingType::onRequest)
1153 .interval(std::chrono::hours(0)));
1154
1155 changeReport(ReportingType::periodic, std::chrono::hours(1000));
1156 updateReportFourTimes();
1157
1158 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1159 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1160 Eq(GetParam().expectedEnabled));
1161}
1162
1163TEST_P(TestReportWithReportUpdatesAndLimit,
1164 appendLimitIsIgnoredAfterChangingToOnRequest)
1165{
1166 sut = makeReport(ReportParams(GetParam().reportParams)
1167 .reportingType(ReportingType::periodic)
1168 .interval(std::chrono::hours(1000)));
1169
1170 changeReport(ReportingType::onRequest, Milliseconds{0});
1171 updateReportFourTimes();
1172
1173 EXPECT_THAT(readings(), SizeIs(2u));
1174 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(true));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001175}
1176
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001177class TestReportInitialization : public TestReport
1178{
1179 public:
1180 void SetUp() override
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001181 {
1182 initMetricMocks(defaultParams().metricParameters());
1183 }
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001184
Patrick Williams39cc6ac2022-07-22 19:26:56 -05001185 void monitorProc(sdbusplus::message_t& msg)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001186 {
1187 std::string iface;
1188 std::vector<std::pair<std::string, std::variant<Readings>>>
1189 changed_properties;
1190 std::vector<std::string> invalidated_properties;
1191
1192 msg.read(iface, changed_properties, invalidated_properties);
1193
1194 if (iface == Report::reportIfaceName)
1195 {
1196 for (const auto& [name, value] : changed_properties)
1197 {
1198 if (name == "Readings")
1199 {
1200 readingsUpdated.Call();
1201 }
1202 }
1203 }
1204 }
1205
1206 void makeMonitor()
1207 {
Patrick Williams3a62ee12021-12-03 10:13:25 -06001208 monitor = std::make_unique<sdbusplus::bus::match_t>(
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001209 *DbusEnvironment::getBus(),
1210 sdbusplus::bus::match::rules::propertiesChanged(
1211 sut->getPath(), Report::reportIfaceName),
1212 [this](auto& msg) { monitorProc(msg); });
1213 }
1214
Patrick Williams3a62ee12021-12-03 10:13:25 -06001215 std::unique_ptr<sdbusplus::bus::match_t> monitor;
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001216 MockFunction<void()> readingsUpdated;
1217};
1218
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001219TEST_F(TestReportInitialization,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001220 registersForMetricUpdatesWhenOnChangeReportCreated)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001221{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001222 std::vector<const interfaces::MetricListener*> args;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001223 for (auto& metric : metricMocks)
1224 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001225 EXPECT_CALL(*metric, registerForUpdates(_))
1226 .WillOnce(Invoke([&args](const interfaces::MetricListener& report) {
1227 args.emplace_back(&report);
1228 }));
1229 ;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001230 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001231
1232 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1233
1234 EXPECT_THAT(args, SizeIs(metricMocks.size()));
1235 for (const auto* reportPtr : args)
1236 {
1237 EXPECT_THAT(reportPtr, Eq(sut.get()));
1238 }
1239}
1240
1241TEST_F(TestReportInitialization,
1242 deregistersForMetricUpdatesWhenOnChangeReportDestroyed)
1243{
1244 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1245
1246 for (auto& metric : metricMocks)
1247 {
1248 EXPECT_CALL(*metric,
1249 unregisterFromUpdates(Ref(
1250 static_cast<interfaces::MetricListener&>(*sut.get()))));
1251 }
1252
1253 sut = nullptr;
1254}
1255
1256TEST_F(TestReportInitialization,
1257 metricsAreInitializedWhenEnabledReportConstructed)
1258{
1259 for (auto& metric : metricMocks)
1260 {
1261 EXPECT_CALL(*metric, initialize());
1262 }
1263 sut = makeReport(defaultParams().enabled(true));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001264}
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001265
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001266TEST_F(TestReportInitialization,
1267 metricsAreNotInitializedWhenDisabledReportConstructed)
1268{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001269 for (auto& metric : metricMocks)
1270 {
1271 EXPECT_CALL(*metric, initialize()).Times(0);
1272 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001273 sut = makeReport(defaultParams().enabled(false));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001274}
1275
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001276TEST_F(TestReportInitialization,
1277 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001278{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001279 EXPECT_CALL(readingsUpdated, Call())
1280 .WillOnce(
1281 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
1282
1283 const auto elapsed = DbusEnvironment::measureTime([this] {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001284 sut = makeReport(defaultParams()
1285 .reportingType(ReportingType::periodic)
1286 .reportActions({ReportAction::emitsReadingsUpdate})
1287 .interval(ReportManager::minInterval));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001288 makeMonitor();
1289 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
1290 });
1291
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001292 EXPECT_THAT(elapsed, AllOf(Ge(ReportManager::minInterval),
1293 Lt(ReportManager::minInterval * 2)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001294}
1295
1296TEST_F(TestReportInitialization,
1297 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
1298{
1299 EXPECT_CALL(readingsUpdated, Call()).Times(0);
1300
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001301 sut = makeReport(defaultParams()
1302 .reportingType(ReportingType::periodic)
1303 .reportActions({}));
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001304 makeMonitor();
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001305 DbusEnvironment::sleepFor(defaultParams().interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001306}
Szymon Dompke3eb56862021-09-20 15:32:04 +02001307
1308TEST_F(TestReportInitialization, appendLimitDeducedProperly)
1309{
1310 sut = makeReport(
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001311 defaultParams().appendLimit(std::numeric_limits<uint64_t>::max()));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001312 auto appendLimit = getProperty<uint64_t>(sut->getPath(), "AppendLimit");
1313 EXPECT_EQ(appendLimit, 2ull);
1314}
Krzysztof Grobelnye6c417c2022-02-02 17:25:53 +01001315
1316TEST_F(TestReportInitialization, appendLimitSetToUintMaxIsStoredCorrectly)
1317{
Krzysztof Grobelnye6c417c2022-02-02 17:25:53 +01001318 sut = makeReport(
1319 ReportParams().appendLimit(std::numeric_limits<uint64_t>::max()));
1320
1321 ASSERT_THAT(storedConfiguration.at("AppendLimit"),
1322 Eq(std::numeric_limits<uint64_t>::max()));
1323}
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001324
1325TEST_F(TestReportInitialization, triggerIdsPropertyIsInitialzed)
1326{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001327 for (const auto& triggerId : {"trigger1", "trigger2"})
1328 {
1329 messanger.on_receive<messages::CollectTriggerIdReq>(
Szymon Dompkee0ed5082022-05-20 10:54:25 +02001330 [this, triggerId](const auto& msg) {
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001331 messanger.send(messages::CollectTriggerIdResp{triggerId});
1332 });
1333 }
1334
1335 sut = makeReport(ReportParams());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001336
1337 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +02001338 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
1339 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
1340 utils::constants::triggerDirPath / "trigger2"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001341}
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001342
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +01001343TEST_F(TestReportInitialization,
1344 metricValuesAreNotStoredForReportUpdatesDifferentThanAppendStopsWhenFull)
1345{
1346 sut = makeReport(ReportParams()
1347 .reportingType(ReportingType::periodic)
1348 .interval(1h)
1349 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1350 .readings(Readings{{}, {{}}}));
1351
1352 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1353 Eq(storedConfiguration.end()));
1354}
1355
1356TEST_F(TestReportInitialization, metricValuesAreNotStoredForOnRequestReport)
1357{
1358 sut = makeReport(ReportParams()
1359 .reportingType(ReportingType::onRequest)
1360 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1361 .readings(Readings{{}, {{}}}));
1362
1363 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1364 Eq(storedConfiguration.end()));
1365}
1366
1367TEST_F(TestReportInitialization,
1368 metricValuesAreStoredForNonOnRequestReportWithAppendStopsWhenFull)
1369{
1370 const auto readings = Readings{{}, {{}}};
1371
1372 sut = makeReport(ReportParams()
1373 .reportingType(ReportingType::periodic)
1374 .interval(1h)
1375 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1376 .readings(readings));
1377
1378 ASSERT_THAT(storedConfiguration.at("MetricValues").get<LabeledReadings>(),
1379 Eq(utils::toLabeledReadings(readings)));
1380}
1381
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001382class TestReportInitializationOnChangeReport : public TestReportInitialization
1383{
1384 public:
1385 void SetUp() override
1386 {
1387 initMetricMocks(params.metricParameters());
1388 }
1389
1390 ReportParams params = defaultOnChangeParams();
1391};
1392
1393TEST_F(TestReportInitializationOnChangeReport,
1394 doesntUpdateReadingsWhenNotRequired)
1395{
1396 EXPECT_CALL(*metricMocks[0], updateReadings(_)).Times(0);
1397
1398 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(false));
1399
1400 sut = makeReport(params);
1401
1402 DbusEnvironment::sleepFor(500ms);
1403}
1404
1405TEST_F(TestReportInitializationOnChangeReport, updatesReadingsWhenRequired)
1406{
1407 EXPECT_CALL(*metricMocks[0], updateReadings(_))
1408 .WillOnce(Return())
1409 .WillOnce(
1410 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")))
1411 .WillRepeatedly(Return());
1412
1413 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(true));
1414
1415 sut = makeReport(params);
1416
1417 DbusEnvironment::waitForFuture("readingsUpdated");
1418}