blob: ac2419d7abf84b05b3a338d54c339b448c5b018c [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"
Krzysztof Grobelny51497a02021-11-09 14:56:22 +010019#include "utils/transform.hpp"
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000020#include "utils/tstring.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020021
22#include <sdbusplus/exception.hpp>
23
24using namespace testing;
25using namespace std::literals::string_literals;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020026using namespace std::chrono_literals;
Szymon Dompke1cdd7e42022-06-08 14:43:13 +020027using sdbusplus::message::object_path;
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000028namespace tstring = utils::tstring;
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020029
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +020030using ErrorMessageDbusType = std::tuple<std::string, std::string>;
31using ErrorMessagesDbusType = std::vector<ErrorMessageDbusType>;
32
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010033constexpr Milliseconds systemTimestamp = 55ms;
34
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +010035namespace
36{
37
38ReportParams defaultParams()
39{
40 return ReportParams();
41}
42
43ReportParams defaultOnChangeParams()
44{
45 return defaultParams().reportingType(ReportingType::onChange);
46}
47
48} // namespace
49
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020050class TestReport : public Test
51{
52 public:
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020053 std::unique_ptr<ReportManagerMock> reportManagerMock =
Wludzik, Jozefe2362792020-10-27 17:23:55 +010054 std::make_unique<NiceMock<ReportManagerMock>>();
Szymon Dompkefdb06a12022-02-11 11:04:44 +010055 std::unique_ptr<ReportFactoryMock> reportFactoryMock =
56 std::make_unique<NiceMock<ReportFactoryMock>>();
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +010057 nlohmann::json storedConfiguration;
Szymon Dompkefdb06a12022-02-11 11:04:44 +010058 NiceMock<StorageMock> storageMock;
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000059 std::vector<std::shared_ptr<MetricMock>> metricMocks;
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010060 std::unique_ptr<ClockFake> clockFakePtr = std::make_unique<ClockFake>();
61 ClockFake& clockFake = *clockFakePtr;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020062 std::unique_ptr<Report> sut;
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010063 utils::Messanger messanger;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020064
Wludzik, Jozefe2362792020-10-27 17:23:55 +010065 MockFunction<void()> checkPoint;
66
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010067 TestReport() : messanger(DbusEnvironment::getIoc())
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010068 {
69 clockFake.system.set(systemTimestamp);
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +010070 ON_CALL(storageMock, store(to_file_path(ReportParams().reportId()), _))
71 .WillByDefault(SaveArg<1>(&storedConfiguration));
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010072 }
73
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000074 void initMetricMocks(
75 const std::vector<LabeledMetricParameters>& metricParameters)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010076 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000077 for (auto i = metricMocks.size(); i < metricParameters.size(); ++i)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010078 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000079 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>());
80 }
81 metricMocks.resize(metricParameters.size());
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000082
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000083 std::vector<MetricValue> readings{{MetricValue{"a", "b", 17.1, 114},
84 MetricValue{"aa", "bb", 42.0, 74}}};
85 readings.resize(metricParameters.size());
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000086
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000087 for (size_t i = 0; i < metricParameters.size(); ++i)
88 {
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +010089 ON_CALL(*metricMocks[i], getUpdatedReadings())
90 .WillByDefault(ReturnRefOfCopy(std::vector({readings[i]})));
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000091 ON_CALL(*metricMocks[i], dumpConfiguration())
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000092 .WillByDefault(Return(metricParameters[i]));
Wludzik, Jozefe2362792020-10-27 17:23:55 +010093 }
94 }
95
Szymon Dompkefdb06a12022-02-11 11:04:44 +010096 std::vector<std::shared_ptr<interfaces::Metric>>
97 getMetricsFromReadingParams(const ReadingParameters& params)
98 {
99 const auto metricParameters =
100 reportFactoryMock->convertMetricParams(params);
101 std::vector<std::shared_ptr<MetricMock>> metricMocks;
102
103 for (size_t i = 0; i < metricParameters.size(); ++i)
104 {
105 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>());
106 ON_CALL(*metricMocks[i], dumpConfiguration())
107 .WillByDefault(Return(metricParameters[i]));
108 }
109
110 return utils::convContainer<std::shared_ptr<interfaces::Metric>>(
111 metricMocks);
112 }
113
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200114 void SetUp() override
115 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100116 sut = makeReport(defaultParams());
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200117 }
118
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100119 static interfaces::JsonStorage::FilePath to_file_path(std::string id)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100120 {
121 return interfaces::JsonStorage::FilePath(
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100122 std::to_string(std::hash<std::string>{}(id)));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100123 }
124
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200125 std::unique_ptr<Report> makeReport(const ReportParams& params)
126 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000127 initMetricMocks(params.metricParameters());
128
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200129 return std::make_unique<Report>(
130 DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100131 params.reportId(), params.reportName(), params.reportingType(),
132 params.reportActions(), params.interval(), params.appendLimit(),
133 params.reportUpdates(), *reportManagerMock, storageMock,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200134 utils::convContainer<std::shared_ptr<interfaces::Metric>>(
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200135 metricMocks),
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100136 *reportFactoryMock, params.enabled(), std::move(clockFakePtr),
137 params.readings());
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200138 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200139
140 template <class T>
141 static T getProperty(const std::string& path, const std::string& property)
142 {
Szymon Dompkee28aa532021-10-27 12:33:12 +0200143 return DbusEnvironment::getProperty<T>(path, Report::reportIfaceName,
144 property);
145 }
146
147 template <class T>
148 static boost::system::error_code setProperty(const std::string& path,
149 const std::string& property,
150 const T& newValue)
151 {
152 return DbusEnvironment::setProperty<T>(path, Report::reportIfaceName,
153 property, newValue);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100154 }
155
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200156 template <class T>
157 struct ChangePropertyParams
158 {
159 Matcher<T> valueBefore = _;
160 T newValue;
161 Matcher<boost::system::error_code> ec =
162 Eq(boost::system::errc::success);
163 Matcher<T> valueAfter = Eq(newValue);
164 };
165
166 template <class T>
167 static void changeProperty(const std::string& path,
168 const std::string& property,
169 ChangePropertyParams<T> p)
170 {
171 ASSERT_THAT(getProperty<T>(path, property), p.valueBefore);
172 ASSERT_THAT(setProperty<T>(path, property, p.newValue), p.ec);
173 EXPECT_THAT(getProperty<T>(path, property), p.valueAfter);
174 }
175
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100176 boost::system::error_code call(const std::string& path,
177 const std::string& interface,
178 const std::string& method)
179 {
180 std::promise<boost::system::error_code> methodPromise;
181 DbusEnvironment::getBus()->async_method_call(
182 [&methodPromise](boost::system::error_code ec) {
183 methodPromise.set_value(ec);
184 },
185 DbusEnvironment::serviceName(), path, interface, method);
186 return DbusEnvironment::waitForFuture(methodPromise.get_future());
187 }
188
189 boost::system::error_code update(const std::string& path)
190 {
191 return call(path, Report::reportIfaceName, "Update");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200192 }
193
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200194 boost::system::error_code deleteReport(const std::string& path)
195 {
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100196 return call(path, Report::deleteIfaceName, "Delete");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200197 }
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200198
199 static std::pair<std::string, std::vector<std::string>>
200 makeStateDetail(const std::string& detailType,
201 std::vector<std::string> detailArgs)
202 {
203 return make_pair(detailType, detailArgs);
204 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200205};
206
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100207TEST_F(TestReport, returnsId)
208{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100209 EXPECT_THAT(sut->getId(), Eq(defaultParams().reportId()));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100210}
211
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200212TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
213{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200214 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100215 Eq(defaultParams().enabled()));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200216 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100217 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100218 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100219 EXPECT_THAT(
220 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100221 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100222 return utils::enumToString(v);
223 })));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200224 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100225 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100226 ReportAction::emitsReadingsUpdate)));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200227 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "AppendLimit"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100228 Eq(defaultParams().appendLimit()));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100229 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100230 Eq(utils::enumToString(defaultParams().reportingType())));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200231 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportUpdates"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100232 Eq(utils::enumToString(defaultParams().reportUpdates())));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200233 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200234 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100235 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100236 ReportAction::logToMetricReportsCollection)));
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000237 EXPECT_THAT(getProperty<ReadingParameters>(
238 sut->getPath(), "ReadingParametersFutureVersion"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100239 Eq(toReadingParameters(defaultParams().metricParameters())));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100240 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100241 Eq(defaultParams().reportName()));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100242 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200243 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200244 IsEmpty());
245 EXPECT_THAT(
246 getProperty<ErrorMessagesDbusType>(sut->getPath(), "ErrorMessages"),
247 IsEmpty());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200248}
249
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200250TEST_F(TestReport, readingsAreInitialyEmpty)
251{
252 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
253 Eq(Readings{}));
254}
255
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100256TEST_F(TestReport, setReadingParametersWithNewParams)
257{
258 ReadingParameters newParams = toReadingParameters(
259 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
260 {LabeledSensorInfo{"Service",
261 "/xyz/openbmc_project/sensors/power/psu",
262 "NewMetadata123"}},
263 OperationType::avg,
264 "NewMetricId123",
265 CollectionTimeScope::startup,
266 CollectionDuration(250ms)}}});
267 auto metrics = getMetricsFromReadingParams(newParams);
268
269 EXPECT_CALL(*reportFactoryMock, updateMetrics(_, _, _))
270 .WillOnce(SetArgReferee<0>(metrics));
271 EXPECT_THAT(
272 setProperty(sut->getPath(), "ReadingParametersFutureVersion", newParams)
273 .value(),
274 Eq(boost::system::errc::success));
275 EXPECT_THAT(getProperty<ReadingParameters>(
276 sut->getPath(), "ReadingParametersFutureVersion"),
277 Eq(newParams));
278}
279
280TEST_F(TestReport, setReportingTypeWithValidNewType)
281{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200282 changeProperty<std::string>(
283 sut->getPath(), "ReportingType",
284 {.valueBefore = Not(Eq(utils::enumToString(ReportingType::onRequest))),
285 .newValue = utils::enumToString(ReportingType::onRequest)});
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100286}
287
288TEST_F(TestReport, setReportingTypeWithInvalidType)
289{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200290 const std::string currentValue =
291 utils::enumToString(defaultParams().reportingType());
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100292
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200293 changeProperty<std::string>(
294 sut->getPath(), "ReportingType",
295 {.valueBefore = Eq(currentValue),
296 .newValue = "Periodic_ABC",
297 .ec = Eq(boost::system::errc::invalid_argument),
298 .valueAfter = Eq(currentValue)});
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100299}
300
301TEST_F(TestReport, setReportActionsWithValidNewActions)
302{
303 std::vector<std::string> newActions = {"EmitsReadingsUpdate"};
304 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100305 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100306 [](const auto v) { return utils::enumToString(v); });
307
308 EXPECT_THAT(newActions, Ne(currActions));
309 EXPECT_THAT(
310 setProperty(sut->getPath(), "ReportActions", newActions).value(),
311 Eq(boost::system::errc::success));
312 EXPECT_THAT(
313 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
314 UnorderedElementsAre("EmitsReadingsUpdate",
315 "LogToMetricReportsCollection"));
316}
317
318TEST_F(TestReport, setReportActionsWithValidUnsortedActions)
319{
320 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
321 "EmitsReadingsUpdate"};
322 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
323 "LogToMetricReportsCollection"};
324 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100325 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100326 [](const auto v) { return utils::enumToString(v); });
327
328 EXPECT_THAT(newActions, Ne(currActions));
329 EXPECT_THAT(
330 setProperty(sut->getPath(), "ReportActions", newActions).value(),
331 Eq(boost::system::errc::success));
332 EXPECT_THAT(
333 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
334 Eq(expectedActions));
335}
336
337TEST_F(TestReport, setReportActionsWithEmptyActions)
338{
339 std::vector<std::string> newActions = {};
340 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
341 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100342 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100343 [](const auto v) { return utils::enumToString(v); });
344
345 EXPECT_THAT(newActions, Ne(currActions));
346 EXPECT_THAT(
347 setProperty(sut->getPath(), "ReportActions", newActions).value(),
348 Eq(boost::system::errc::success));
349 EXPECT_THAT(
350 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
351 Eq(expectedActions));
352}
353
354TEST_F(TestReport, setReportActionsWithInvalidActions)
355{
356 std::vector<std::string> invalidActions = {"EmitsReadingsUpdate_1"};
357 EXPECT_THAT(
358 setProperty(sut->getPath(), "ReportActions", invalidActions).value(),
359 Eq(boost::system::errc::invalid_argument));
360 EXPECT_THAT(
361 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100362 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100363 return utils::enumToString(v);
364 })));
365}
366
367TEST_F(TestReport, createReportWithEmptyActions)
368{
369 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
370
371 sut = makeReport(ReportParams().reportId("TestId_1").reportActions({}));
372 EXPECT_THAT(
373 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
374 Eq(expectedActions));
375}
376
377TEST_F(TestReport, createReportWithValidUnsortedActions)
378{
379 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
380 "EmitsReadingsUpdate"};
381 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
382 "LogToMetricReportsCollection"};
383
384 sut = makeReport(
385 ReportParams()
386 .reportId("TestId_1")
387 .reportActions(utils::transform(newActions, [](const auto& action) {
388 return utils::toReportAction(action);
389 })));
390 EXPECT_THAT(
391 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
392 Eq(expectedActions));
393}
394
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200395TEST_F(TestReport, setEnabledWithNewValue)
396{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100397 bool newValue = !defaultParams().enabled();
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200398 EXPECT_THAT(setProperty(sut->getPath(), "Enabled", newValue).value(),
399 Eq(boost::system::errc::success));
400 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(newValue));
401}
402
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200403TEST_F(TestReport, setIntervalWithValidValue)
404{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200405 uint64_t newValue = ReportManager::minInterval.count() * 42;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200406 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200407 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200408 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
409 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200410}
411
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100412TEST_F(
413 TestReport,
414 settingIntervalWithInvalidValueDoesNotChangePropertyAndReturnsInvalidArgument)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200415{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200416 uint64_t newValue = ReportManager::minInterval.count() - 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200417 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100418 Eq(boost::system::errc::invalid_argument));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200419 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100420 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100421}
422
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200423TEST_F(TestReport, settingInvalidReportingTypeCreatesErrorMessage)
424{
425 auto report = makeReport(defaultParams()
426 .reportId("report2")
427 .reportingType(ReportingType::onRequest)
428 .interval(Milliseconds{0}));
429
430 EXPECT_THAT(
431 setProperty<std::string>(report->getPath(), "ReportingType", "Periodic")
432 .value(),
433 Eq(boost::system::errc::success));
434
435 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
436 Eq("Periodic"));
437 EXPECT_THAT(
438 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
439 UnorderedElementsAre(
440 ErrorMessageDbusType(
441 utils::enumToString(ErrorType::propertyConflict), "Interval"),
442 ErrorMessageDbusType(
443 utils::enumToString(ErrorType::propertyConflict),
444 "ReportingType")));
445}
446
447TEST_F(TestReport, settingValidReportingTypeRemovesErrors)
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 EXPECT_THAT(setProperty<std::string>(report->getPath(), "ReportingType",
459 "OnRequest")
460 .value(),
461 Eq(boost::system::errc::success));
462
463 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
464 Eq("OnRequest"));
465 EXPECT_THAT(
466 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
467 IsEmpty());
468}
469
470TEST_F(TestReport, settingInvalidIntervalDisablesReport)
471{
472 auto report = makeReport(defaultParams()
473 .reportId("report2")
474 .reportingType(ReportingType::periodic)
475 .interval(ReportManager::minInterval));
476
477 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval", 0).value(),
478 Eq(boost::system::errc::success));
479
480 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"), Eq(0u));
481 EXPECT_THAT(
482 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
483 UnorderedElementsAre(
484 ErrorMessageDbusType(
485 utils::enumToString(ErrorType::propertyConflict), "Interval"),
486 ErrorMessageDbusType(
487 utils::enumToString(ErrorType::propertyConflict),
488 "ReportingType")));
489}
490
491TEST_F(TestReport, settingValidIntervalEnablesReport)
492{
493 auto report = makeReport(defaultParams()
494 .reportId("report2")
495 .reportingType(ReportingType::periodic)
496 .interval(ReportManager::minInterval));
497
498 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval", 0).value(),
499 Eq(boost::system::errc::success));
500 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval",
501 ReportManager::minInterval.count())
502 .value(),
503 Eq(boost::system::errc::success));
504
505 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"),
506 Eq(ReportManager::minInterval.count()));
507 EXPECT_THAT(
508 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
509 IsEmpty());
510}
511
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200512TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
513{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100514 EXPECT_THAT(
515 setProperty(sut->getPath(), "EmitsReadingsUpdate", true).value(),
516 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200517 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100518 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100519 ReportAction::emitsReadingsUpdate)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200520}
521
522TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
523{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100524 EXPECT_THAT(
525 setProperty(sut->getPath(), "LogToMetricReportsCollection", true)
526 .value(),
527 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200528 EXPECT_THAT(
529 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100530 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100531 ReportAction::logToMetricReportsCollection)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200532}
533
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100534TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
535{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100536 EXPECT_CALL(storageMock, store(_, _)).Times(0);
537 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
538 .Times(AtLeast(1));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100539
540 bool persistency = false;
541 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
542 Eq(boost::system::errc::success));
543 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
544 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200545}
546
547TEST_F(TestReport, deleteReport)
548{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200549 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
550 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200551 EXPECT_THAT(ec, Eq(boost::system::errc::success));
552}
553
554TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
555{
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200556 auto ec =
557 deleteReport(utils::constants::reportDirPath.str + "NonExisting"s);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200558 EXPECT_THAT(ec.value(), Eq(EBADR));
559}
560
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100561TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
562{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100563 EXPECT_CALL(storageMock, store(_, _)).Times(0);
564 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
565 .Times(AtLeast(1));
566
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100567 auto ec = deleteReport(sut->getPath());
568 EXPECT_THAT(ec, Eq(boost::system::errc::success));
569}
570
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100571TEST_F(TestReport, updatesTriggerIdWhenTriggerIsAdded)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100572{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100573 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100574
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100575 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100576 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100577 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100578 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100579 messanger.send(messages::TriggerPresenceChangedInd{
580 messages::Presence::Exist, "trigger2", {"someOtherReport"}});
581 messanger.send(messages::TriggerPresenceChangedInd{
582 messages::Presence::Exist,
583 "trigger3",
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100584 {"someOtherReport", defaultParams().reportId()}});
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100585
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100586 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200587 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
588 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
589 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100590}
591
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100592TEST_F(TestReport, updatesTriggerIdWhenTriggerIsRemoved)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100593{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100594 utils::Messanger messanger(DbusEnvironment::getIoc());
595
596 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100597 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100598 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100599 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100600 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100601 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100602
603 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100604 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100605 messanger.send(messages::TriggerPresenceChangedInd{
606 messages::Presence::Removed, "trigger2", {}});
607 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100608 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +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 / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100613}
614
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100615TEST_F(TestReport, updatesTriggerIdWhenTriggerIsModified)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100616{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100617 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100618
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100619 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100620 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100621 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100622 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100623 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100624 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100625
626 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100627 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100628 messanger.send(messages::TriggerPresenceChangedInd{
629 messages::Presence::Exist, "trigger2", {}});
630 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100631 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100632
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100633 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200634 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
635 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
636 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100637}
638
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100639class TestReportStore :
640 public TestReport,
641 public WithParamInterface<std::pair<std::string, nlohmann::json>>
642{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100643 void SetUp() override
644 {}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100645};
646
647INSTANTIATE_TEST_SUITE_P(
648 _, TestReportStore,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100649 Values(
650 std::make_pair("Enabled"s, nlohmann::json(defaultParams().enabled())),
651 std::make_pair("Version"s, nlohmann::json(6)),
652 std::make_pair("Id"s, nlohmann::json(defaultParams().reportId())),
653 std::make_pair("Name"s, nlohmann::json(defaultParams().reportName())),
654 std::make_pair("ReportingType",
655 nlohmann::json(defaultParams().reportingType())),
656 std::make_pair("ReportActions", nlohmann::json(utils::transform(
657 defaultParams().reportActions(),
658 [](const auto v) {
659 return utils::toUnderlying(v);
660 }))),
661 std::make_pair("Interval",
662 nlohmann::json(defaultParams().interval().count())),
663 std::make_pair("AppendLimit",
664 nlohmann::json(ReportParams().appendLimit())),
665 std::make_pair(
666 "ReadingParameters",
667 nlohmann::json(
668 {{{tstring::SensorPath::str(),
669 {{{tstring::Service::str(), "Service"},
670 {tstring::Path::str(),
671 "/xyz/openbmc_project/sensors/power/p1"},
672 {tstring::Metadata::str(), "metadata1"}}}},
673 {tstring::OperationType::str(), OperationType::avg},
674 {tstring::Id::str(), "MetricId1"},
675 {tstring::CollectionTimeScope::str(),
676 CollectionTimeScope::point},
677 {tstring::CollectionDuration::str(), 0}},
678 {{tstring::SensorPath::str(),
679 {{{tstring::Service::str(), "Service"},
680 {tstring::Path::str(),
681 "/xyz/openbmc_project/sensors/power/p2"},
682 {tstring::Metadata::str(), "metadata2"}}}},
683 {tstring::OperationType::str(), OperationType::avg},
684 {tstring::Id::str(), "MetricId2"},
685 {tstring::CollectionTimeScope::str(),
686 CollectionTimeScope::point},
687 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100688
689TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
690{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100691 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100692
693 {
694 InSequence seq;
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100695 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100696 EXPECT_CALL(checkPoint, Call());
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100697 EXPECT_CALL(storageMock, store(to_file_path(sut->getId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100698 }
699
700 setProperty(sut->getPath(), "Persistency", false);
701 checkPoint.Call();
702 setProperty(sut->getPath(), "Persistency", true);
703
704 const auto& [key, value] = GetParam();
705
706 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
707}
708
709TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
710{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100711 EXPECT_CALL(storageMock,
712 store(to_file_path(defaultParams().reportId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100713
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100714 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100715
716 const auto& [key, value] = GetParam();
717
718 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
719}
720
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200721class TestReportValidNames :
722 public TestReport,
723 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200724{
725 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200726 void SetUp() override
727 {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200728};
729
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200730INSTANTIATE_TEST_SUITE_P(
731 ValidNames, TestReportValidNames,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100732 Values(defaultParams().reportName("Valid_1"),
733 defaultParams().reportName("Valid_1/Valid_2"),
734 defaultParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200735
736TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
737{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200738 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200739}
740
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100741class TestReportInvalidIds :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200742 public TestReport,
743 public WithParamInterface<ReportParams>
744{
745 public:
746 void SetUp() override
747 {}
748};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200749
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100750INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidIds,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100751 Values(defaultParams().reportId("/"),
752 defaultParams().reportId("/Invalid"),
753 defaultParams().reportId("Invalid/"),
754 defaultParams().reportId("Invalid/Invalid/"),
755 defaultParams().reportId("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200756
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100757TEST_P(TestReportInvalidIds, failsToCreateReportWithInvalidName)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100758{
759 EXPECT_CALL(storageMock, store).Times(0);
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100760
761 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100762}
763
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200764class TestReportAllReportTypes :
765 public TestReport,
766 public WithParamInterface<ReportParams>
767{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200768 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200769 void SetUp() override
770 {
771 sut = makeReport(GetParam());
772 }
773};
774
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100775INSTANTIATE_TEST_SUITE_P(
776 _, TestReportAllReportTypes,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100777 Values(defaultParams().reportingType(ReportingType::onRequest),
778 defaultParams().reportingType(ReportingType::onChange),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200779 defaultParams()
780 .reportingType(ReportingType::periodic)
781 .interval(ReportManager::minInterval)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200782
783TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
784{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100785 EXPECT_THAT(utils::toReportingType(
786 getProperty<std::string>(sut->getPath(), "ReportingType")),
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200787 Eq(GetParam().reportingType()));
788}
789
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100790TEST_P(TestReportAllReportTypes, readingsAreUpdated)
791{
792 clockFake.system.advance(10ms);
793
794 messanger.send(messages::UpdateReportInd{{sut->getId()}});
795 const auto [timestamp, readings] =
796 getProperty<Readings>(sut->getPath(), "Readings");
797
798 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
799}
800
801TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIsDisabled)
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200802{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100803 clockFake.system.advance(10ms);
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200804
805 setProperty(sut->getPath(), "Enabled", false);
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100806 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200807 const auto [timestamp, readings] =
808 getProperty<Readings>(sut->getPath(), "Readings");
809
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100810 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200811}
812
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100813TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIdDiffers)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100814{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100815 clockFake.system.advance(10ms);
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100816
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100817 messanger.send(messages::UpdateReportInd{{sut->getId() + "x"s}});
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100818 const auto [timestamp, readings] =
819 getProperty<Readings>(sut->getPath(), "Readings");
820
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100821 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100822}
823
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100824class TestReportOnRequestType : public TestReport
825{
826 void SetUp() override
827 {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100828 sut =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100829 makeReport(defaultParams().reportingType(ReportingType::onRequest));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100830 }
831};
832
833TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
834{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100835 clockFake.system.advance(10ms);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100836
837 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
838
839 const auto [timestamp, readings] =
840 getProperty<Readings>(sut->getPath(), "Readings");
841
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100842 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100843}
844
845TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
846{
847 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
848
849 const auto [timestamp, readings] =
850 getProperty<Readings>(sut->getPath(), "Readings");
851
852 EXPECT_THAT(readings,
853 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000854 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100855}
856
857class TestReportNonOnRequestType :
858 public TestReport,
859 public WithParamInterface<ReportParams>
860{
861 void SetUp() override
862 {
863 sut = makeReport(GetParam());
864 }
865};
866
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100867INSTANTIATE_TEST_SUITE_P(
868 _, TestReportNonOnRequestType,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100869 Values(defaultParams().reportingType(ReportingType::periodic),
870 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100871
872TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
873{
874 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
875
876 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
877 Eq(Readings{}));
878}
879
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200880class TestReportNonPeriodicReport :
881 public TestReport,
882 public WithParamInterface<ReportParams>
883{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200884 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200885 void SetUp() override
886 {
887 sut = makeReport(GetParam());
888 }
889};
890
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100891INSTANTIATE_TEST_SUITE_P(
892 _, TestReportNonPeriodicReport,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100893 Values(defaultParams().reportingType(ReportingType::onRequest),
894 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200895
896TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
897{
898 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
899
900 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
901 Eq(Readings{}));
902}
903
904class TestReportPeriodicReport : public TestReport
905{
906 void SetUp() override
907 {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200908 sut = makeReport(defaultParams()
909 .reportingType(ReportingType::periodic)
910 .interval(ReportManager::minInterval));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200911 }
912};
913
914TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
915{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100916 clockFake.system.advance(10ms);
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200917 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
918
919 const auto [timestamp, readings] =
920 getProperty<Readings>(sut->getPath(), "Readings");
921
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100922 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200923}
924
925TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
926{
927 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
928
929 const auto [timestamp, readings] =
930 getProperty<Readings>(sut->getPath(), "Readings");
931
932 EXPECT_THAT(readings,
933 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000934 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200935}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100936
Szymon Dompke3eb56862021-09-20 15:32:04 +0200937struct ReportUpdatesReportParams
938{
939 ReportParams reportParams;
940 std::vector<ReadingData> expectedReadings;
941 bool expectedEnabled;
942};
943
944class TestReportWithReportUpdatesAndLimit :
945 public TestReport,
946 public WithParamInterface<ReportUpdatesReportParams>
947{
948 void SetUp() override
949 {
950 sut = makeReport(ReportParams(GetParam().reportParams)
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100951 .reportingType(ReportingType::periodic)
Szymon Dompke3eb56862021-09-20 15:32:04 +0200952 .interval(std::chrono::hours(1000)));
953 }
954};
955
956INSTANTIATE_TEST_SUITE_P(
957 _, TestReportWithReportUpdatesAndLimit,
958 Values(
959 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100960 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100961 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
962 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200963 std::vector<ReadingData>{{std::make_tuple("aa"s, "bb"s, 42.0, 74u),
964 std::make_tuple("a"s, "b"s, 17.1, 114u),
965 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
966 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
967 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
968 true},
969 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100970 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100971 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
972 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200973 std::vector<ReadingData>{
974 {std::make_tuple("a"s, "b"s, 17.1, 114u),
975 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
976 std::make_tuple("a"s, "b"s, 17.1, 114u),
977 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
978 true},
979 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100980 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100981 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
982 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200983 std::vector<ReadingData>{}, true},
984 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100985 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100986 .reportUpdates(ReportUpdates::appendStopsWhenFull)
987 .appendLimit(10),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200988 std::vector<ReadingData>{
989 {std::make_tuple("a"s, "b"s, 17.1, 114u),
990 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
991 std::make_tuple("a"s, "b"s, 17.1, 114u),
992 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
993 std::make_tuple("a"s, "b"s, 17.1, 114u),
994 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
995 std::make_tuple("a"s, "b"s, 17.1, 114u),
996 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
997 true},
998 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100999 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001000 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1001 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001002 std::vector<ReadingData>{{std::make_tuple("a"s, "b"s, 17.1, 114u),
1003 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1004 std::make_tuple("a"s, "b"s, 17.1, 114u),
1005 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1006 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
1007 false},
1008 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001009 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001010 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1011 .appendLimit(4),
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 false},
1018 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001019 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001020 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1021 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001022 std::vector<ReadingData>{}, false},
1023 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001024 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001025 .reportUpdates(ReportUpdates::overwrite)
1026 .appendLimit(500),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001027 std::vector<ReadingData>{
1028 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1029 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1030 true},
1031 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001032 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001033 .reportUpdates(ReportUpdates::overwrite)
1034 .appendLimit(1),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001035 std::vector<ReadingData>{
1036 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1037 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1038 true},
1039 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001040 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001041 .reportUpdates(ReportUpdates::overwrite)
1042 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001043 std::vector<ReadingData>{
1044 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1045 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1046 true}));
1047
1048TEST_P(TestReportWithReportUpdatesAndLimit,
1049 readingsAreUpdatedAfterIntervalExpires)
1050{
1051 for (int i = 0; i < 4; i++)
1052 {
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001053 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Szymon Dompke3eb56862021-09-20 15:32:04 +02001054 }
1055
1056 const auto [timestamp, readings] =
1057 getProperty<Readings>(sut->getPath(), "Readings");
1058 const auto enabled = getProperty<bool>(sut->getPath(), "Enabled");
1059
1060 EXPECT_THAT(readings, ElementsAreArray(GetParam().expectedReadings));
1061 EXPECT_EQ(enabled, GetParam().expectedEnabled);
1062}
1063
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001064class TestReportInitialization : public TestReport
1065{
1066 public:
1067 void SetUp() override
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001068 {
1069 initMetricMocks(defaultParams().metricParameters());
1070 }
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001071
1072 void monitorProc(sdbusplus::message::message& msg)
1073 {
1074 std::string iface;
1075 std::vector<std::pair<std::string, std::variant<Readings>>>
1076 changed_properties;
1077 std::vector<std::string> invalidated_properties;
1078
1079 msg.read(iface, changed_properties, invalidated_properties);
1080
1081 if (iface == Report::reportIfaceName)
1082 {
1083 for (const auto& [name, value] : changed_properties)
1084 {
1085 if (name == "Readings")
1086 {
1087 readingsUpdated.Call();
1088 }
1089 }
1090 }
1091 }
1092
1093 void makeMonitor()
1094 {
Patrick Williams3a62ee12021-12-03 10:13:25 -06001095 monitor = std::make_unique<sdbusplus::bus::match_t>(
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001096 *DbusEnvironment::getBus(),
1097 sdbusplus::bus::match::rules::propertiesChanged(
1098 sut->getPath(), Report::reportIfaceName),
1099 [this](auto& msg) { monitorProc(msg); });
1100 }
1101
Patrick Williams3a62ee12021-12-03 10:13:25 -06001102 std::unique_ptr<sdbusplus::bus::match_t> monitor;
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001103 MockFunction<void()> readingsUpdated;
1104};
1105
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001106TEST_F(TestReportInitialization,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001107 registersForMetricUpdatesWhenOnChangeReportCreated)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001108{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001109 std::vector<const interfaces::MetricListener*> args;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001110 for (auto& metric : metricMocks)
1111 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001112 EXPECT_CALL(*metric, registerForUpdates(_))
1113 .WillOnce(Invoke([&args](const interfaces::MetricListener& report) {
1114 args.emplace_back(&report);
1115 }));
1116 ;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001117 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001118
1119 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1120
1121 EXPECT_THAT(args, SizeIs(metricMocks.size()));
1122 for (const auto* reportPtr : args)
1123 {
1124 EXPECT_THAT(reportPtr, Eq(sut.get()));
1125 }
1126}
1127
1128TEST_F(TestReportInitialization,
1129 deregistersForMetricUpdatesWhenOnChangeReportDestroyed)
1130{
1131 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1132
1133 for (auto& metric : metricMocks)
1134 {
1135 EXPECT_CALL(*metric,
1136 unregisterFromUpdates(Ref(
1137 static_cast<interfaces::MetricListener&>(*sut.get()))));
1138 }
1139
1140 sut = nullptr;
1141}
1142
1143TEST_F(TestReportInitialization,
1144 metricsAreInitializedWhenEnabledReportConstructed)
1145{
1146 for (auto& metric : metricMocks)
1147 {
1148 EXPECT_CALL(*metric, initialize());
1149 }
1150 sut = makeReport(defaultParams().enabled(true));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001151}
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001152
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001153TEST_F(TestReportInitialization,
1154 metricsAreNotInitializedWhenDisabledReportConstructed)
1155{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001156 for (auto& metric : metricMocks)
1157 {
1158 EXPECT_CALL(*metric, initialize()).Times(0);
1159 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001160 sut = makeReport(defaultParams().enabled(false));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001161}
1162
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001163TEST_F(TestReportInitialization,
1164 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001165{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001166 EXPECT_CALL(readingsUpdated, Call())
1167 .WillOnce(
1168 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
1169
1170 const auto elapsed = DbusEnvironment::measureTime([this] {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001171 sut = makeReport(defaultParams()
1172 .reportingType(ReportingType::periodic)
1173 .reportActions({ReportAction::emitsReadingsUpdate})
1174 .interval(ReportManager::minInterval));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001175 makeMonitor();
1176 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
1177 });
1178
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001179 EXPECT_THAT(elapsed, AllOf(Ge(ReportManager::minInterval),
1180 Lt(ReportManager::minInterval * 2)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001181}
1182
1183TEST_F(TestReportInitialization,
1184 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
1185{
1186 EXPECT_CALL(readingsUpdated, Call()).Times(0);
1187
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001188 sut = makeReport(defaultParams()
1189 .reportingType(ReportingType::periodic)
1190 .reportActions({}));
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001191 makeMonitor();
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001192 DbusEnvironment::sleepFor(defaultParams().interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001193}
Szymon Dompke3eb56862021-09-20 15:32:04 +02001194
1195TEST_F(TestReportInitialization, appendLimitDeducedProperly)
1196{
1197 sut = makeReport(
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001198 defaultParams().appendLimit(std::numeric_limits<uint64_t>::max()));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001199 auto appendLimit = getProperty<uint64_t>(sut->getPath(), "AppendLimit");
1200 EXPECT_EQ(appendLimit, 2ull);
1201}
Krzysztof Grobelnye6c417c2022-02-02 17:25:53 +01001202
1203TEST_F(TestReportInitialization, appendLimitSetToUintMaxIsStoredCorrectly)
1204{
Krzysztof Grobelnye6c417c2022-02-02 17:25:53 +01001205 sut = makeReport(
1206 ReportParams().appendLimit(std::numeric_limits<uint64_t>::max()));
1207
1208 ASSERT_THAT(storedConfiguration.at("AppendLimit"),
1209 Eq(std::numeric_limits<uint64_t>::max()));
1210}
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001211
1212TEST_F(TestReportInitialization, triggerIdsPropertyIsInitialzed)
1213{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001214 for (const auto& triggerId : {"trigger1", "trigger2"})
1215 {
1216 messanger.on_receive<messages::CollectTriggerIdReq>(
Szymon Dompkee0ed5082022-05-20 10:54:25 +02001217 [this, triggerId](const auto& msg) {
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001218 messanger.send(messages::CollectTriggerIdResp{triggerId});
1219 });
1220 }
1221
1222 sut = makeReport(ReportParams());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001223
1224 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +02001225 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
1226 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
1227 utils::constants::triggerDirPath / "trigger2"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001228}
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001229
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +01001230TEST_F(TestReportInitialization,
1231 metricValuesAreNotStoredForReportUpdatesDifferentThanAppendStopsWhenFull)
1232{
1233 sut = makeReport(ReportParams()
1234 .reportingType(ReportingType::periodic)
1235 .interval(1h)
1236 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1237 .readings(Readings{{}, {{}}}));
1238
1239 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1240 Eq(storedConfiguration.end()));
1241}
1242
1243TEST_F(TestReportInitialization, metricValuesAreNotStoredForOnRequestReport)
1244{
1245 sut = makeReport(ReportParams()
1246 .reportingType(ReportingType::onRequest)
1247 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1248 .readings(Readings{{}, {{}}}));
1249
1250 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1251 Eq(storedConfiguration.end()));
1252}
1253
1254TEST_F(TestReportInitialization,
1255 metricValuesAreStoredForNonOnRequestReportWithAppendStopsWhenFull)
1256{
1257 const auto readings = Readings{{}, {{}}};
1258
1259 sut = makeReport(ReportParams()
1260 .reportingType(ReportingType::periodic)
1261 .interval(1h)
1262 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1263 .readings(readings));
1264
1265 ASSERT_THAT(storedConfiguration.at("MetricValues").get<LabeledReadings>(),
1266 Eq(utils::toLabeledReadings(readings)));
1267}
1268
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001269class TestReportInitializationOnChangeReport : public TestReportInitialization
1270{
1271 public:
1272 void SetUp() override
1273 {
1274 initMetricMocks(params.metricParameters());
1275 }
1276
1277 ReportParams params = defaultOnChangeParams();
1278};
1279
1280TEST_F(TestReportInitializationOnChangeReport,
1281 doesntUpdateReadingsWhenNotRequired)
1282{
1283 EXPECT_CALL(*metricMocks[0], updateReadings(_)).Times(0);
1284
1285 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(false));
1286
1287 sut = makeReport(params);
1288
1289 DbusEnvironment::sleepFor(500ms);
1290}
1291
1292TEST_F(TestReportInitializationOnChangeReport, updatesReadingsWhenRequired)
1293{
1294 EXPECT_CALL(*metricMocks[0], updateReadings(_))
1295 .WillOnce(Return())
1296 .WillOnce(
1297 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")))
1298 .WillRepeatedly(Return());
1299
1300 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(true));
1301
1302 sut = makeReport(params);
1303
1304 DbusEnvironment::waitForFuture("readingsUpdated");
1305}