blob: 579c714b3bad92f943d6be7b664224d922717568 [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}}};
88 readings.resize(metricParameters.size());
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000089
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000090 for (size_t i = 0; i < metricParameters.size(); ++i)
91 {
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +010092 ON_CALL(*metricMocks[i], getUpdatedReadings())
93 .WillByDefault(ReturnRefOfCopy(std::vector({readings[i]})));
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000094 ON_CALL(*metricMocks[i], dumpConfiguration())
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000095 .WillByDefault(Return(metricParameters[i]));
Wludzik, Jozefe2362792020-10-27 17:23:55 +010096 }
97 }
98
Szymon Dompkefdb06a12022-02-11 11:04:44 +010099 std::vector<std::shared_ptr<interfaces::Metric>>
100 getMetricsFromReadingParams(const ReadingParameters& params)
101 {
102 const auto metricParameters =
103 reportFactoryMock->convertMetricParams(params);
104 std::vector<std::shared_ptr<MetricMock>> metricMocks;
105
106 for (size_t i = 0; i < metricParameters.size(); ++i)
107 {
108 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>());
109 ON_CALL(*metricMocks[i], dumpConfiguration())
110 .WillByDefault(Return(metricParameters[i]));
111 }
112
113 return utils::convContainer<std::shared_ptr<interfaces::Metric>>(
114 metricMocks);
115 }
116
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200117 void SetUp() override
118 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100119 sut = makeReport(defaultParams());
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200120 }
121
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100122 static interfaces::JsonStorage::FilePath to_file_path(std::string id)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100123 {
124 return interfaces::JsonStorage::FilePath(
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100125 std::to_string(std::hash<std::string>{}(id)));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100126 }
127
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200128 std::unique_ptr<Report> makeReport(const ReportParams& params)
129 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000130 initMetricMocks(params.metricParameters());
131
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200132 return std::make_unique<Report>(
133 DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100134 params.reportId(), params.reportName(), params.reportingType(),
135 params.reportActions(), params.interval(), params.appendLimit(),
136 params.reportUpdates(), *reportManagerMock, storageMock,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200137 utils::convContainer<std::shared_ptr<interfaces::Metric>>(
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200138 metricMocks),
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100139 *reportFactoryMock, params.enabled(), std::move(clockFakePtr),
140 params.readings());
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200141 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200142
143 template <class T>
144 static T getProperty(const std::string& path, const std::string& property)
145 {
Szymon Dompkee28aa532021-10-27 12:33:12 +0200146 return DbusEnvironment::getProperty<T>(path, Report::reportIfaceName,
147 property);
148 }
149
150 template <class T>
151 static boost::system::error_code setProperty(const std::string& path,
152 const std::string& property,
153 const T& newValue)
154 {
155 return DbusEnvironment::setProperty<T>(path, Report::reportIfaceName,
156 property, newValue);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100157 }
158
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200159 template <class T>
160 struct ChangePropertyParams
161 {
162 Matcher<T> valueBefore = _;
163 T newValue;
164 Matcher<boost::system::error_code> ec =
165 Eq(boost::system::errc::success);
166 Matcher<T> valueAfter = Eq(newValue);
167 };
168
169 template <class T>
170 static void changeProperty(const std::string& path,
171 const std::string& property,
172 ChangePropertyParams<T> p)
173 {
174 ASSERT_THAT(getProperty<T>(path, property), p.valueBefore);
175 ASSERT_THAT(setProperty<T>(path, property, p.newValue), p.ec);
176 EXPECT_THAT(getProperty<T>(path, property), p.valueAfter);
177 }
178
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100179 boost::system::error_code call(const std::string& path,
180 const std::string& interface,
181 const std::string& method)
182 {
183 std::promise<boost::system::error_code> methodPromise;
184 DbusEnvironment::getBus()->async_method_call(
185 [&methodPromise](boost::system::error_code ec) {
186 methodPromise.set_value(ec);
187 },
188 DbusEnvironment::serviceName(), path, interface, method);
189 return DbusEnvironment::waitForFuture(methodPromise.get_future());
190 }
191
192 boost::system::error_code update(const std::string& path)
193 {
194 return call(path, Report::reportIfaceName, "Update");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200195 }
196
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200197 boost::system::error_code deleteReport(const std::string& path)
198 {
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100199 return call(path, Report::deleteIfaceName, "Delete");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200200 }
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200201
202 static std::pair<std::string, std::vector<std::string>>
203 makeStateDetail(const std::string& detailType,
204 std::vector<std::string> detailArgs)
205 {
206 return make_pair(detailType, detailArgs);
207 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200208};
209
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100210TEST_F(TestReport, returnsId)
211{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100212 EXPECT_THAT(sut->getId(), Eq(defaultParams().reportId()));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100213}
214
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200215TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
216{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200217 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100218 Eq(defaultParams().enabled()));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200219 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100220 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100221 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100222 EXPECT_THAT(
223 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100224 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100225 return utils::enumToString(v);
226 })));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200227 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100228 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100229 ReportAction::emitsReadingsUpdate)));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200230 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "AppendLimit"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100231 Eq(defaultParams().appendLimit()));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100232 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100233 Eq(utils::enumToString(defaultParams().reportingType())));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200234 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportUpdates"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100235 Eq(utils::enumToString(defaultParams().reportUpdates())));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200236 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200237 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100238 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100239 ReportAction::logToMetricReportsCollection)));
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000240 EXPECT_THAT(getProperty<ReadingParameters>(
241 sut->getPath(), "ReadingParametersFutureVersion"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100242 Eq(toReadingParameters(defaultParams().metricParameters())));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100243 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100244 Eq(defaultParams().reportName()));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100245 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200246 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200247 IsEmpty());
248 EXPECT_THAT(
249 getProperty<ErrorMessagesDbusType>(sut->getPath(), "ErrorMessages"),
250 IsEmpty());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200251}
252
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200253TEST_F(TestReport, readingsAreInitialyEmpty)
254{
255 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
256 Eq(Readings{}));
257}
258
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100259TEST_F(TestReport, setReadingParametersWithNewParams)
260{
261 ReadingParameters newParams = toReadingParameters(
262 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
263 {LabeledSensorInfo{"Service",
264 "/xyz/openbmc_project/sensors/power/psu",
265 "NewMetadata123"}},
266 OperationType::avg,
267 "NewMetricId123",
268 CollectionTimeScope::startup,
269 CollectionDuration(250ms)}}});
270 auto metrics = getMetricsFromReadingParams(newParams);
271
272 EXPECT_CALL(*reportFactoryMock, updateMetrics(_, _, _))
273 .WillOnce(SetArgReferee<0>(metrics));
274 EXPECT_THAT(
275 setProperty(sut->getPath(), "ReadingParametersFutureVersion", newParams)
276 .value(),
277 Eq(boost::system::errc::success));
278 EXPECT_THAT(getProperty<ReadingParameters>(
279 sut->getPath(), "ReadingParametersFutureVersion"),
280 Eq(newParams));
281}
282
Szymon Dompke32305f12022-07-05 15:37:21 +0200283TEST_F(TestReport, setReadingParametersWithTooLongMetricId)
284{
285 const ReadingParameters currentValue =
286 toReadingParameters(defaultParams().metricParameters());
287
288 ReadingParameters newParams = toReadingParameters(
289 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
290 {LabeledSensorInfo{"Service",
291 "/xyz/openbmc_project/sensors/power/psu",
292 "NewMetadata123"}},
293 OperationType::avg,
294 utils::string_utils::getTooLongId(),
295 CollectionTimeScope::startup,
296 CollectionDuration(250ms)}}});
297
298 changeProperty<ReadingParameters>(
299 sut->getPath(), "ReadingParametersFutureVersion",
300 {.valueBefore = Eq(currentValue),
301 .newValue = newParams,
302 .ec = Eq(boost::system::errc::invalid_argument),
303 .valueAfter = Eq(currentValue)});
304}
305
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100306TEST_F(TestReport, setReportingTypeWithValidNewType)
307{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200308 changeProperty<std::string>(
309 sut->getPath(), "ReportingType",
310 {.valueBefore = Not(Eq(utils::enumToString(ReportingType::onRequest))),
311 .newValue = utils::enumToString(ReportingType::onRequest)});
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100312}
313
314TEST_F(TestReport, setReportingTypeWithInvalidType)
315{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200316 const std::string currentValue =
317 utils::enumToString(defaultParams().reportingType());
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100318
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200319 changeProperty<std::string>(
320 sut->getPath(), "ReportingType",
321 {.valueBefore = Eq(currentValue),
322 .newValue = "Periodic_ABC",
323 .ec = Eq(boost::system::errc::invalid_argument),
324 .valueAfter = Eq(currentValue)});
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100325}
326
327TEST_F(TestReport, setReportActionsWithValidNewActions)
328{
329 std::vector<std::string> newActions = {"EmitsReadingsUpdate"};
330 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100331 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100332 [](const auto v) { return utils::enumToString(v); });
333
334 EXPECT_THAT(newActions, Ne(currActions));
335 EXPECT_THAT(
336 setProperty(sut->getPath(), "ReportActions", newActions).value(),
337 Eq(boost::system::errc::success));
338 EXPECT_THAT(
339 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
340 UnorderedElementsAre("EmitsReadingsUpdate",
341 "LogToMetricReportsCollection"));
342}
343
344TEST_F(TestReport, setReportActionsWithValidUnsortedActions)
345{
346 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
347 "EmitsReadingsUpdate"};
348 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
349 "LogToMetricReportsCollection"};
350 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100351 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100352 [](const auto v) { return utils::enumToString(v); });
353
354 EXPECT_THAT(newActions, Ne(currActions));
355 EXPECT_THAT(
356 setProperty(sut->getPath(), "ReportActions", newActions).value(),
357 Eq(boost::system::errc::success));
358 EXPECT_THAT(
359 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
360 Eq(expectedActions));
361}
362
363TEST_F(TestReport, setReportActionsWithEmptyActions)
364{
365 std::vector<std::string> newActions = {};
366 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
367 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100368 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100369 [](const auto v) { return utils::enumToString(v); });
370
371 EXPECT_THAT(newActions, Ne(currActions));
372 EXPECT_THAT(
373 setProperty(sut->getPath(), "ReportActions", newActions).value(),
374 Eq(boost::system::errc::success));
375 EXPECT_THAT(
376 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
377 Eq(expectedActions));
378}
379
380TEST_F(TestReport, setReportActionsWithInvalidActions)
381{
382 std::vector<std::string> invalidActions = {"EmitsReadingsUpdate_1"};
383 EXPECT_THAT(
384 setProperty(sut->getPath(), "ReportActions", invalidActions).value(),
385 Eq(boost::system::errc::invalid_argument));
386 EXPECT_THAT(
387 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100388 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100389 return utils::enumToString(v);
390 })));
391}
392
393TEST_F(TestReport, createReportWithEmptyActions)
394{
395 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
396
397 sut = makeReport(ReportParams().reportId("TestId_1").reportActions({}));
398 EXPECT_THAT(
399 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
400 Eq(expectedActions));
401}
402
403TEST_F(TestReport, createReportWithValidUnsortedActions)
404{
405 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
406 "EmitsReadingsUpdate"};
407 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
408 "LogToMetricReportsCollection"};
409
410 sut = makeReport(
411 ReportParams()
412 .reportId("TestId_1")
413 .reportActions(utils::transform(newActions, [](const auto& action) {
414 return utils::toReportAction(action);
415 })));
416 EXPECT_THAT(
417 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
418 Eq(expectedActions));
419}
420
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200421TEST_F(TestReport, setEnabledWithNewValue)
422{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100423 bool newValue = !defaultParams().enabled();
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200424 EXPECT_THAT(setProperty(sut->getPath(), "Enabled", newValue).value(),
425 Eq(boost::system::errc::success));
426 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(newValue));
427}
428
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200429TEST_F(TestReport, setIntervalWithValidValue)
430{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200431 uint64_t newValue = ReportManager::minInterval.count() * 42;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200432 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200433 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200434 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
435 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200436}
437
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100438TEST_F(
439 TestReport,
440 settingIntervalWithInvalidValueDoesNotChangePropertyAndReturnsInvalidArgument)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200441{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200442 uint64_t newValue = ReportManager::minInterval.count() - 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200443 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100444 Eq(boost::system::errc::invalid_argument));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200445 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100446 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100447}
448
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200449TEST_F(TestReport, settingInvalidReportingTypeCreatesErrorMessage)
450{
451 auto report = makeReport(defaultParams()
452 .reportId("report2")
453 .reportingType(ReportingType::onRequest)
454 .interval(Milliseconds{0}));
455
456 EXPECT_THAT(
457 setProperty<std::string>(report->getPath(), "ReportingType", "Periodic")
458 .value(),
459 Eq(boost::system::errc::success));
460
461 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
462 Eq("Periodic"));
463 EXPECT_THAT(
464 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
465 UnorderedElementsAre(
466 ErrorMessageDbusType(
467 utils::enumToString(ErrorType::propertyConflict), "Interval"),
468 ErrorMessageDbusType(
469 utils::enumToString(ErrorType::propertyConflict),
470 "ReportingType")));
471}
472
473TEST_F(TestReport, settingValidReportingTypeRemovesErrors)
474{
475 auto report = makeReport(defaultParams()
476 .reportId("report2")
477 .reportingType(ReportingType::onRequest)
478 .interval(Milliseconds{0}));
479
480 EXPECT_THAT(
481 setProperty<std::string>(report->getPath(), "ReportingType", "Periodic")
482 .value(),
483 Eq(boost::system::errc::success));
484 EXPECT_THAT(setProperty<std::string>(report->getPath(), "ReportingType",
485 "OnRequest")
486 .value(),
487 Eq(boost::system::errc::success));
488
489 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
490 Eq("OnRequest"));
491 EXPECT_THAT(
492 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
493 IsEmpty());
494}
495
496TEST_F(TestReport, settingInvalidIntervalDisablesReport)
497{
498 auto report = makeReport(defaultParams()
499 .reportId("report2")
500 .reportingType(ReportingType::periodic)
501 .interval(ReportManager::minInterval));
502
503 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval", 0).value(),
504 Eq(boost::system::errc::success));
505
506 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"), Eq(0u));
507 EXPECT_THAT(
508 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
509 UnorderedElementsAre(
510 ErrorMessageDbusType(
511 utils::enumToString(ErrorType::propertyConflict), "Interval"),
512 ErrorMessageDbusType(
513 utils::enumToString(ErrorType::propertyConflict),
514 "ReportingType")));
515}
516
517TEST_F(TestReport, settingValidIntervalEnablesReport)
518{
519 auto report = makeReport(defaultParams()
520 .reportId("report2")
521 .reportingType(ReportingType::periodic)
522 .interval(ReportManager::minInterval));
523
524 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval", 0).value(),
525 Eq(boost::system::errc::success));
526 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval",
527 ReportManager::minInterval.count())
528 .value(),
529 Eq(boost::system::errc::success));
530
531 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"),
532 Eq(ReportManager::minInterval.count()));
533 EXPECT_THAT(
534 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
535 IsEmpty());
536}
537
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200538TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
539{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100540 EXPECT_THAT(
541 setProperty(sut->getPath(), "EmitsReadingsUpdate", true).value(),
542 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200543 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100544 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100545 ReportAction::emitsReadingsUpdate)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200546}
547
548TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
549{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100550 EXPECT_THAT(
551 setProperty(sut->getPath(), "LogToMetricReportsCollection", true)
552 .value(),
553 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200554 EXPECT_THAT(
555 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100556 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100557 ReportAction::logToMetricReportsCollection)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200558}
559
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100560TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
561{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100562 EXPECT_CALL(storageMock, store(_, _)).Times(0);
563 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
564 .Times(AtLeast(1));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100565
566 bool persistency = false;
567 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
568 Eq(boost::system::errc::success));
569 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
570 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200571}
572
573TEST_F(TestReport, deleteReport)
574{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200575 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
576 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200577 EXPECT_THAT(ec, Eq(boost::system::errc::success));
578}
579
580TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
581{
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200582 auto ec =
583 deleteReport(utils::constants::reportDirPath.str + "NonExisting"s);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200584 EXPECT_THAT(ec.value(), Eq(EBADR));
585}
586
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100587TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
588{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100589 EXPECT_CALL(storageMock, store(_, _)).Times(0);
590 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
591 .Times(AtLeast(1));
592
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100593 auto ec = deleteReport(sut->getPath());
594 EXPECT_THAT(ec, Eq(boost::system::errc::success));
595}
596
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100597TEST_F(TestReport, updatesTriggerIdWhenTriggerIsAdded)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100598{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100599 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100600
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100601 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100602 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100603 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100604 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100605 messanger.send(messages::TriggerPresenceChangedInd{
606 messages::Presence::Exist, "trigger2", {"someOtherReport"}});
607 messanger.send(messages::TriggerPresenceChangedInd{
608 messages::Presence::Exist,
609 "trigger3",
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100610 {"someOtherReport", defaultParams().reportId()}});
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100611
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100612 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200613 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
614 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
615 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100616}
617
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100618TEST_F(TestReport, updatesTriggerIdWhenTriggerIsRemoved)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100619{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100620 utils::Messanger messanger(DbusEnvironment::getIoc());
621
622 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100623 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100624 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100625 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100626 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100627 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100628
629 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100630 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100631 messanger.send(messages::TriggerPresenceChangedInd{
632 messages::Presence::Removed, "trigger2", {}});
633 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100634 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100635
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100636 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200637 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
638 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100639}
640
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100641TEST_F(TestReport, updatesTriggerIdWhenTriggerIsModified)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100642{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100643 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100644
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100645 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100646 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100647 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100648 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100649 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100650 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100651
652 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100653 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100654 messanger.send(messages::TriggerPresenceChangedInd{
655 messages::Presence::Exist, "trigger2", {}});
656 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100657 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100658
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100659 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200660 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
661 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
662 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100663}
664
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100665class TestReportStore :
666 public TestReport,
667 public WithParamInterface<std::pair<std::string, nlohmann::json>>
668{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100669 void SetUp() override
670 {}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100671};
672
673INSTANTIATE_TEST_SUITE_P(
674 _, TestReportStore,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100675 Values(
676 std::make_pair("Enabled"s, nlohmann::json(defaultParams().enabled())),
677 std::make_pair("Version"s, nlohmann::json(6)),
678 std::make_pair("Id"s, nlohmann::json(defaultParams().reportId())),
679 std::make_pair("Name"s, nlohmann::json(defaultParams().reportName())),
680 std::make_pair("ReportingType",
681 nlohmann::json(defaultParams().reportingType())),
682 std::make_pair("ReportActions", nlohmann::json(utils::transform(
683 defaultParams().reportActions(),
684 [](const auto v) {
685 return utils::toUnderlying(v);
686 }))),
687 std::make_pair("Interval",
688 nlohmann::json(defaultParams().interval().count())),
689 std::make_pair("AppendLimit",
690 nlohmann::json(ReportParams().appendLimit())),
691 std::make_pair(
692 "ReadingParameters",
693 nlohmann::json(
694 {{{tstring::SensorPath::str(),
695 {{{tstring::Service::str(), "Service"},
696 {tstring::Path::str(),
697 "/xyz/openbmc_project/sensors/power/p1"},
698 {tstring::Metadata::str(), "metadata1"}}}},
699 {tstring::OperationType::str(), OperationType::avg},
700 {tstring::Id::str(), "MetricId1"},
701 {tstring::CollectionTimeScope::str(),
702 CollectionTimeScope::point},
703 {tstring::CollectionDuration::str(), 0}},
704 {{tstring::SensorPath::str(),
705 {{{tstring::Service::str(), "Service"},
706 {tstring::Path::str(),
707 "/xyz/openbmc_project/sensors/power/p2"},
708 {tstring::Metadata::str(), "metadata2"}}}},
709 {tstring::OperationType::str(), OperationType::avg},
710 {tstring::Id::str(), "MetricId2"},
711 {tstring::CollectionTimeScope::str(),
712 CollectionTimeScope::point},
713 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100714
715TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
716{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100717 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100718
719 {
720 InSequence seq;
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100721 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100722 EXPECT_CALL(checkPoint, Call());
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100723 EXPECT_CALL(storageMock, store(to_file_path(sut->getId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100724 }
725
726 setProperty(sut->getPath(), "Persistency", false);
727 checkPoint.Call();
728 setProperty(sut->getPath(), "Persistency", true);
729
730 const auto& [key, value] = GetParam();
731
732 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
733}
734
735TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
736{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100737 EXPECT_CALL(storageMock,
738 store(to_file_path(defaultParams().reportId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100739
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100740 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100741
742 const auto& [key, value] = GetParam();
743
744 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
745}
746
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200747class TestReportValidNames :
748 public TestReport,
749 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200750{
751 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200752 void SetUp() override
753 {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200754};
755
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200756INSTANTIATE_TEST_SUITE_P(
757 ValidNames, TestReportValidNames,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100758 Values(defaultParams().reportName("Valid_1"),
759 defaultParams().reportName("Valid_1/Valid_2"),
760 defaultParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200761
762TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
763{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200764 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200765}
766
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100767class TestReportInvalidIds :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200768 public TestReport,
769 public WithParamInterface<ReportParams>
770{
771 public:
772 void SetUp() override
773 {}
774};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200775
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100776INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidIds,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100777 Values(defaultParams().reportId("/"),
778 defaultParams().reportId("/Invalid"),
779 defaultParams().reportId("Invalid/"),
780 defaultParams().reportId("Invalid/Invalid/"),
781 defaultParams().reportId("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200782
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100783TEST_P(TestReportInvalidIds, failsToCreateReportWithInvalidName)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100784{
785 EXPECT_CALL(storageMock, store).Times(0);
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100786
787 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100788}
789
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200790class TestReportAllReportTypes :
791 public TestReport,
792 public WithParamInterface<ReportParams>
793{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200794 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200795 void SetUp() override
796 {
797 sut = makeReport(GetParam());
798 }
799};
800
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100801INSTANTIATE_TEST_SUITE_P(
802 _, TestReportAllReportTypes,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100803 Values(defaultParams().reportingType(ReportingType::onRequest),
804 defaultParams().reportingType(ReportingType::onChange),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200805 defaultParams()
806 .reportingType(ReportingType::periodic)
807 .interval(ReportManager::minInterval)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200808
809TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
810{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100811 EXPECT_THAT(utils::toReportingType(
812 getProperty<std::string>(sut->getPath(), "ReportingType")),
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200813 Eq(GetParam().reportingType()));
814}
815
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100816TEST_P(TestReportAllReportTypes, readingsAreUpdated)
817{
818 clockFake.system.advance(10ms);
819
820 messanger.send(messages::UpdateReportInd{{sut->getId()}});
821 const auto [timestamp, readings] =
822 getProperty<Readings>(sut->getPath(), "Readings");
823
824 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
825}
826
827TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIsDisabled)
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200828{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100829 clockFake.system.advance(10ms);
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200830
831 setProperty(sut->getPath(), "Enabled", false);
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100832 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200833 const auto [timestamp, readings] =
834 getProperty<Readings>(sut->getPath(), "Readings");
835
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100836 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200837}
838
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100839TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIdDiffers)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100840{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100841 clockFake.system.advance(10ms);
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100842
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100843 messanger.send(messages::UpdateReportInd{{sut->getId() + "x"s}});
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100844 const auto [timestamp, readings] =
845 getProperty<Readings>(sut->getPath(), "Readings");
846
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100847 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100848}
849
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100850class TestReportOnRequestType : public TestReport
851{
852 void SetUp() override
853 {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100854 sut =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100855 makeReport(defaultParams().reportingType(ReportingType::onRequest));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100856 }
857};
858
859TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
860{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100861 clockFake.system.advance(10ms);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100862
863 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
864
865 const auto [timestamp, readings] =
866 getProperty<Readings>(sut->getPath(), "Readings");
867
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100868 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100869}
870
871TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
872{
873 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
874
875 const auto [timestamp, readings] =
876 getProperty<Readings>(sut->getPath(), "Readings");
877
878 EXPECT_THAT(readings,
879 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000880 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100881}
882
883class TestReportNonOnRequestType :
884 public TestReport,
885 public WithParamInterface<ReportParams>
886{
887 void SetUp() override
888 {
889 sut = makeReport(GetParam());
890 }
891};
892
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100893INSTANTIATE_TEST_SUITE_P(
894 _, TestReportNonOnRequestType,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100895 Values(defaultParams().reportingType(ReportingType::periodic),
896 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100897
898TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
899{
900 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
901
902 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
903 Eq(Readings{}));
904}
905
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200906class TestReportNonPeriodicReport :
907 public TestReport,
908 public WithParamInterface<ReportParams>
909{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200910 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200911 void SetUp() override
912 {
913 sut = makeReport(GetParam());
914 }
915};
916
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100917INSTANTIATE_TEST_SUITE_P(
918 _, TestReportNonPeriodicReport,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100919 Values(defaultParams().reportingType(ReportingType::onRequest),
920 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200921
922TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
923{
924 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
925
926 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
927 Eq(Readings{}));
928}
929
930class TestReportPeriodicReport : public TestReport
931{
932 void SetUp() override
933 {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200934 sut = makeReport(defaultParams()
935 .reportingType(ReportingType::periodic)
936 .interval(ReportManager::minInterval));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200937 }
938};
939
940TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
941{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100942 clockFake.system.advance(10ms);
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200943 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
944
945 const auto [timestamp, readings] =
946 getProperty<Readings>(sut->getPath(), "Readings");
947
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100948 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200949}
950
951TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
952{
953 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
954
955 const auto [timestamp, readings] =
956 getProperty<Readings>(sut->getPath(), "Readings");
957
958 EXPECT_THAT(readings,
959 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000960 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200961}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100962
Szymon Dompke3eb56862021-09-20 15:32:04 +0200963struct ReportUpdatesReportParams
964{
965 ReportParams reportParams;
966 std::vector<ReadingData> expectedReadings;
967 bool expectedEnabled;
968};
969
970class TestReportWithReportUpdatesAndLimit :
971 public TestReport,
972 public WithParamInterface<ReportUpdatesReportParams>
973{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200974 public:
Szymon Dompke3eb56862021-09-20 15:32:04 +0200975 void SetUp() override
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200976 {}
977
978 void changeReport(ReportingType rt, Milliseconds interval)
Szymon Dompke3eb56862021-09-20 15:32:04 +0200979 {
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200980 setProperty<std::string>(sut->getPath(), "ReportingType",
981 utils::enumToString(rt));
982 setProperty<uint64_t>(sut->getPath(), "Interval", interval.count());
983 }
984
985 auto readings()
986 {
987 auto [timestamp, readings] =
988 getProperty<Readings>(sut->getPath(), "Readings");
989 return readings;
990 }
991
992 void updateReportFourTimes()
993 {
994 for (int i = 0; i < 4; i++)
995 {
996 messanger.send(messages::UpdateReportInd{{sut->getId()}});
997 }
Szymon Dompke3eb56862021-09-20 15:32:04 +0200998 }
999};
1000
1001INSTANTIATE_TEST_SUITE_P(
1002 _, TestReportWithReportUpdatesAndLimit,
1003 Values(
1004 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001005 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001006 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1007 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001008 std::vector<ReadingData>{{std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1009 std::make_tuple("a"s, "b"s, 17.1, 114u),
1010 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1011 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1012 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
1013 true},
1014 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001015 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001016 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1017 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001018 std::vector<ReadingData>{
1019 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1020 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1021 std::make_tuple("a"s, "b"s, 17.1, 114u),
1022 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1023 true},
1024 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001025 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001026 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1027 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001028 std::vector<ReadingData>{}, true},
1029 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001030 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001031 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1032 .appendLimit(10),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001033 std::vector<ReadingData>{
1034 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1035 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1036 std::make_tuple("a"s, "b"s, 17.1, 114u),
1037 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1038 std::make_tuple("a"s, "b"s, 17.1, 114u),
1039 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1040 std::make_tuple("a"s, "b"s, 17.1, 114u),
1041 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1042 true},
1043 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001044 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001045 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1046 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001047 std::vector<ReadingData>{{std::make_tuple("a"s, "b"s, 17.1, 114u),
1048 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1049 std::make_tuple("a"s, "b"s, 17.1, 114u),
1050 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1051 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
1052 false},
1053 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001054 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001055 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1056 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001057 std::vector<ReadingData>{
1058 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1059 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1060 std::make_tuple("a"s, "b"s, 17.1, 114u),
1061 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1062 false},
1063 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001064 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001065 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1066 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001067 std::vector<ReadingData>{}, false},
1068 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001069 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001070 .reportUpdates(ReportUpdates::overwrite)
1071 .appendLimit(500),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001072 std::vector<ReadingData>{
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::overwrite)
1079 .appendLimit(1),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001080 std::vector<ReadingData>{
1081 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1082 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1083 true},
1084 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001085 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001086 .reportUpdates(ReportUpdates::overwrite)
1087 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001088 std::vector<ReadingData>{
1089 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1090 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001091 true},
1092 ReportUpdatesReportParams{
1093 defaultParams()
1094 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1095 .appendLimit(std::numeric_limits<uint64_t>::max()),
1096 std::vector<ReadingData>{
1097 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1098 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1099 false}));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001100
1101TEST_P(TestReportWithReportUpdatesAndLimit,
1102 readingsAreUpdatedAfterIntervalExpires)
1103{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001104 sut = makeReport(ReportParams(GetParam().reportParams)
1105 .reportingType(ReportingType::periodic)
1106 .interval(std::chrono::hours(1000)));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001107
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001108 updateReportFourTimes();
Szymon Dompke3eb56862021-09-20 15:32:04 +02001109
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001110 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1111 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1112 Eq(GetParam().expectedEnabled));
1113}
1114
1115TEST_P(TestReportWithReportUpdatesAndLimit,
1116 appendLimitIsRespectedAfterChangingToPeriodic)
1117{
1118 sut = makeReport(ReportParams(GetParam().reportParams)
1119 .reportingType(ReportingType::onRequest)
1120 .interval(std::chrono::hours(0)));
1121
1122 changeReport(ReportingType::periodic, std::chrono::hours(1000));
1123 updateReportFourTimes();
1124
1125 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1126 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1127 Eq(GetParam().expectedEnabled));
1128}
1129
1130TEST_P(TestReportWithReportUpdatesAndLimit,
1131 appendLimitIsIgnoredAfterChangingToOnRequest)
1132{
1133 sut = makeReport(ReportParams(GetParam().reportParams)
1134 .reportingType(ReportingType::periodic)
1135 .interval(std::chrono::hours(1000)));
1136
1137 changeReport(ReportingType::onRequest, Milliseconds{0});
1138 updateReportFourTimes();
1139
1140 EXPECT_THAT(readings(), SizeIs(2u));
1141 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(true));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001142}
1143
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001144class TestReportInitialization : public TestReport
1145{
1146 public:
1147 void SetUp() override
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001148 {
1149 initMetricMocks(defaultParams().metricParameters());
1150 }
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001151
Patrick Williams39cc6ac2022-07-22 19:26:56 -05001152 void monitorProc(sdbusplus::message_t& msg)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001153 {
1154 std::string iface;
1155 std::vector<std::pair<std::string, std::variant<Readings>>>
1156 changed_properties;
1157 std::vector<std::string> invalidated_properties;
1158
1159 msg.read(iface, changed_properties, invalidated_properties);
1160
1161 if (iface == Report::reportIfaceName)
1162 {
1163 for (const auto& [name, value] : changed_properties)
1164 {
1165 if (name == "Readings")
1166 {
1167 readingsUpdated.Call();
1168 }
1169 }
1170 }
1171 }
1172
1173 void makeMonitor()
1174 {
Patrick Williams3a62ee12021-12-03 10:13:25 -06001175 monitor = std::make_unique<sdbusplus::bus::match_t>(
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001176 *DbusEnvironment::getBus(),
1177 sdbusplus::bus::match::rules::propertiesChanged(
1178 sut->getPath(), Report::reportIfaceName),
1179 [this](auto& msg) { monitorProc(msg); });
1180 }
1181
Patrick Williams3a62ee12021-12-03 10:13:25 -06001182 std::unique_ptr<sdbusplus::bus::match_t> monitor;
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001183 MockFunction<void()> readingsUpdated;
1184};
1185
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001186TEST_F(TestReportInitialization,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001187 registersForMetricUpdatesWhenOnChangeReportCreated)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001188{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001189 std::vector<const interfaces::MetricListener*> args;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001190 for (auto& metric : metricMocks)
1191 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001192 EXPECT_CALL(*metric, registerForUpdates(_))
1193 .WillOnce(Invoke([&args](const interfaces::MetricListener& report) {
1194 args.emplace_back(&report);
1195 }));
1196 ;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001197 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001198
1199 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1200
1201 EXPECT_THAT(args, SizeIs(metricMocks.size()));
1202 for (const auto* reportPtr : args)
1203 {
1204 EXPECT_THAT(reportPtr, Eq(sut.get()));
1205 }
1206}
1207
1208TEST_F(TestReportInitialization,
1209 deregistersForMetricUpdatesWhenOnChangeReportDestroyed)
1210{
1211 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1212
1213 for (auto& metric : metricMocks)
1214 {
1215 EXPECT_CALL(*metric,
1216 unregisterFromUpdates(Ref(
1217 static_cast<interfaces::MetricListener&>(*sut.get()))));
1218 }
1219
1220 sut = nullptr;
1221}
1222
1223TEST_F(TestReportInitialization,
1224 metricsAreInitializedWhenEnabledReportConstructed)
1225{
1226 for (auto& metric : metricMocks)
1227 {
1228 EXPECT_CALL(*metric, initialize());
1229 }
1230 sut = makeReport(defaultParams().enabled(true));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001231}
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001232
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001233TEST_F(TestReportInitialization,
1234 metricsAreNotInitializedWhenDisabledReportConstructed)
1235{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001236 for (auto& metric : metricMocks)
1237 {
1238 EXPECT_CALL(*metric, initialize()).Times(0);
1239 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001240 sut = makeReport(defaultParams().enabled(false));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001241}
1242
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001243TEST_F(TestReportInitialization,
1244 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001245{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001246 EXPECT_CALL(readingsUpdated, Call())
1247 .WillOnce(
1248 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
1249
1250 const auto elapsed = DbusEnvironment::measureTime([this] {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001251 sut = makeReport(defaultParams()
1252 .reportingType(ReportingType::periodic)
1253 .reportActions({ReportAction::emitsReadingsUpdate})
1254 .interval(ReportManager::minInterval));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001255 makeMonitor();
1256 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
1257 });
1258
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001259 EXPECT_THAT(elapsed, AllOf(Ge(ReportManager::minInterval),
1260 Lt(ReportManager::minInterval * 2)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001261}
1262
1263TEST_F(TestReportInitialization,
1264 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
1265{
1266 EXPECT_CALL(readingsUpdated, Call()).Times(0);
1267
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001268 sut = makeReport(defaultParams()
1269 .reportingType(ReportingType::periodic)
1270 .reportActions({}));
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001271 makeMonitor();
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001272 DbusEnvironment::sleepFor(defaultParams().interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001273}
Szymon Dompke3eb56862021-09-20 15:32:04 +02001274
1275TEST_F(TestReportInitialization, appendLimitDeducedProperly)
1276{
1277 sut = makeReport(
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001278 defaultParams().appendLimit(std::numeric_limits<uint64_t>::max()));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001279 auto appendLimit = getProperty<uint64_t>(sut->getPath(), "AppendLimit");
1280 EXPECT_EQ(appendLimit, 2ull);
1281}
Krzysztof Grobelnye6c417c2022-02-02 17:25:53 +01001282
1283TEST_F(TestReportInitialization, appendLimitSetToUintMaxIsStoredCorrectly)
1284{
Krzysztof Grobelnye6c417c2022-02-02 17:25:53 +01001285 sut = makeReport(
1286 ReportParams().appendLimit(std::numeric_limits<uint64_t>::max()));
1287
1288 ASSERT_THAT(storedConfiguration.at("AppendLimit"),
1289 Eq(std::numeric_limits<uint64_t>::max()));
1290}
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001291
1292TEST_F(TestReportInitialization, triggerIdsPropertyIsInitialzed)
1293{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001294 for (const auto& triggerId : {"trigger1", "trigger2"})
1295 {
1296 messanger.on_receive<messages::CollectTriggerIdReq>(
Szymon Dompkee0ed5082022-05-20 10:54:25 +02001297 [this, triggerId](const auto& msg) {
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001298 messanger.send(messages::CollectTriggerIdResp{triggerId});
1299 });
1300 }
1301
1302 sut = makeReport(ReportParams());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001303
1304 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +02001305 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
1306 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
1307 utils::constants::triggerDirPath / "trigger2"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001308}
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001309
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +01001310TEST_F(TestReportInitialization,
1311 metricValuesAreNotStoredForReportUpdatesDifferentThanAppendStopsWhenFull)
1312{
1313 sut = makeReport(ReportParams()
1314 .reportingType(ReportingType::periodic)
1315 .interval(1h)
1316 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1317 .readings(Readings{{}, {{}}}));
1318
1319 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1320 Eq(storedConfiguration.end()));
1321}
1322
1323TEST_F(TestReportInitialization, metricValuesAreNotStoredForOnRequestReport)
1324{
1325 sut = makeReport(ReportParams()
1326 .reportingType(ReportingType::onRequest)
1327 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1328 .readings(Readings{{}, {{}}}));
1329
1330 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1331 Eq(storedConfiguration.end()));
1332}
1333
1334TEST_F(TestReportInitialization,
1335 metricValuesAreStoredForNonOnRequestReportWithAppendStopsWhenFull)
1336{
1337 const auto readings = Readings{{}, {{}}};
1338
1339 sut = makeReport(ReportParams()
1340 .reportingType(ReportingType::periodic)
1341 .interval(1h)
1342 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1343 .readings(readings));
1344
1345 ASSERT_THAT(storedConfiguration.at("MetricValues").get<LabeledReadings>(),
1346 Eq(utils::toLabeledReadings(readings)));
1347}
1348
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001349class TestReportInitializationOnChangeReport : public TestReportInitialization
1350{
1351 public:
1352 void SetUp() override
1353 {
1354 initMetricMocks(params.metricParameters());
1355 }
1356
1357 ReportParams params = defaultOnChangeParams();
1358};
1359
1360TEST_F(TestReportInitializationOnChangeReport,
1361 doesntUpdateReadingsWhenNotRequired)
1362{
1363 EXPECT_CALL(*metricMocks[0], updateReadings(_)).Times(0);
1364
1365 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(false));
1366
1367 sut = makeReport(params);
1368
1369 DbusEnvironment::sleepFor(500ms);
1370}
1371
1372TEST_F(TestReportInitializationOnChangeReport, updatesReadingsWhenRequired)
1373{
1374 EXPECT_CALL(*metricMocks[0], updateReadings(_))
1375 .WillOnce(Return())
1376 .WillOnce(
1377 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")))
1378 .WillRepeatedly(Return());
1379
1380 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(true));
1381
1382 sut = makeReport(params);
1383
1384 DbusEnvironment::waitForFuture("readingsUpdated");
1385}