blob: 8be6397c68030be096b351fd117bf3af5e5dfdb0 [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
25using namespace testing;
26using namespace std::literals::string_literals;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020027using namespace std::chrono_literals;
Szymon Dompke1cdd7e42022-06-08 14:43:13 +020028using sdbusplus::message::object_path;
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000029namespace tstring = utils::tstring;
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020030
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +020031using ErrorMessageDbusType = std::tuple<std::string, std::string>;
32using ErrorMessagesDbusType = std::vector<ErrorMessageDbusType>;
33
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010034constexpr Milliseconds systemTimestamp = 55ms;
35
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +010036namespace
37{
38
39ReportParams defaultParams()
40{
41 return ReportParams();
42}
43
44ReportParams defaultOnChangeParams()
45{
46 return defaultParams().reportingType(ReportingType::onChange);
47}
48
49} // namespace
50
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020051class TestReport : public Test
52{
53 public:
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020054 std::unique_ptr<ReportManagerMock> reportManagerMock =
Wludzik, Jozefe2362792020-10-27 17:23:55 +010055 std::make_unique<NiceMock<ReportManagerMock>>();
Szymon Dompkefdb06a12022-02-11 11:04:44 +010056 std::unique_ptr<ReportFactoryMock> reportFactoryMock =
57 std::make_unique<NiceMock<ReportFactoryMock>>();
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +010058 nlohmann::json storedConfiguration;
Szymon Dompkefdb06a12022-02-11 11:04:44 +010059 NiceMock<StorageMock> storageMock;
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000060 std::vector<std::shared_ptr<MetricMock>> metricMocks;
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010061 std::unique_ptr<ClockFake> clockFakePtr = std::make_unique<ClockFake>();
62 ClockFake& clockFake = *clockFakePtr;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020063 std::unique_ptr<Report> sut;
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010064 utils::Messanger messanger;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020065
Wludzik, Jozefe2362792020-10-27 17:23:55 +010066 MockFunction<void()> checkPoint;
67
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010068 TestReport() : messanger(DbusEnvironment::getIoc())
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010069 {
70 clockFake.system.set(systemTimestamp);
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +010071 ON_CALL(storageMock, store(to_file_path(ReportParams().reportId()), _))
72 .WillByDefault(SaveArg<1>(&storedConfiguration));
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010073 }
74
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000075 void initMetricMocks(
76 const std::vector<LabeledMetricParameters>& metricParameters)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010077 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000078 for (auto i = metricMocks.size(); i < metricParameters.size(); ++i)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010079 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000080 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>());
81 }
82 metricMocks.resize(metricParameters.size());
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000083
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000084 std::vector<MetricValue> readings{{MetricValue{"a", "b", 17.1, 114},
85 MetricValue{"aa", "bb", 42.0, 74}}};
86 readings.resize(metricParameters.size());
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000087
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000088 for (size_t i = 0; i < metricParameters.size(); ++i)
89 {
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +010090 ON_CALL(*metricMocks[i], getUpdatedReadings())
91 .WillByDefault(ReturnRefOfCopy(std::vector({readings[i]})));
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000092 ON_CALL(*metricMocks[i], dumpConfiguration())
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000093 .WillByDefault(Return(metricParameters[i]));
Wludzik, Jozefe2362792020-10-27 17:23:55 +010094 }
95 }
96
Szymon Dompkefdb06a12022-02-11 11:04:44 +010097 std::vector<std::shared_ptr<interfaces::Metric>>
98 getMetricsFromReadingParams(const ReadingParameters& params)
99 {
100 const auto metricParameters =
101 reportFactoryMock->convertMetricParams(params);
102 std::vector<std::shared_ptr<MetricMock>> metricMocks;
103
104 for (size_t i = 0; i < metricParameters.size(); ++i)
105 {
106 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>());
107 ON_CALL(*metricMocks[i], dumpConfiguration())
108 .WillByDefault(Return(metricParameters[i]));
109 }
110
111 return utils::convContainer<std::shared_ptr<interfaces::Metric>>(
112 metricMocks);
113 }
114
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200115 void SetUp() override
116 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100117 sut = makeReport(defaultParams());
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200118 }
119
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100120 static interfaces::JsonStorage::FilePath to_file_path(std::string id)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100121 {
122 return interfaces::JsonStorage::FilePath(
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100123 std::to_string(std::hash<std::string>{}(id)));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100124 }
125
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200126 std::unique_ptr<Report> makeReport(const ReportParams& params)
127 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000128 initMetricMocks(params.metricParameters());
129
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200130 return std::make_unique<Report>(
131 DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100132 params.reportId(), params.reportName(), params.reportingType(),
133 params.reportActions(), params.interval(), params.appendLimit(),
134 params.reportUpdates(), *reportManagerMock, storageMock,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200135 utils::convContainer<std::shared_ptr<interfaces::Metric>>(
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200136 metricMocks),
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100137 *reportFactoryMock, params.enabled(), std::move(clockFakePtr),
138 params.readings());
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200139 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200140
141 template <class T>
142 static T getProperty(const std::string& path, const std::string& property)
143 {
Szymon Dompkee28aa532021-10-27 12:33:12 +0200144 return DbusEnvironment::getProperty<T>(path, Report::reportIfaceName,
145 property);
146 }
147
148 template <class T>
149 static boost::system::error_code setProperty(const std::string& path,
150 const std::string& property,
151 const T& newValue)
152 {
153 return DbusEnvironment::setProperty<T>(path, Report::reportIfaceName,
154 property, newValue);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100155 }
156
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200157 template <class T>
158 struct ChangePropertyParams
159 {
160 Matcher<T> valueBefore = _;
161 T newValue;
162 Matcher<boost::system::error_code> ec =
163 Eq(boost::system::errc::success);
164 Matcher<T> valueAfter = Eq(newValue);
165 };
166
167 template <class T>
168 static void changeProperty(const std::string& path,
169 const std::string& property,
170 ChangePropertyParams<T> p)
171 {
172 ASSERT_THAT(getProperty<T>(path, property), p.valueBefore);
173 ASSERT_THAT(setProperty<T>(path, property, p.newValue), p.ec);
174 EXPECT_THAT(getProperty<T>(path, property), p.valueAfter);
175 }
176
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100177 boost::system::error_code call(const std::string& path,
178 const std::string& interface,
179 const std::string& method)
180 {
181 std::promise<boost::system::error_code> methodPromise;
182 DbusEnvironment::getBus()->async_method_call(
183 [&methodPromise](boost::system::error_code ec) {
184 methodPromise.set_value(ec);
185 },
186 DbusEnvironment::serviceName(), path, interface, method);
187 return DbusEnvironment::waitForFuture(methodPromise.get_future());
188 }
189
190 boost::system::error_code update(const std::string& path)
191 {
192 return call(path, Report::reportIfaceName, "Update");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200193 }
194
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200195 boost::system::error_code deleteReport(const std::string& path)
196 {
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100197 return call(path, Report::deleteIfaceName, "Delete");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200198 }
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200199
200 static std::pair<std::string, std::vector<std::string>>
201 makeStateDetail(const std::string& detailType,
202 std::vector<std::string> detailArgs)
203 {
204 return make_pair(detailType, detailArgs);
205 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200206};
207
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100208TEST_F(TestReport, returnsId)
209{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100210 EXPECT_THAT(sut->getId(), Eq(defaultParams().reportId()));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100211}
212
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200213TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
214{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200215 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100216 Eq(defaultParams().enabled()));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200217 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100218 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100219 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100220 EXPECT_THAT(
221 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100222 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100223 return utils::enumToString(v);
224 })));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200225 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100226 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100227 ReportAction::emitsReadingsUpdate)));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200228 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "AppendLimit"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100229 Eq(defaultParams().appendLimit()));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100230 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100231 Eq(utils::enumToString(defaultParams().reportingType())));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200232 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportUpdates"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100233 Eq(utils::enumToString(defaultParams().reportUpdates())));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200234 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200235 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100236 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100237 ReportAction::logToMetricReportsCollection)));
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000238 EXPECT_THAT(getProperty<ReadingParameters>(
239 sut->getPath(), "ReadingParametersFutureVersion"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100240 Eq(toReadingParameters(defaultParams().metricParameters())));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100241 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100242 Eq(defaultParams().reportName()));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100243 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200244 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200245 IsEmpty());
246 EXPECT_THAT(
247 getProperty<ErrorMessagesDbusType>(sut->getPath(), "ErrorMessages"),
248 IsEmpty());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200249}
250
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200251TEST_F(TestReport, readingsAreInitialyEmpty)
252{
253 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
254 Eq(Readings{}));
255}
256
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100257TEST_F(TestReport, setReadingParametersWithNewParams)
258{
259 ReadingParameters newParams = toReadingParameters(
260 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
261 {LabeledSensorInfo{"Service",
262 "/xyz/openbmc_project/sensors/power/psu",
263 "NewMetadata123"}},
264 OperationType::avg,
265 "NewMetricId123",
266 CollectionTimeScope::startup,
267 CollectionDuration(250ms)}}});
268 auto metrics = getMetricsFromReadingParams(newParams);
269
270 EXPECT_CALL(*reportFactoryMock, updateMetrics(_, _, _))
271 .WillOnce(SetArgReferee<0>(metrics));
272 EXPECT_THAT(
273 setProperty(sut->getPath(), "ReadingParametersFutureVersion", newParams)
274 .value(),
275 Eq(boost::system::errc::success));
276 EXPECT_THAT(getProperty<ReadingParameters>(
277 sut->getPath(), "ReadingParametersFutureVersion"),
278 Eq(newParams));
279}
280
Szymon Dompke32305f12022-07-05 15:37:21 +0200281TEST_F(TestReport, setReadingParametersWithTooLongMetricId)
282{
283 const ReadingParameters currentValue =
284 toReadingParameters(defaultParams().metricParameters());
285
286 ReadingParameters newParams = toReadingParameters(
287 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
288 {LabeledSensorInfo{"Service",
289 "/xyz/openbmc_project/sensors/power/psu",
290 "NewMetadata123"}},
291 OperationType::avg,
292 utils::string_utils::getTooLongId(),
293 CollectionTimeScope::startup,
294 CollectionDuration(250ms)}}});
295
296 changeProperty<ReadingParameters>(
297 sut->getPath(), "ReadingParametersFutureVersion",
298 {.valueBefore = Eq(currentValue),
299 .newValue = newParams,
300 .ec = Eq(boost::system::errc::invalid_argument),
301 .valueAfter = Eq(currentValue)});
302}
303
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100304TEST_F(TestReport, setReportingTypeWithValidNewType)
305{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200306 changeProperty<std::string>(
307 sut->getPath(), "ReportingType",
308 {.valueBefore = Not(Eq(utils::enumToString(ReportingType::onRequest))),
309 .newValue = utils::enumToString(ReportingType::onRequest)});
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100310}
311
312TEST_F(TestReport, setReportingTypeWithInvalidType)
313{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200314 const std::string currentValue =
315 utils::enumToString(defaultParams().reportingType());
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100316
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200317 changeProperty<std::string>(
318 sut->getPath(), "ReportingType",
319 {.valueBefore = Eq(currentValue),
320 .newValue = "Periodic_ABC",
321 .ec = Eq(boost::system::errc::invalid_argument),
322 .valueAfter = Eq(currentValue)});
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100323}
324
325TEST_F(TestReport, setReportActionsWithValidNewActions)
326{
327 std::vector<std::string> newActions = {"EmitsReadingsUpdate"};
328 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100329 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100330 [](const auto v) { return utils::enumToString(v); });
331
332 EXPECT_THAT(newActions, Ne(currActions));
333 EXPECT_THAT(
334 setProperty(sut->getPath(), "ReportActions", newActions).value(),
335 Eq(boost::system::errc::success));
336 EXPECT_THAT(
337 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
338 UnorderedElementsAre("EmitsReadingsUpdate",
339 "LogToMetricReportsCollection"));
340}
341
342TEST_F(TestReport, setReportActionsWithValidUnsortedActions)
343{
344 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
345 "EmitsReadingsUpdate"};
346 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
347 "LogToMetricReportsCollection"};
348 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100349 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100350 [](const auto v) { return utils::enumToString(v); });
351
352 EXPECT_THAT(newActions, Ne(currActions));
353 EXPECT_THAT(
354 setProperty(sut->getPath(), "ReportActions", newActions).value(),
355 Eq(boost::system::errc::success));
356 EXPECT_THAT(
357 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
358 Eq(expectedActions));
359}
360
361TEST_F(TestReport, setReportActionsWithEmptyActions)
362{
363 std::vector<std::string> newActions = {};
364 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
365 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100366 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100367 [](const auto v) { return utils::enumToString(v); });
368
369 EXPECT_THAT(newActions, Ne(currActions));
370 EXPECT_THAT(
371 setProperty(sut->getPath(), "ReportActions", newActions).value(),
372 Eq(boost::system::errc::success));
373 EXPECT_THAT(
374 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
375 Eq(expectedActions));
376}
377
378TEST_F(TestReport, setReportActionsWithInvalidActions)
379{
380 std::vector<std::string> invalidActions = {"EmitsReadingsUpdate_1"};
381 EXPECT_THAT(
382 setProperty(sut->getPath(), "ReportActions", invalidActions).value(),
383 Eq(boost::system::errc::invalid_argument));
384 EXPECT_THAT(
385 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100386 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100387 return utils::enumToString(v);
388 })));
389}
390
391TEST_F(TestReport, createReportWithEmptyActions)
392{
393 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
394
395 sut = makeReport(ReportParams().reportId("TestId_1").reportActions({}));
396 EXPECT_THAT(
397 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
398 Eq(expectedActions));
399}
400
401TEST_F(TestReport, createReportWithValidUnsortedActions)
402{
403 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
404 "EmitsReadingsUpdate"};
405 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
406 "LogToMetricReportsCollection"};
407
408 sut = makeReport(
409 ReportParams()
410 .reportId("TestId_1")
411 .reportActions(utils::transform(newActions, [](const auto& action) {
412 return utils::toReportAction(action);
413 })));
414 EXPECT_THAT(
415 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
416 Eq(expectedActions));
417}
418
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200419TEST_F(TestReport, setEnabledWithNewValue)
420{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100421 bool newValue = !defaultParams().enabled();
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200422 EXPECT_THAT(setProperty(sut->getPath(), "Enabled", newValue).value(),
423 Eq(boost::system::errc::success));
424 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(newValue));
425}
426
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200427TEST_F(TestReport, setIntervalWithValidValue)
428{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200429 uint64_t newValue = ReportManager::minInterval.count() * 42;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200430 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200431 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200432 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
433 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200434}
435
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100436TEST_F(
437 TestReport,
438 settingIntervalWithInvalidValueDoesNotChangePropertyAndReturnsInvalidArgument)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200439{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200440 uint64_t newValue = ReportManager::minInterval.count() - 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200441 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100442 Eq(boost::system::errc::invalid_argument));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200443 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100444 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100445}
446
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200447TEST_F(TestReport, settingInvalidReportingTypeCreatesErrorMessage)
448{
449 auto report = makeReport(defaultParams()
450 .reportId("report2")
451 .reportingType(ReportingType::onRequest)
452 .interval(Milliseconds{0}));
453
454 EXPECT_THAT(
455 setProperty<std::string>(report->getPath(), "ReportingType", "Periodic")
456 .value(),
457 Eq(boost::system::errc::success));
458
459 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
460 Eq("Periodic"));
461 EXPECT_THAT(
462 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
463 UnorderedElementsAre(
464 ErrorMessageDbusType(
465 utils::enumToString(ErrorType::propertyConflict), "Interval"),
466 ErrorMessageDbusType(
467 utils::enumToString(ErrorType::propertyConflict),
468 "ReportingType")));
469}
470
471TEST_F(TestReport, settingValidReportingTypeRemovesErrors)
472{
473 auto report = makeReport(defaultParams()
474 .reportId("report2")
475 .reportingType(ReportingType::onRequest)
476 .interval(Milliseconds{0}));
477
478 EXPECT_THAT(
479 setProperty<std::string>(report->getPath(), "ReportingType", "Periodic")
480 .value(),
481 Eq(boost::system::errc::success));
482 EXPECT_THAT(setProperty<std::string>(report->getPath(), "ReportingType",
483 "OnRequest")
484 .value(),
485 Eq(boost::system::errc::success));
486
487 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
488 Eq("OnRequest"));
489 EXPECT_THAT(
490 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
491 IsEmpty());
492}
493
494TEST_F(TestReport, settingInvalidIntervalDisablesReport)
495{
496 auto report = makeReport(defaultParams()
497 .reportId("report2")
498 .reportingType(ReportingType::periodic)
499 .interval(ReportManager::minInterval));
500
501 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval", 0).value(),
502 Eq(boost::system::errc::success));
503
504 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"), Eq(0u));
505 EXPECT_THAT(
506 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
507 UnorderedElementsAre(
508 ErrorMessageDbusType(
509 utils::enumToString(ErrorType::propertyConflict), "Interval"),
510 ErrorMessageDbusType(
511 utils::enumToString(ErrorType::propertyConflict),
512 "ReportingType")));
513}
514
515TEST_F(TestReport, settingValidIntervalEnablesReport)
516{
517 auto report = makeReport(defaultParams()
518 .reportId("report2")
519 .reportingType(ReportingType::periodic)
520 .interval(ReportManager::minInterval));
521
522 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval", 0).value(),
523 Eq(boost::system::errc::success));
524 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval",
525 ReportManager::minInterval.count())
526 .value(),
527 Eq(boost::system::errc::success));
528
529 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"),
530 Eq(ReportManager::minInterval.count()));
531 EXPECT_THAT(
532 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
533 IsEmpty());
534}
535
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200536TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
537{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100538 EXPECT_THAT(
539 setProperty(sut->getPath(), "EmitsReadingsUpdate", true).value(),
540 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200541 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100542 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100543 ReportAction::emitsReadingsUpdate)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200544}
545
546TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
547{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100548 EXPECT_THAT(
549 setProperty(sut->getPath(), "LogToMetricReportsCollection", true)
550 .value(),
551 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200552 EXPECT_THAT(
553 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100554 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100555 ReportAction::logToMetricReportsCollection)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200556}
557
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100558TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
559{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100560 EXPECT_CALL(storageMock, store(_, _)).Times(0);
561 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
562 .Times(AtLeast(1));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100563
564 bool persistency = false;
565 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
566 Eq(boost::system::errc::success));
567 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
568 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200569}
570
571TEST_F(TestReport, deleteReport)
572{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200573 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
574 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200575 EXPECT_THAT(ec, Eq(boost::system::errc::success));
576}
577
578TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
579{
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200580 auto ec =
581 deleteReport(utils::constants::reportDirPath.str + "NonExisting"s);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200582 EXPECT_THAT(ec.value(), Eq(EBADR));
583}
584
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100585TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
586{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100587 EXPECT_CALL(storageMock, store(_, _)).Times(0);
588 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
589 .Times(AtLeast(1));
590
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100591 auto ec = deleteReport(sut->getPath());
592 EXPECT_THAT(ec, Eq(boost::system::errc::success));
593}
594
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100595TEST_F(TestReport, updatesTriggerIdWhenTriggerIsAdded)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100596{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100597 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100598
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100599 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100600 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
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{
604 messages::Presence::Exist, "trigger2", {"someOtherReport"}});
605 messanger.send(messages::TriggerPresenceChangedInd{
606 messages::Presence::Exist,
607 "trigger3",
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100608 {"someOtherReport", defaultParams().reportId()}});
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100609
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100610 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200611 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
612 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
613 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100614}
615
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100616TEST_F(TestReport, updatesTriggerIdWhenTriggerIsRemoved)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100617{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100618 utils::Messanger messanger(DbusEnvironment::getIoc());
619
620 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100621 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100622 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100623 messages::Presence::Exist, "trigger2", {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, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100626
627 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100628 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100629 messanger.send(messages::TriggerPresenceChangedInd{
630 messages::Presence::Removed, "trigger2", {}});
631 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100632 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100633
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100634 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200635 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
636 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100637}
638
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100639TEST_F(TestReport, updatesTriggerIdWhenTriggerIsModified)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100640{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100641 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100642
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100643 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100644 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100645 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100646 messages::Presence::Exist, "trigger2", {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, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100649
650 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100651 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100652 messanger.send(messages::TriggerPresenceChangedInd{
653 messages::Presence::Exist, "trigger2", {}});
654 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100655 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100656
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100657 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200658 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
659 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
660 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100661}
662
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100663class TestReportStore :
664 public TestReport,
665 public WithParamInterface<std::pair<std::string, nlohmann::json>>
666{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100667 void SetUp() override
668 {}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100669};
670
671INSTANTIATE_TEST_SUITE_P(
672 _, TestReportStore,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100673 Values(
674 std::make_pair("Enabled"s, nlohmann::json(defaultParams().enabled())),
675 std::make_pair("Version"s, nlohmann::json(6)),
676 std::make_pair("Id"s, nlohmann::json(defaultParams().reportId())),
677 std::make_pair("Name"s, nlohmann::json(defaultParams().reportName())),
678 std::make_pair("ReportingType",
679 nlohmann::json(defaultParams().reportingType())),
680 std::make_pair("ReportActions", nlohmann::json(utils::transform(
681 defaultParams().reportActions(),
682 [](const auto v) {
683 return utils::toUnderlying(v);
684 }))),
685 std::make_pair("Interval",
686 nlohmann::json(defaultParams().interval().count())),
687 std::make_pair("AppendLimit",
688 nlohmann::json(ReportParams().appendLimit())),
689 std::make_pair(
690 "ReadingParameters",
691 nlohmann::json(
692 {{{tstring::SensorPath::str(),
693 {{{tstring::Service::str(), "Service"},
694 {tstring::Path::str(),
695 "/xyz/openbmc_project/sensors/power/p1"},
696 {tstring::Metadata::str(), "metadata1"}}}},
697 {tstring::OperationType::str(), OperationType::avg},
698 {tstring::Id::str(), "MetricId1"},
699 {tstring::CollectionTimeScope::str(),
700 CollectionTimeScope::point},
701 {tstring::CollectionDuration::str(), 0}},
702 {{tstring::SensorPath::str(),
703 {{{tstring::Service::str(), "Service"},
704 {tstring::Path::str(),
705 "/xyz/openbmc_project/sensors/power/p2"},
706 {tstring::Metadata::str(), "metadata2"}}}},
707 {tstring::OperationType::str(), OperationType::avg},
708 {tstring::Id::str(), "MetricId2"},
709 {tstring::CollectionTimeScope::str(),
710 CollectionTimeScope::point},
711 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100712
713TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
714{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100715 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100716
717 {
718 InSequence seq;
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100719 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100720 EXPECT_CALL(checkPoint, Call());
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100721 EXPECT_CALL(storageMock, store(to_file_path(sut->getId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100722 }
723
724 setProperty(sut->getPath(), "Persistency", false);
725 checkPoint.Call();
726 setProperty(sut->getPath(), "Persistency", true);
727
728 const auto& [key, value] = GetParam();
729
730 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
731}
732
733TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
734{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100735 EXPECT_CALL(storageMock,
736 store(to_file_path(defaultParams().reportId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100737
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100738 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100739
740 const auto& [key, value] = GetParam();
741
742 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
743}
744
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200745class TestReportValidNames :
746 public TestReport,
747 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200748{
749 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200750 void SetUp() override
751 {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200752};
753
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200754INSTANTIATE_TEST_SUITE_P(
755 ValidNames, TestReportValidNames,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100756 Values(defaultParams().reportName("Valid_1"),
757 defaultParams().reportName("Valid_1/Valid_2"),
758 defaultParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200759
760TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
761{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200762 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200763}
764
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100765class TestReportInvalidIds :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200766 public TestReport,
767 public WithParamInterface<ReportParams>
768{
769 public:
770 void SetUp() override
771 {}
772};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200773
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100774INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidIds,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100775 Values(defaultParams().reportId("/"),
776 defaultParams().reportId("/Invalid"),
777 defaultParams().reportId("Invalid/"),
778 defaultParams().reportId("Invalid/Invalid/"),
779 defaultParams().reportId("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200780
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100781TEST_P(TestReportInvalidIds, failsToCreateReportWithInvalidName)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100782{
783 EXPECT_CALL(storageMock, store).Times(0);
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100784
785 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100786}
787
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200788class TestReportAllReportTypes :
789 public TestReport,
790 public WithParamInterface<ReportParams>
791{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200792 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200793 void SetUp() override
794 {
795 sut = makeReport(GetParam());
796 }
797};
798
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100799INSTANTIATE_TEST_SUITE_P(
800 _, TestReportAllReportTypes,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100801 Values(defaultParams().reportingType(ReportingType::onRequest),
802 defaultParams().reportingType(ReportingType::onChange),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200803 defaultParams()
804 .reportingType(ReportingType::periodic)
805 .interval(ReportManager::minInterval)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200806
807TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
808{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100809 EXPECT_THAT(utils::toReportingType(
810 getProperty<std::string>(sut->getPath(), "ReportingType")),
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200811 Eq(GetParam().reportingType()));
812}
813
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100814TEST_P(TestReportAllReportTypes, readingsAreUpdated)
815{
816 clockFake.system.advance(10ms);
817
818 messanger.send(messages::UpdateReportInd{{sut->getId()}});
819 const auto [timestamp, readings] =
820 getProperty<Readings>(sut->getPath(), "Readings");
821
822 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
823}
824
825TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIsDisabled)
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200826{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100827 clockFake.system.advance(10ms);
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200828
829 setProperty(sut->getPath(), "Enabled", false);
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100830 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200831 const auto [timestamp, readings] =
832 getProperty<Readings>(sut->getPath(), "Readings");
833
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100834 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200835}
836
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100837TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIdDiffers)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100838{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100839 clockFake.system.advance(10ms);
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100840
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100841 messanger.send(messages::UpdateReportInd{{sut->getId() + "x"s}});
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100842 const auto [timestamp, readings] =
843 getProperty<Readings>(sut->getPath(), "Readings");
844
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100845 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100846}
847
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100848class TestReportOnRequestType : public TestReport
849{
850 void SetUp() override
851 {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100852 sut =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100853 makeReport(defaultParams().reportingType(ReportingType::onRequest));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100854 }
855};
856
857TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
858{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100859 clockFake.system.advance(10ms);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100860
861 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
862
863 const auto [timestamp, readings] =
864 getProperty<Readings>(sut->getPath(), "Readings");
865
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100866 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100867}
868
869TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
870{
871 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
872
873 const auto [timestamp, readings] =
874 getProperty<Readings>(sut->getPath(), "Readings");
875
876 EXPECT_THAT(readings,
877 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000878 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100879}
880
881class TestReportNonOnRequestType :
882 public TestReport,
883 public WithParamInterface<ReportParams>
884{
885 void SetUp() override
886 {
887 sut = makeReport(GetParam());
888 }
889};
890
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100891INSTANTIATE_TEST_SUITE_P(
892 _, TestReportNonOnRequestType,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100893 Values(defaultParams().reportingType(ReportingType::periodic),
894 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100895
896TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
897{
898 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
899
900 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
901 Eq(Readings{}));
902}
903
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200904class TestReportNonPeriodicReport :
905 public TestReport,
906 public WithParamInterface<ReportParams>
907{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200908 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200909 void SetUp() override
910 {
911 sut = makeReport(GetParam());
912 }
913};
914
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100915INSTANTIATE_TEST_SUITE_P(
916 _, TestReportNonPeriodicReport,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100917 Values(defaultParams().reportingType(ReportingType::onRequest),
918 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200919
920TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
921{
922 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
923
924 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
925 Eq(Readings{}));
926}
927
928class TestReportPeriodicReport : public TestReport
929{
930 void SetUp() override
931 {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200932 sut = makeReport(defaultParams()
933 .reportingType(ReportingType::periodic)
934 .interval(ReportManager::minInterval));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200935 }
936};
937
938TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
939{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100940 clockFake.system.advance(10ms);
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200941 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
942
943 const auto [timestamp, readings] =
944 getProperty<Readings>(sut->getPath(), "Readings");
945
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100946 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200947}
948
949TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
950{
951 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
952
953 const auto [timestamp, readings] =
954 getProperty<Readings>(sut->getPath(), "Readings");
955
956 EXPECT_THAT(readings,
957 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000958 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200959}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100960
Szymon Dompke3eb56862021-09-20 15:32:04 +0200961struct ReportUpdatesReportParams
962{
963 ReportParams reportParams;
964 std::vector<ReadingData> expectedReadings;
965 bool expectedEnabled;
966};
967
968class TestReportWithReportUpdatesAndLimit :
969 public TestReport,
970 public WithParamInterface<ReportUpdatesReportParams>
971{
972 void SetUp() override
973 {
974 sut = makeReport(ReportParams(GetParam().reportParams)
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100975 .reportingType(ReportingType::periodic)
Szymon Dompke3eb56862021-09-20 15:32:04 +0200976 .interval(std::chrono::hours(1000)));
977 }
978};
979
980INSTANTIATE_TEST_SUITE_P(
981 _, TestReportWithReportUpdatesAndLimit,
982 Values(
983 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100984 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100985 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
986 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200987 std::vector<ReadingData>{{std::make_tuple("aa"s, "bb"s, 42.0, 74u),
988 std::make_tuple("a"s, "b"s, 17.1, 114u),
989 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
990 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
991 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
992 true},
993 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100994 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100995 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
996 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200997 std::vector<ReadingData>{
998 {std::make_tuple("a"s, "b"s, 17.1, 114u),
999 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1000 std::make_tuple("a"s, "b"s, 17.1, 114u),
1001 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1002 true},
1003 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001004 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001005 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1006 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001007 std::vector<ReadingData>{}, true},
1008 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001009 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001010 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1011 .appendLimit(10),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001012 std::vector<ReadingData>{
1013 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1014 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1015 std::make_tuple("a"s, "b"s, 17.1, 114u),
1016 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1017 std::make_tuple("a"s, "b"s, 17.1, 114u),
1018 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1019 std::make_tuple("a"s, "b"s, 17.1, 114u),
1020 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1021 true},
1022 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001023 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001024 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1025 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001026 std::vector<ReadingData>{{std::make_tuple("a"s, "b"s, 17.1, 114u),
1027 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1028 std::make_tuple("a"s, "b"s, 17.1, 114u),
1029 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1030 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
1031 false},
1032 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001033 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001034 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1035 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001036 std::vector<ReadingData>{
1037 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1038 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1039 std::make_tuple("a"s, "b"s, 17.1, 114u),
1040 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1041 false},
1042 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001043 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001044 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1045 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001046 std::vector<ReadingData>{}, false},
1047 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001048 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001049 .reportUpdates(ReportUpdates::overwrite)
1050 .appendLimit(500),
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 true},
1055 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001056 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001057 .reportUpdates(ReportUpdates::overwrite)
1058 .appendLimit(1),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001059 std::vector<ReadingData>{
1060 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1061 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1062 true},
1063 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001064 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001065 .reportUpdates(ReportUpdates::overwrite)
1066 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001067 std::vector<ReadingData>{
1068 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1069 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1070 true}));
1071
1072TEST_P(TestReportWithReportUpdatesAndLimit,
1073 readingsAreUpdatedAfterIntervalExpires)
1074{
1075 for (int i = 0; i < 4; i++)
1076 {
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001077 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Szymon Dompke3eb56862021-09-20 15:32:04 +02001078 }
1079
1080 const auto [timestamp, readings] =
1081 getProperty<Readings>(sut->getPath(), "Readings");
1082 const auto enabled = getProperty<bool>(sut->getPath(), "Enabled");
1083
1084 EXPECT_THAT(readings, ElementsAreArray(GetParam().expectedReadings));
1085 EXPECT_EQ(enabled, GetParam().expectedEnabled);
1086}
1087
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001088class TestReportInitialization : public TestReport
1089{
1090 public:
1091 void SetUp() override
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001092 {
1093 initMetricMocks(defaultParams().metricParameters());
1094 }
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001095
Patrick Williams39cc6ac2022-07-22 19:26:56 -05001096 void monitorProc(sdbusplus::message_t& msg)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001097 {
1098 std::string iface;
1099 std::vector<std::pair<std::string, std::variant<Readings>>>
1100 changed_properties;
1101 std::vector<std::string> invalidated_properties;
1102
1103 msg.read(iface, changed_properties, invalidated_properties);
1104
1105 if (iface == Report::reportIfaceName)
1106 {
1107 for (const auto& [name, value] : changed_properties)
1108 {
1109 if (name == "Readings")
1110 {
1111 readingsUpdated.Call();
1112 }
1113 }
1114 }
1115 }
1116
1117 void makeMonitor()
1118 {
Patrick Williams3a62ee12021-12-03 10:13:25 -06001119 monitor = std::make_unique<sdbusplus::bus::match_t>(
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001120 *DbusEnvironment::getBus(),
1121 sdbusplus::bus::match::rules::propertiesChanged(
1122 sut->getPath(), Report::reportIfaceName),
1123 [this](auto& msg) { monitorProc(msg); });
1124 }
1125
Patrick Williams3a62ee12021-12-03 10:13:25 -06001126 std::unique_ptr<sdbusplus::bus::match_t> monitor;
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001127 MockFunction<void()> readingsUpdated;
1128};
1129
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001130TEST_F(TestReportInitialization,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001131 registersForMetricUpdatesWhenOnChangeReportCreated)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001132{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001133 std::vector<const interfaces::MetricListener*> args;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001134 for (auto& metric : metricMocks)
1135 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001136 EXPECT_CALL(*metric, registerForUpdates(_))
1137 .WillOnce(Invoke([&args](const interfaces::MetricListener& report) {
1138 args.emplace_back(&report);
1139 }));
1140 ;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001141 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001142
1143 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1144
1145 EXPECT_THAT(args, SizeIs(metricMocks.size()));
1146 for (const auto* reportPtr : args)
1147 {
1148 EXPECT_THAT(reportPtr, Eq(sut.get()));
1149 }
1150}
1151
1152TEST_F(TestReportInitialization,
1153 deregistersForMetricUpdatesWhenOnChangeReportDestroyed)
1154{
1155 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1156
1157 for (auto& metric : metricMocks)
1158 {
1159 EXPECT_CALL(*metric,
1160 unregisterFromUpdates(Ref(
1161 static_cast<interfaces::MetricListener&>(*sut.get()))));
1162 }
1163
1164 sut = nullptr;
1165}
1166
1167TEST_F(TestReportInitialization,
1168 metricsAreInitializedWhenEnabledReportConstructed)
1169{
1170 for (auto& metric : metricMocks)
1171 {
1172 EXPECT_CALL(*metric, initialize());
1173 }
1174 sut = makeReport(defaultParams().enabled(true));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001175}
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001176
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001177TEST_F(TestReportInitialization,
1178 metricsAreNotInitializedWhenDisabledReportConstructed)
1179{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001180 for (auto& metric : metricMocks)
1181 {
1182 EXPECT_CALL(*metric, initialize()).Times(0);
1183 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001184 sut = makeReport(defaultParams().enabled(false));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001185}
1186
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001187TEST_F(TestReportInitialization,
1188 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001189{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001190 EXPECT_CALL(readingsUpdated, Call())
1191 .WillOnce(
1192 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
1193
1194 const auto elapsed = DbusEnvironment::measureTime([this] {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001195 sut = makeReport(defaultParams()
1196 .reportingType(ReportingType::periodic)
1197 .reportActions({ReportAction::emitsReadingsUpdate})
1198 .interval(ReportManager::minInterval));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001199 makeMonitor();
1200 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
1201 });
1202
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001203 EXPECT_THAT(elapsed, AllOf(Ge(ReportManager::minInterval),
1204 Lt(ReportManager::minInterval * 2)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001205}
1206
1207TEST_F(TestReportInitialization,
1208 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
1209{
1210 EXPECT_CALL(readingsUpdated, Call()).Times(0);
1211
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001212 sut = makeReport(defaultParams()
1213 .reportingType(ReportingType::periodic)
1214 .reportActions({}));
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001215 makeMonitor();
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001216 DbusEnvironment::sleepFor(defaultParams().interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001217}
Szymon Dompke3eb56862021-09-20 15:32:04 +02001218
1219TEST_F(TestReportInitialization, appendLimitDeducedProperly)
1220{
1221 sut = makeReport(
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001222 defaultParams().appendLimit(std::numeric_limits<uint64_t>::max()));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001223 auto appendLimit = getProperty<uint64_t>(sut->getPath(), "AppendLimit");
1224 EXPECT_EQ(appendLimit, 2ull);
1225}
Krzysztof Grobelnye6c417c2022-02-02 17:25:53 +01001226
1227TEST_F(TestReportInitialization, appendLimitSetToUintMaxIsStoredCorrectly)
1228{
Krzysztof Grobelnye6c417c2022-02-02 17:25:53 +01001229 sut = makeReport(
1230 ReportParams().appendLimit(std::numeric_limits<uint64_t>::max()));
1231
1232 ASSERT_THAT(storedConfiguration.at("AppendLimit"),
1233 Eq(std::numeric_limits<uint64_t>::max()));
1234}
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001235
1236TEST_F(TestReportInitialization, triggerIdsPropertyIsInitialzed)
1237{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001238 for (const auto& triggerId : {"trigger1", "trigger2"})
1239 {
1240 messanger.on_receive<messages::CollectTriggerIdReq>(
Szymon Dompkee0ed5082022-05-20 10:54:25 +02001241 [this, triggerId](const auto& msg) {
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001242 messanger.send(messages::CollectTriggerIdResp{triggerId});
1243 });
1244 }
1245
1246 sut = makeReport(ReportParams());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001247
1248 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +02001249 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
1250 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
1251 utils::constants::triggerDirPath / "trigger2"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001252}
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001253
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +01001254TEST_F(TestReportInitialization,
1255 metricValuesAreNotStoredForReportUpdatesDifferentThanAppendStopsWhenFull)
1256{
1257 sut = makeReport(ReportParams()
1258 .reportingType(ReportingType::periodic)
1259 .interval(1h)
1260 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1261 .readings(Readings{{}, {{}}}));
1262
1263 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1264 Eq(storedConfiguration.end()));
1265}
1266
1267TEST_F(TestReportInitialization, metricValuesAreNotStoredForOnRequestReport)
1268{
1269 sut = makeReport(ReportParams()
1270 .reportingType(ReportingType::onRequest)
1271 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1272 .readings(Readings{{}, {{}}}));
1273
1274 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1275 Eq(storedConfiguration.end()));
1276}
1277
1278TEST_F(TestReportInitialization,
1279 metricValuesAreStoredForNonOnRequestReportWithAppendStopsWhenFull)
1280{
1281 const auto readings = Readings{{}, {{}}};
1282
1283 sut = makeReport(ReportParams()
1284 .reportingType(ReportingType::periodic)
1285 .interval(1h)
1286 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1287 .readings(readings));
1288
1289 ASSERT_THAT(storedConfiguration.at("MetricValues").get<LabeledReadings>(),
1290 Eq(utils::toLabeledReadings(readings)));
1291}
1292
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001293class TestReportInitializationOnChangeReport : public TestReportInitialization
1294{
1295 public:
1296 void SetUp() override
1297 {
1298 initMetricMocks(params.metricParameters());
1299 }
1300
1301 ReportParams params = defaultOnChangeParams();
1302};
1303
1304TEST_F(TestReportInitializationOnChangeReport,
1305 doesntUpdateReadingsWhenNotRequired)
1306{
1307 EXPECT_CALL(*metricMocks[0], updateReadings(_)).Times(0);
1308
1309 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(false));
1310
1311 sut = makeReport(params);
1312
1313 DbusEnvironment::sleepFor(500ms);
1314}
1315
1316TEST_F(TestReportInitializationOnChangeReport, updatesReadingsWhenRequired)
1317{
1318 EXPECT_CALL(*metricMocks[0], updateReadings(_))
1319 .WillOnce(Return())
1320 .WillOnce(
1321 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")))
1322 .WillRepeatedly(Return());
1323
1324 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(true));
1325
1326 sut = makeReport(params);
1327
1328 DbusEnvironment::waitForFuture("readingsUpdated");
1329}