blob: 875bd4b9a0c02870958f7ac0e0a5bf9ed94aa046 [file] [log] [blame]
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +02001#include "dbus_environment.hpp"
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +01002#include "fakes/clock_fake.hpp"
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +00003#include "helpers.hpp"
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01004#include "messages/collect_trigger_id.hpp"
5#include "messages/trigger_presence_changed_ind.hpp"
6#include "messages/update_report_ind.hpp"
Wludzik, Jozefe2362792020-10-27 17:23:55 +01007#include "mocks/json_storage_mock.hpp"
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +02008#include "mocks/metric_mock.hpp"
Szymon Dompkefdb06a12022-02-11 11:04:44 +01009#include "mocks/report_factory_mock.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020010#include "mocks/report_manager_mock.hpp"
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020011#include "params/report_params.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020012#include "report.hpp"
13#include "report_manager.hpp"
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +010014#include "utils/clock.hpp"
Krzysztof Grobelny51497a02021-11-09 14:56:22 +010015#include "utils/contains.hpp"
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020016#include "utils/conv_container.hpp"
Szymon Dompke1cdd7e42022-06-08 14:43:13 +020017#include "utils/dbus_path_utils.hpp"
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010018#include "utils/messanger.hpp"
Szymon Dompke32305f12022-07-05 15:37:21 +020019#include "utils/string_utils.hpp"
Krzysztof Grobelny51497a02021-11-09 14:56:22 +010020#include "utils/transform.hpp"
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000021#include "utils/tstring.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020022
23#include <sdbusplus/exception.hpp>
24
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +020025#include <ranges>
26
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020027using namespace testing;
28using namespace std::literals::string_literals;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020029using namespace std::chrono_literals;
Szymon Dompke1cdd7e42022-06-08 14:43:13 +020030using sdbusplus::message::object_path;
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000031namespace tstring = utils::tstring;
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020032
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +020033using ErrorMessageDbusType = std::tuple<std::string, std::string>;
34using ErrorMessagesDbusType = std::vector<ErrorMessageDbusType>;
35
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010036constexpr Milliseconds systemTimestamp = 55ms;
37
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +010038namespace
39{
40
41ReportParams defaultParams()
42{
43 return ReportParams();
44}
45
46ReportParams defaultOnChangeParams()
47{
48 return defaultParams().reportingType(ReportingType::onChange);
49}
50
51} // namespace
52
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020053class TestReport : public Test
54{
55 public:
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020056 std::unique_ptr<ReportManagerMock> reportManagerMock =
Wludzik, Jozefe2362792020-10-27 17:23:55 +010057 std::make_unique<NiceMock<ReportManagerMock>>();
Szymon Dompkefdb06a12022-02-11 11:04:44 +010058 std::unique_ptr<ReportFactoryMock> reportFactoryMock =
59 std::make_unique<NiceMock<ReportFactoryMock>>();
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +010060 nlohmann::json storedConfiguration;
Szymon Dompkefdb06a12022-02-11 11:04:44 +010061 NiceMock<StorageMock> storageMock;
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000062 std::vector<std::shared_ptr<MetricMock>> metricMocks;
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010063 std::unique_ptr<ClockFake> clockFakePtr = std::make_unique<ClockFake>();
64 ClockFake& clockFake = *clockFakePtr;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020065 std::unique_ptr<Report> sut;
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010066 utils::Messanger messanger;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020067
Wludzik, Jozefe2362792020-10-27 17:23:55 +010068 MockFunction<void()> checkPoint;
69
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010070 TestReport() : messanger(DbusEnvironment::getIoc())
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010071 {
72 clockFake.system.set(systemTimestamp);
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +010073 ON_CALL(storageMock, store(to_file_path(ReportParams().reportId()), _))
74 .WillByDefault(SaveArg<1>(&storedConfiguration));
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010075 }
76
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000077 void initMetricMocks(
78 const std::vector<LabeledMetricParameters>& metricParameters)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010079 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000080 for (auto i = metricMocks.size(); i < metricParameters.size(); ++i)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010081 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000082 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>());
83 }
84 metricMocks.resize(metricParameters.size());
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000085
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000086 std::vector<MetricValue> readings{{MetricValue{"a", "b", 17.1, 114},
87 MetricValue{"aa", "bb", 42.0, 74}}};
Szymon Dompkebcf045a2022-09-16 15:23:30 +020088
89 ASSERT_THAT(readings.size(), Ge(metricParameters.size()));
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000090
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000091 for (size_t i = 0; i < metricParameters.size(); ++i)
92 {
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +010093 ON_CALL(*metricMocks[i], getUpdatedReadings())
94 .WillByDefault(ReturnRefOfCopy(std::vector({readings[i]})));
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000095 ON_CALL(*metricMocks[i], dumpConfiguration())
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000096 .WillByDefault(Return(metricParameters[i]));
Wludzik, Jozefe2362792020-10-27 17:23:55 +010097 }
98 }
99
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100100 std::vector<std::shared_ptr<interfaces::Metric>>
101 getMetricsFromReadingParams(const ReadingParameters& params)
102 {
103 const auto metricParameters =
104 reportFactoryMock->convertMetricParams(params);
105 std::vector<std::shared_ptr<MetricMock>> metricMocks;
106
107 for (size_t i = 0; i < metricParameters.size(); ++i)
108 {
109 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>());
110 ON_CALL(*metricMocks[i], dumpConfiguration())
111 .WillByDefault(Return(metricParameters[i]));
Krzysztof Grobelny18e71012022-11-02 13:17:01 +0000112 ON_CALL(*metricMocks[i], metricCount())
Szymon Dompke892f7c82022-10-12 09:54:22 +0200113 .WillByDefault(Return(metricParameters[i]
114 .at_label<tstring::SensorPath>()
115 .size()));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100116 }
117
118 return utils::convContainer<std::shared_ptr<interfaces::Metric>>(
119 metricMocks);
120 }
121
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200122 void SetUp() override
123 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100124 sut = makeReport(defaultParams());
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200125 }
126
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100127 static interfaces::JsonStorage::FilePath to_file_path(std::string id)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100128 {
129 return interfaces::JsonStorage::FilePath(
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100130 std::to_string(std::hash<std::string>{}(id)));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100131 }
132
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200133 std::unique_ptr<Report> makeReport(const ReportParams& params)
134 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000135 initMetricMocks(params.metricParameters());
136
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200137 return std::make_unique<Report>(
138 DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100139 params.reportId(), params.reportName(), params.reportingType(),
140 params.reportActions(), params.interval(), params.appendLimit(),
141 params.reportUpdates(), *reportManagerMock, storageMock,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200142 utils::convContainer<std::shared_ptr<interfaces::Metric>>(
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200143 metricMocks),
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100144 *reportFactoryMock, params.enabled(), std::move(clockFakePtr),
145 params.readings());
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200146 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200147
148 template <class T>
149 static T getProperty(const std::string& path, const std::string& property)
150 {
Szymon Dompkee28aa532021-10-27 12:33:12 +0200151 return DbusEnvironment::getProperty<T>(path, Report::reportIfaceName,
152 property);
153 }
154
155 template <class T>
156 static boost::system::error_code setProperty(const std::string& path,
157 const std::string& property,
158 const T& newValue)
159 {
160 return DbusEnvironment::setProperty<T>(path, Report::reportIfaceName,
161 property, newValue);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100162 }
163
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200164 template <class T>
165 struct ChangePropertyParams
166 {
167 Matcher<T> valueBefore = _;
168 T newValue;
169 Matcher<boost::system::error_code> ec =
170 Eq(boost::system::errc::success);
171 Matcher<T> valueAfter = Eq(newValue);
172 };
173
174 template <class T>
175 static void changeProperty(const std::string& path,
176 const std::string& property,
177 ChangePropertyParams<T> p)
178 {
179 ASSERT_THAT(getProperty<T>(path, property), p.valueBefore);
180 ASSERT_THAT(setProperty<T>(path, property, p.newValue), p.ec);
181 EXPECT_THAT(getProperty<T>(path, property), p.valueAfter);
182 }
183
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100184 boost::system::error_code call(const std::string& path,
185 const std::string& interface,
186 const std::string& method)
187 {
188 std::promise<boost::system::error_code> methodPromise;
189 DbusEnvironment::getBus()->async_method_call(
190 [&methodPromise](boost::system::error_code ec) {
191 methodPromise.set_value(ec);
192 },
193 DbusEnvironment::serviceName(), path, interface, method);
194 return DbusEnvironment::waitForFuture(methodPromise.get_future());
195 }
196
197 boost::system::error_code update(const std::string& path)
198 {
199 return call(path, Report::reportIfaceName, "Update");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200200 }
201
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200202 boost::system::error_code deleteReport(const std::string& path)
203 {
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100204 return call(path, Report::deleteIfaceName, "Delete");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200205 }
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200206
207 static std::pair<std::string, std::vector<std::string>>
208 makeStateDetail(const std::string& detailType,
209 std::vector<std::string> detailArgs)
210 {
211 return make_pair(detailType, detailArgs);
212 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200213};
214
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100215TEST_F(TestReport, returnsId)
216{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100217 EXPECT_THAT(sut->getId(), Eq(defaultParams().reportId()));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100218}
219
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200220TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
221{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200222 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100223 Eq(defaultParams().enabled()));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200224 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100225 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100226 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100227 EXPECT_THAT(
228 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100229 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100230 return utils::enumToString(v);
231 })));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200232 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100233 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100234 ReportAction::emitsReadingsUpdate)));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200235 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "AppendLimit"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100236 Eq(defaultParams().appendLimit()));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100237 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100238 Eq(utils::enumToString(defaultParams().reportingType())));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200239 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportUpdates"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100240 Eq(utils::enumToString(defaultParams().reportUpdates())));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200241 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200242 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100243 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100244 ReportAction::logToMetricReportsCollection)));
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000245 EXPECT_THAT(getProperty<ReadingParameters>(
246 sut->getPath(), "ReadingParametersFutureVersion"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100247 Eq(toReadingParameters(defaultParams().metricParameters())));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100248 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100249 Eq(defaultParams().reportName()));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100250 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200251 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200252 IsEmpty());
253 EXPECT_THAT(
254 getProperty<ErrorMessagesDbusType>(sut->getPath(), "ErrorMessages"),
255 IsEmpty());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200256}
257
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200258TEST_F(TestReport, readingsAreInitialyEmpty)
259{
260 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
261 Eq(Readings{}));
262}
263
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100264TEST_F(TestReport, setReadingParametersWithNewParams)
265{
266 ReadingParameters newParams = toReadingParameters(
267 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
268 {LabeledSensorInfo{"Service",
269 "/xyz/openbmc_project/sensors/power/psu",
270 "NewMetadata123"}},
271 OperationType::avg,
272 "NewMetricId123",
273 CollectionTimeScope::startup,
274 CollectionDuration(250ms)}}});
275 auto metrics = getMetricsFromReadingParams(newParams);
276
277 EXPECT_CALL(*reportFactoryMock, updateMetrics(_, _, _))
278 .WillOnce(SetArgReferee<0>(metrics));
279 EXPECT_THAT(
280 setProperty(sut->getPath(), "ReadingParametersFutureVersion", newParams)
281 .value(),
282 Eq(boost::system::errc::success));
283 EXPECT_THAT(getProperty<ReadingParameters>(
284 sut->getPath(), "ReadingParametersFutureVersion"),
285 Eq(newParams));
286}
287
Szymon Dompke32305f12022-07-05 15:37:21 +0200288TEST_F(TestReport, setReadingParametersWithTooLongMetricId)
289{
290 const ReadingParameters currentValue =
291 toReadingParameters(defaultParams().metricParameters());
292
293 ReadingParameters newParams = toReadingParameters(
294 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
295 {LabeledSensorInfo{"Service",
296 "/xyz/openbmc_project/sensors/power/psu",
297 "NewMetadata123"}},
298 OperationType::avg,
299 utils::string_utils::getTooLongId(),
300 CollectionTimeScope::startup,
301 CollectionDuration(250ms)}}});
302
303 changeProperty<ReadingParameters>(
304 sut->getPath(), "ReadingParametersFutureVersion",
305 {.valueBefore = Eq(currentValue),
306 .newValue = newParams,
307 .ec = Eq(boost::system::errc::invalid_argument),
308 .valueAfter = Eq(currentValue)});
309}
310
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100311TEST_F(TestReport, setReportingTypeWithValidNewType)
312{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200313 changeProperty<std::string>(
314 sut->getPath(), "ReportingType",
315 {.valueBefore = Not(Eq(utils::enumToString(ReportingType::onRequest))),
316 .newValue = utils::enumToString(ReportingType::onRequest)});
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100317}
318
319TEST_F(TestReport, setReportingTypeWithInvalidType)
320{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200321 const std::string currentValue =
322 utils::enumToString(defaultParams().reportingType());
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100323
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200324 changeProperty<std::string>(
325 sut->getPath(), "ReportingType",
326 {.valueBefore = Eq(currentValue),
327 .newValue = "Periodic_ABC",
328 .ec = Eq(boost::system::errc::invalid_argument),
329 .valueAfter = Eq(currentValue)});
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100330}
331
332TEST_F(TestReport, setReportActionsWithValidNewActions)
333{
334 std::vector<std::string> newActions = {"EmitsReadingsUpdate"};
335 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100336 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100337 [](const auto v) { return utils::enumToString(v); });
338
339 EXPECT_THAT(newActions, Ne(currActions));
340 EXPECT_THAT(
341 setProperty(sut->getPath(), "ReportActions", newActions).value(),
342 Eq(boost::system::errc::success));
343 EXPECT_THAT(
344 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
345 UnorderedElementsAre("EmitsReadingsUpdate",
346 "LogToMetricReportsCollection"));
347}
348
349TEST_F(TestReport, setReportActionsWithValidUnsortedActions)
350{
351 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
352 "EmitsReadingsUpdate"};
353 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
354 "LogToMetricReportsCollection"};
355 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100356 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100357 [](const auto v) { return utils::enumToString(v); });
358
359 EXPECT_THAT(newActions, Ne(currActions));
360 EXPECT_THAT(
361 setProperty(sut->getPath(), "ReportActions", newActions).value(),
362 Eq(boost::system::errc::success));
363 EXPECT_THAT(
364 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
365 Eq(expectedActions));
366}
367
368TEST_F(TestReport, setReportActionsWithEmptyActions)
369{
370 std::vector<std::string> newActions = {};
371 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
372 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100373 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100374 [](const auto v) { return utils::enumToString(v); });
375
376 EXPECT_THAT(newActions, Ne(currActions));
377 EXPECT_THAT(
378 setProperty(sut->getPath(), "ReportActions", newActions).value(),
379 Eq(boost::system::errc::success));
380 EXPECT_THAT(
381 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
382 Eq(expectedActions));
383}
384
385TEST_F(TestReport, setReportActionsWithInvalidActions)
386{
387 std::vector<std::string> invalidActions = {"EmitsReadingsUpdate_1"};
388 EXPECT_THAT(
389 setProperty(sut->getPath(), "ReportActions", invalidActions).value(),
390 Eq(boost::system::errc::invalid_argument));
391 EXPECT_THAT(
392 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100393 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100394 return utils::enumToString(v);
395 })));
396}
397
398TEST_F(TestReport, createReportWithEmptyActions)
399{
400 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"};
401
402 sut = makeReport(ReportParams().reportId("TestId_1").reportActions({}));
403 EXPECT_THAT(
404 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
405 Eq(expectedActions));
406}
407
408TEST_F(TestReport, createReportWithValidUnsortedActions)
409{
410 std::vector<std::string> newActions = {"LogToMetricReportsCollection",
411 "EmitsReadingsUpdate"};
412 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate",
413 "LogToMetricReportsCollection"};
414
415 sut = makeReport(
416 ReportParams()
417 .reportId("TestId_1")
418 .reportActions(utils::transform(newActions, [](const auto& action) {
419 return utils::toReportAction(action);
420 })));
421 EXPECT_THAT(
422 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
423 Eq(expectedActions));
424}
425
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200426TEST_F(TestReport, setEnabledWithNewValue)
427{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100428 bool newValue = !defaultParams().enabled();
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200429 EXPECT_THAT(setProperty(sut->getPath(), "Enabled", newValue).value(),
430 Eq(boost::system::errc::success));
431 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(newValue));
432}
433
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200434TEST_F(TestReport, setIntervalWithValidValue)
435{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200436 uint64_t newValue = ReportManager::minInterval.count() * 42;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200437 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200438 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200439 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
440 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200441}
442
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100443TEST_F(
444 TestReport,
445 settingIntervalWithInvalidValueDoesNotChangePropertyAndReturnsInvalidArgument)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200446{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200447 uint64_t newValue = ReportManager::minInterval.count() - 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200448 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100449 Eq(boost::system::errc::invalid_argument));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200450 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100451 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100452}
453
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200454TEST_F(TestReport, settingInvalidReportingTypeCreatesErrorMessage)
455{
456 auto report = makeReport(defaultParams()
457 .reportId("report2")
458 .reportingType(ReportingType::onRequest)
459 .interval(Milliseconds{0}));
460
461 EXPECT_THAT(
462 setProperty<std::string>(report->getPath(), "ReportingType", "Periodic")
463 .value(),
464 Eq(boost::system::errc::success));
465
466 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
467 Eq("Periodic"));
468 EXPECT_THAT(
469 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
470 UnorderedElementsAre(
471 ErrorMessageDbusType(
472 utils::enumToString(ErrorType::propertyConflict), "Interval"),
473 ErrorMessageDbusType(
474 utils::enumToString(ErrorType::propertyConflict),
475 "ReportingType")));
476}
477
478TEST_F(TestReport, settingValidReportingTypeRemovesErrors)
479{
480 auto report = makeReport(defaultParams()
481 .reportId("report2")
482 .reportingType(ReportingType::onRequest)
483 .interval(Milliseconds{0}));
484
485 EXPECT_THAT(
486 setProperty<std::string>(report->getPath(), "ReportingType", "Periodic")
487 .value(),
488 Eq(boost::system::errc::success));
489 EXPECT_THAT(setProperty<std::string>(report->getPath(), "ReportingType",
490 "OnRequest")
491 .value(),
492 Eq(boost::system::errc::success));
493
494 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
495 Eq("OnRequest"));
496 EXPECT_THAT(
497 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
498 IsEmpty());
499}
500
501TEST_F(TestReport, settingInvalidIntervalDisablesReport)
502{
503 auto report = makeReport(defaultParams()
504 .reportId("report2")
505 .reportingType(ReportingType::periodic)
506 .interval(ReportManager::minInterval));
507
508 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval", 0).value(),
509 Eq(boost::system::errc::success));
510
511 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"), Eq(0u));
512 EXPECT_THAT(
513 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
514 UnorderedElementsAre(
515 ErrorMessageDbusType(
516 utils::enumToString(ErrorType::propertyConflict), "Interval"),
517 ErrorMessageDbusType(
518 utils::enumToString(ErrorType::propertyConflict),
519 "ReportingType")));
520}
521
522TEST_F(TestReport, settingValidIntervalEnablesReport)
523{
524 auto report = makeReport(defaultParams()
525 .reportId("report2")
526 .reportingType(ReportingType::periodic)
527 .interval(ReportManager::minInterval));
528
529 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval", 0).value(),
530 Eq(boost::system::errc::success));
531 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval",
532 ReportManager::minInterval.count())
533 .value(),
534 Eq(boost::system::errc::success));
535
536 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"),
537 Eq(ReportManager::minInterval.count()));
538 EXPECT_THAT(
539 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"),
540 IsEmpty());
541}
542
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200543TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
544{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100545 EXPECT_THAT(
546 setProperty(sut->getPath(), "EmitsReadingsUpdate", true).value(),
547 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200548 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100549 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100550 ReportAction::emitsReadingsUpdate)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200551}
552
553TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
554{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100555 EXPECT_THAT(
556 setProperty(sut->getPath(), "LogToMetricReportsCollection", true)
557 .value(),
558 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200559 EXPECT_THAT(
560 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100561 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100562 ReportAction::logToMetricReportsCollection)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200563}
564
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100565TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
566{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100567 EXPECT_CALL(storageMock, store(_, _)).Times(0);
568 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
569 .Times(AtLeast(1));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100570
571 bool persistency = false;
572 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
573 Eq(boost::system::errc::success));
574 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
575 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200576}
577
578TEST_F(TestReport, deleteReport)
579{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200580 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
581 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200582 EXPECT_THAT(ec, Eq(boost::system::errc::success));
583}
584
585TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
586{
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200587 auto ec =
588 deleteReport(utils::constants::reportDirPath.str + "NonExisting"s);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200589 EXPECT_THAT(ec.value(), Eq(EBADR));
590}
591
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100592TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
593{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100594 EXPECT_CALL(storageMock, store(_, _)).Times(0);
595 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
596 .Times(AtLeast(1));
597
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100598 auto ec = deleteReport(sut->getPath());
599 EXPECT_THAT(ec, Eq(boost::system::errc::success));
600}
601
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100602TEST_F(TestReport, updatesTriggerIdWhenTriggerIsAdded)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100603{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100604 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100605
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100606 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100607 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100608 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100609 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100610 messanger.send(messages::TriggerPresenceChangedInd{
611 messages::Presence::Exist, "trigger2", {"someOtherReport"}});
612 messanger.send(messages::TriggerPresenceChangedInd{
613 messages::Presence::Exist,
614 "trigger3",
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100615 {"someOtherReport", defaultParams().reportId()}});
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100616
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100617 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200618 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
619 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
620 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100621}
622
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100623TEST_F(TestReport, updatesTriggerIdWhenTriggerIsRemoved)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100624{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100625 utils::Messanger messanger(DbusEnvironment::getIoc());
626
627 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100628 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100629 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100630 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100631 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100632 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100633
634 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100635 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100636 messanger.send(messages::TriggerPresenceChangedInd{
637 messages::Presence::Removed, "trigger2", {}});
638 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100639 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100640
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100641 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200642 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
643 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100644}
645
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100646TEST_F(TestReport, updatesTriggerIdWhenTriggerIsModified)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100647{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100648 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100649
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100650 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{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100653 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100654 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
657 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100658 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100659 messanger.send(messages::TriggerPresenceChangedInd{
660 messages::Presence::Exist, "trigger2", {}});
661 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100662 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100663
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100664 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200665 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
666 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
667 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100668}
669
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100670class TestReportStore :
671 public TestReport,
672 public WithParamInterface<std::pair<std::string, nlohmann::json>>
673{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100674 void SetUp() override
675 {}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100676};
677
678INSTANTIATE_TEST_SUITE_P(
679 _, TestReportStore,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100680 Values(
681 std::make_pair("Enabled"s, nlohmann::json(defaultParams().enabled())),
Krzysztof Grobelny18e71012022-11-02 13:17:01 +0000682 std::make_pair("Version"s, nlohmann::json(7)),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100683 std::make_pair("Id"s, nlohmann::json(defaultParams().reportId())),
684 std::make_pair("Name"s, nlohmann::json(defaultParams().reportName())),
685 std::make_pair("ReportingType",
686 nlohmann::json(defaultParams().reportingType())),
687 std::make_pair("ReportActions", nlohmann::json(utils::transform(
688 defaultParams().reportActions(),
689 [](const auto v) {
690 return utils::toUnderlying(v);
691 }))),
692 std::make_pair("Interval",
693 nlohmann::json(defaultParams().interval().count())),
694 std::make_pair("AppendLimit",
695 nlohmann::json(ReportParams().appendLimit())),
696 std::make_pair(
697 "ReadingParameters",
698 nlohmann::json(
699 {{{tstring::SensorPath::str(),
700 {{{tstring::Service::str(), "Service"},
701 {tstring::Path::str(),
702 "/xyz/openbmc_project/sensors/power/p1"},
703 {tstring::Metadata::str(), "metadata1"}}}},
704 {tstring::OperationType::str(), OperationType::avg},
705 {tstring::Id::str(), "MetricId1"},
706 {tstring::CollectionTimeScope::str(),
707 CollectionTimeScope::point},
708 {tstring::CollectionDuration::str(), 0}},
709 {{tstring::SensorPath::str(),
710 {{{tstring::Service::str(), "Service"},
711 {tstring::Path::str(),
712 "/xyz/openbmc_project/sensors/power/p2"},
713 {tstring::Metadata::str(), "metadata2"}}}},
714 {tstring::OperationType::str(), OperationType::avg},
715 {tstring::Id::str(), "MetricId2"},
716 {tstring::CollectionTimeScope::str(),
717 CollectionTimeScope::point},
718 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100719
720TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
721{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100722 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100723
724 {
725 InSequence seq;
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100726 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100727 EXPECT_CALL(checkPoint, Call());
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100728 EXPECT_CALL(storageMock, store(to_file_path(sut->getId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100729 }
730
731 setProperty(sut->getPath(), "Persistency", false);
732 checkPoint.Call();
733 setProperty(sut->getPath(), "Persistency", true);
734
735 const auto& [key, value] = GetParam();
736
737 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
738}
739
740TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
741{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100742 EXPECT_CALL(storageMock,
743 store(to_file_path(defaultParams().reportId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100744
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100745 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100746
747 const auto& [key, value] = GetParam();
748
749 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
750}
751
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200752class TestReportValidNames :
753 public TestReport,
754 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200755{
756 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200757 void SetUp() override
758 {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200759};
760
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200761INSTANTIATE_TEST_SUITE_P(
762 ValidNames, TestReportValidNames,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100763 Values(defaultParams().reportName("Valid_1"),
764 defaultParams().reportName("Valid_1/Valid_2"),
765 defaultParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200766
767TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
768{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200769 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200770}
771
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100772class TestReportInvalidIds :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200773 public TestReport,
774 public WithParamInterface<ReportParams>
775{
776 public:
777 void SetUp() override
778 {}
779};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200780
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100781INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidIds,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100782 Values(defaultParams().reportId("/"),
783 defaultParams().reportId("/Invalid"),
784 defaultParams().reportId("Invalid/"),
785 defaultParams().reportId("Invalid/Invalid/"),
786 defaultParams().reportId("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200787
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100788TEST_P(TestReportInvalidIds, failsToCreateReportWithInvalidName)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100789{
790 EXPECT_CALL(storageMock, store).Times(0);
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100791
792 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100793}
794
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200795class TestReportAllReportTypes :
796 public TestReport,
797 public WithParamInterface<ReportParams>
798{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200799 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200800 void SetUp() override
801 {
802 sut = makeReport(GetParam());
803 }
804};
805
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100806INSTANTIATE_TEST_SUITE_P(
807 _, TestReportAllReportTypes,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100808 Values(defaultParams().reportingType(ReportingType::onRequest),
809 defaultParams().reportingType(ReportingType::onChange),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200810 defaultParams()
811 .reportingType(ReportingType::periodic)
812 .interval(ReportManager::minInterval)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200813
814TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
815{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100816 EXPECT_THAT(utils::toReportingType(
817 getProperty<std::string>(sut->getPath(), "ReportingType")),
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200818 Eq(GetParam().reportingType()));
819}
820
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100821TEST_P(TestReportAllReportTypes, readingsAreUpdated)
822{
823 clockFake.system.advance(10ms);
824
825 messanger.send(messages::UpdateReportInd{{sut->getId()}});
826 const auto [timestamp, readings] =
827 getProperty<Readings>(sut->getPath(), "Readings");
828
829 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
830}
831
832TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIsDisabled)
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200833{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100834 clockFake.system.advance(10ms);
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200835
836 setProperty(sut->getPath(), "Enabled", false);
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100837 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200838 const auto [timestamp, readings] =
839 getProperty<Readings>(sut->getPath(), "Readings");
840
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100841 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200842}
843
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100844TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIdDiffers)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100845{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100846 clockFake.system.advance(10ms);
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100847
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100848 messanger.send(messages::UpdateReportInd{{sut->getId() + "x"s}});
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100849 const auto [timestamp, readings] =
850 getProperty<Readings>(sut->getPath(), "Readings");
851
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100852 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100853}
854
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100855class TestReportOnRequestType : public TestReport
856{
857 void SetUp() override
858 {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100859 sut =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100860 makeReport(defaultParams().reportingType(ReportingType::onRequest));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100861 }
862};
863
864TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
865{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100866 clockFake.system.advance(10ms);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100867
868 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
869
870 const auto [timestamp, readings] =
871 getProperty<Readings>(sut->getPath(), "Readings");
872
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100873 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100874}
875
876TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
877{
878 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
879
880 const auto [timestamp, readings] =
881 getProperty<Readings>(sut->getPath(), "Readings");
882
883 EXPECT_THAT(readings,
884 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000885 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100886}
887
888class TestReportNonOnRequestType :
889 public TestReport,
890 public WithParamInterface<ReportParams>
891{
892 void SetUp() override
893 {
894 sut = makeReport(GetParam());
895 }
896};
897
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100898INSTANTIATE_TEST_SUITE_P(
899 _, TestReportNonOnRequestType,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100900 Values(defaultParams().reportingType(ReportingType::periodic),
901 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100902
903TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
904{
905 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
906
907 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
908 Eq(Readings{}));
909}
910
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200911class TestReportNonPeriodicReport :
912 public TestReport,
913 public WithParamInterface<ReportParams>
914{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200915 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200916 void SetUp() override
917 {
918 sut = makeReport(GetParam());
919 }
920};
921
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100922INSTANTIATE_TEST_SUITE_P(
923 _, TestReportNonPeriodicReport,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100924 Values(defaultParams().reportingType(ReportingType::onRequest),
925 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200926
927TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
928{
929 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
930
931 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
932 Eq(Readings{}));
933}
934
935class TestReportPeriodicReport : public TestReport
936{
937 void SetUp() override
938 {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200939 sut = makeReport(defaultParams()
Krzysztof Grobelny18e71012022-11-02 13:17:01 +0000940 .appendLimit(2u)
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200941 .reportingType(ReportingType::periodic)
942 .interval(ReportManager::minInterval));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200943 }
944};
945
946TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
947{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100948 clockFake.system.advance(10ms);
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200949 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
950
951 const auto [timestamp, readings] =
952 getProperty<Readings>(sut->getPath(), "Readings");
953
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100954 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200955}
956
957TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
958{
959 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
960
961 const auto [timestamp, readings] =
962 getProperty<Readings>(sut->getPath(), "Readings");
963
964 EXPECT_THAT(readings,
965 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000966 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200967}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100968
Szymon Dompke3eb56862021-09-20 15:32:04 +0200969struct ReportUpdatesReportParams
970{
971 ReportParams reportParams;
972 std::vector<ReadingData> expectedReadings;
973 bool expectedEnabled;
974};
975
976class TestReportWithReportUpdatesAndLimit :
977 public TestReport,
978 public WithParamInterface<ReportUpdatesReportParams>
979{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200980 public:
Szymon Dompke3eb56862021-09-20 15:32:04 +0200981 void SetUp() override
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200982 {}
983
984 void changeReport(ReportingType rt, Milliseconds interval)
Szymon Dompke3eb56862021-09-20 15:32:04 +0200985 {
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200986 setProperty<std::string>(sut->getPath(), "ReportingType",
987 utils::enumToString(rt));
988 setProperty<uint64_t>(sut->getPath(), "Interval", interval.count());
989 }
990
991 auto readings()
992 {
993 auto [timestamp, readings] =
994 getProperty<Readings>(sut->getPath(), "Readings");
995 return readings;
996 }
997
998 void updateReportFourTimes()
999 {
1000 for (int i = 0; i < 4; i++)
1001 {
1002 messanger.send(messages::UpdateReportInd{{sut->getId()}});
1003 }
Szymon Dompke3eb56862021-09-20 15:32:04 +02001004 }
1005};
1006
1007INSTANTIATE_TEST_SUITE_P(
1008 _, TestReportWithReportUpdatesAndLimit,
1009 Values(
1010 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001011 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001012 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1013 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001014 std::vector<ReadingData>{{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("aa"s, "bb"s, 42.0, 74u),
1018 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
1019 true},
1020 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001021 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001022 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1023 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001024 std::vector<ReadingData>{
1025 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1026 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1027 std::make_tuple("a"s, "b"s, 17.1, 114u),
1028 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1029 true},
1030 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001031 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001032 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1033 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001034 std::vector<ReadingData>{}, true},
1035 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001036 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001037 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1038 .appendLimit(10),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001039 std::vector<ReadingData>{
1040 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1041 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1042 std::make_tuple("a"s, "b"s, 17.1, 114u),
1043 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1044 std::make_tuple("a"s, "b"s, 17.1, 114u),
1045 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1046 std::make_tuple("a"s, "b"s, 17.1, 114u),
1047 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1048 true},
1049 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001050 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001051 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1052 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001053 std::vector<ReadingData>{{std::make_tuple("a"s, "b"s, 17.1, 114u),
1054 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1055 std::make_tuple("a"s, "b"s, 17.1, 114u),
1056 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1057 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
1058 false},
1059 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001060 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001061 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1062 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001063 std::vector<ReadingData>{
1064 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1065 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1066 std::make_tuple("a"s, "b"s, 17.1, 114u),
1067 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1068 false},
1069 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001070 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001071 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1072 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001073 std::vector<ReadingData>{}, false},
1074 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001075 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001076 .reportUpdates(ReportUpdates::overwrite)
1077 .appendLimit(500),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001078 std::vector<ReadingData>{
1079 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1080 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1081 true},
1082 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001083 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001084 .reportUpdates(ReportUpdates::overwrite)
1085 .appendLimit(1),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001086 std::vector<ReadingData>{
1087 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1088 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1089 true},
1090 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001091 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001092 .reportUpdates(ReportUpdates::overwrite)
1093 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001094 std::vector<ReadingData>{
1095 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1096 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001097 true},
1098 ReportUpdatesReportParams{
1099 defaultParams()
1100 .reportUpdates(ReportUpdates::appendStopsWhenFull)
Krzysztof Grobelny18e71012022-11-02 13:17:01 +00001101 .appendLimit(2u),
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001102 std::vector<ReadingData>{
1103 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1104 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1105 false}));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001106
1107TEST_P(TestReportWithReportUpdatesAndLimit,
1108 readingsAreUpdatedAfterIntervalExpires)
1109{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001110 sut = makeReport(ReportParams(GetParam().reportParams)
1111 .reportingType(ReportingType::periodic)
1112 .interval(std::chrono::hours(1000)));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001113
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001114 updateReportFourTimes();
Szymon Dompke3eb56862021-09-20 15:32:04 +02001115
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001116 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1117 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1118 Eq(GetParam().expectedEnabled));
1119}
1120
1121TEST_P(TestReportWithReportUpdatesAndLimit,
1122 appendLimitIsRespectedAfterChangingToPeriodic)
1123{
1124 sut = makeReport(ReportParams(GetParam().reportParams)
Krzysztof Grobelny18e71012022-11-02 13:17:01 +00001125 .appendLimit(GetParam().expectedReadings.size())
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001126 .reportingType(ReportingType::onRequest)
1127 .interval(std::chrono::hours(0)));
1128
1129 changeReport(ReportingType::periodic, std::chrono::hours(1000));
1130 updateReportFourTimes();
1131
1132 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1133 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1134 Eq(GetParam().expectedEnabled));
1135}
1136
1137TEST_P(TestReportWithReportUpdatesAndLimit,
1138 appendLimitIsIgnoredAfterChangingToOnRequest)
1139{
1140 sut = makeReport(ReportParams(GetParam().reportParams)
1141 .reportingType(ReportingType::periodic)
1142 .interval(std::chrono::hours(1000)));
1143
1144 changeReport(ReportingType::onRequest, Milliseconds{0});
1145 updateReportFourTimes();
1146
1147 EXPECT_THAT(readings(), SizeIs(2u));
1148 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(true));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001149}
1150
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001151class TestReportInitialization : public TestReport
1152{
1153 public:
1154 void SetUp() override
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001155 {
1156 initMetricMocks(defaultParams().metricParameters());
1157 }
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001158
Patrick Williams39cc6ac2022-07-22 19:26:56 -05001159 void monitorProc(sdbusplus::message_t& msg)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001160 {
1161 std::string iface;
1162 std::vector<std::pair<std::string, std::variant<Readings>>>
1163 changed_properties;
1164 std::vector<std::string> invalidated_properties;
1165
1166 msg.read(iface, changed_properties, invalidated_properties);
1167
1168 if (iface == Report::reportIfaceName)
1169 {
1170 for (const auto& [name, value] : changed_properties)
1171 {
1172 if (name == "Readings")
1173 {
1174 readingsUpdated.Call();
1175 }
1176 }
1177 }
1178 }
1179
1180 void makeMonitor()
1181 {
Patrick Williams3a62ee12021-12-03 10:13:25 -06001182 monitor = std::make_unique<sdbusplus::bus::match_t>(
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001183 *DbusEnvironment::getBus(),
1184 sdbusplus::bus::match::rules::propertiesChanged(
1185 sut->getPath(), Report::reportIfaceName),
1186 [this](auto& msg) { monitorProc(msg); });
1187 }
1188
Patrick Williams3a62ee12021-12-03 10:13:25 -06001189 std::unique_ptr<sdbusplus::bus::match_t> monitor;
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001190 MockFunction<void()> readingsUpdated;
1191};
1192
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001193TEST_F(TestReportInitialization,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001194 registersForMetricUpdatesWhenOnChangeReportCreated)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001195{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001196 std::vector<const interfaces::MetricListener*> args;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001197 for (auto& metric : metricMocks)
1198 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001199 EXPECT_CALL(*metric, registerForUpdates(_))
1200 .WillOnce(Invoke([&args](const interfaces::MetricListener& report) {
1201 args.emplace_back(&report);
1202 }));
1203 ;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001204 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001205
1206 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1207
1208 EXPECT_THAT(args, SizeIs(metricMocks.size()));
1209 for (const auto* reportPtr : args)
1210 {
1211 EXPECT_THAT(reportPtr, Eq(sut.get()));
1212 }
1213}
1214
1215TEST_F(TestReportInitialization,
1216 deregistersForMetricUpdatesWhenOnChangeReportDestroyed)
1217{
1218 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1219
1220 for (auto& metric : metricMocks)
1221 {
1222 EXPECT_CALL(*metric,
1223 unregisterFromUpdates(Ref(
1224 static_cast<interfaces::MetricListener&>(*sut.get()))));
1225 }
1226
1227 sut = nullptr;
1228}
1229
1230TEST_F(TestReportInitialization,
1231 metricsAreInitializedWhenEnabledReportConstructed)
1232{
1233 for (auto& metric : metricMocks)
1234 {
1235 EXPECT_CALL(*metric, initialize());
1236 }
1237 sut = makeReport(defaultParams().enabled(true));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001238}
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001239
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001240TEST_F(TestReportInitialization,
1241 metricsAreNotInitializedWhenDisabledReportConstructed)
1242{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001243 for (auto& metric : metricMocks)
1244 {
1245 EXPECT_CALL(*metric, initialize()).Times(0);
1246 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001247 sut = makeReport(defaultParams().enabled(false));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001248}
1249
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001250TEST_F(TestReportInitialization,
1251 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001252{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001253 EXPECT_CALL(readingsUpdated, Call())
1254 .WillOnce(
1255 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
1256
1257 const auto elapsed = DbusEnvironment::measureTime([this] {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001258 sut = makeReport(defaultParams()
1259 .reportingType(ReportingType::periodic)
1260 .reportActions({ReportAction::emitsReadingsUpdate})
1261 .interval(ReportManager::minInterval));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001262 makeMonitor();
1263 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
1264 });
1265
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001266 EXPECT_THAT(elapsed, AllOf(Ge(ReportManager::minInterval),
1267 Lt(ReportManager::minInterval * 2)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001268}
1269
1270TEST_F(TestReportInitialization,
1271 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
1272{
1273 EXPECT_CALL(readingsUpdated, Call()).Times(0);
1274
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001275 sut = makeReport(defaultParams()
1276 .reportingType(ReportingType::periodic)
1277 .reportActions({}));
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001278 makeMonitor();
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001279 DbusEnvironment::sleepFor(defaultParams().interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001280}
Szymon Dompke3eb56862021-09-20 15:32:04 +02001281
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001282TEST_F(TestReportInitialization, triggerIdsPropertyIsInitialzed)
1283{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001284 for (const auto& triggerId : {"trigger1", "trigger2"})
1285 {
1286 messanger.on_receive<messages::CollectTriggerIdReq>(
Szymon Dompkee0ed5082022-05-20 10:54:25 +02001287 [this, triggerId](const auto& msg) {
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001288 messanger.send(messages::CollectTriggerIdResp{triggerId});
1289 });
1290 }
1291
1292 sut = makeReport(ReportParams());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001293
1294 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +02001295 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
1296 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
1297 utils::constants::triggerDirPath / "trigger2"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001298}
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001299
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +01001300TEST_F(TestReportInitialization,
1301 metricValuesAreNotStoredForReportUpdatesDifferentThanAppendStopsWhenFull)
1302{
1303 sut = makeReport(ReportParams()
1304 .reportingType(ReportingType::periodic)
1305 .interval(1h)
1306 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1307 .readings(Readings{{}, {{}}}));
1308
1309 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1310 Eq(storedConfiguration.end()));
1311}
1312
1313TEST_F(TestReportInitialization, metricValuesAreNotStoredForOnRequestReport)
1314{
1315 sut = makeReport(ReportParams()
1316 .reportingType(ReportingType::onRequest)
1317 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1318 .readings(Readings{{}, {{}}}));
1319
1320 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1321 Eq(storedConfiguration.end()));
1322}
1323
1324TEST_F(TestReportInitialization,
1325 metricValuesAreStoredForNonOnRequestReportWithAppendStopsWhenFull)
1326{
1327 const auto readings = Readings{{}, {{}}};
1328
1329 sut = makeReport(ReportParams()
1330 .reportingType(ReportingType::periodic)
1331 .interval(1h)
1332 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1333 .readings(readings));
1334
1335 ASSERT_THAT(storedConfiguration.at("MetricValues").get<LabeledReadings>(),
1336 Eq(utils::toLabeledReadings(readings)));
1337}
1338
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001339class TestReportInitializationOnChangeReport : public TestReportInitialization
1340{
1341 public:
1342 void SetUp() override
1343 {
1344 initMetricMocks(params.metricParameters());
1345 }
1346
1347 ReportParams params = defaultOnChangeParams();
1348};
1349
1350TEST_F(TestReportInitializationOnChangeReport,
1351 doesntUpdateReadingsWhenNotRequired)
1352{
1353 EXPECT_CALL(*metricMocks[0], updateReadings(_)).Times(0);
1354
1355 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(false));
1356
1357 sut = makeReport(params);
1358
1359 DbusEnvironment::sleepFor(500ms);
1360}
1361
1362TEST_F(TestReportInitializationOnChangeReport, updatesReadingsWhenRequired)
1363{
1364 EXPECT_CALL(*metricMocks[0], updateReadings(_))
1365 .WillOnce(Return())
1366 .WillOnce(
1367 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")))
1368 .WillRepeatedly(Return());
1369
1370 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(true));
1371
1372 sut = makeReport(params);
1373
1374 DbusEnvironment::waitForFuture("readingsUpdated");
1375}