blob: 1d0f0bb77f0deaf7d6530cb04590d24609c54892 [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) {
Patrick Williams3a1c2972023-05-10 07:51:04 -0500191 methodPromise.set_value(ec);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100192 },
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{
Patrick Williams3a1c2972023-05-10 07:51:04 -0500674 void SetUp() override {}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100675};
676
677INSTANTIATE_TEST_SUITE_P(
678 _, TestReportStore,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100679 Values(
680 std::make_pair("Enabled"s, nlohmann::json(defaultParams().enabled())),
Krzysztof Grobelny18e71012022-11-02 13:17:01 +0000681 std::make_pair("Version"s, nlohmann::json(7)),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100682 std::make_pair("Id"s, nlohmann::json(defaultParams().reportId())),
683 std::make_pair("Name"s, nlohmann::json(defaultParams().reportName())),
684 std::make_pair("ReportingType",
685 nlohmann::json(defaultParams().reportingType())),
686 std::make_pair("ReportActions", nlohmann::json(utils::transform(
687 defaultParams().reportActions(),
688 [](const auto v) {
Patrick Williams3a1c2972023-05-10 07:51:04 -0500689 return utils::toUnderlying(v);
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100690 }))),
691 std::make_pair("Interval",
692 nlohmann::json(defaultParams().interval().count())),
693 std::make_pair("AppendLimit",
694 nlohmann::json(ReportParams().appendLimit())),
695 std::make_pair(
696 "ReadingParameters",
697 nlohmann::json(
698 {{{tstring::SensorPath::str(),
699 {{{tstring::Service::str(), "Service"},
700 {tstring::Path::str(),
701 "/xyz/openbmc_project/sensors/power/p1"},
702 {tstring::Metadata::str(), "metadata1"}}}},
703 {tstring::OperationType::str(), OperationType::avg},
704 {tstring::Id::str(), "MetricId1"},
705 {tstring::CollectionTimeScope::str(),
706 CollectionTimeScope::point},
707 {tstring::CollectionDuration::str(), 0}},
708 {{tstring::SensorPath::str(),
709 {{{tstring::Service::str(), "Service"},
710 {tstring::Path::str(),
711 "/xyz/openbmc_project/sensors/power/p2"},
712 {tstring::Metadata::str(), "metadata2"}}}},
713 {tstring::OperationType::str(), OperationType::avg},
714 {tstring::Id::str(), "MetricId2"},
715 {tstring::CollectionTimeScope::str(),
716 CollectionTimeScope::point},
717 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100718
719TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
720{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100721 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100722
723 {
724 InSequence seq;
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100725 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100726 EXPECT_CALL(checkPoint, Call());
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100727 EXPECT_CALL(storageMock, store(to_file_path(sut->getId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100728 }
729
730 setProperty(sut->getPath(), "Persistency", false);
731 checkPoint.Call();
732 setProperty(sut->getPath(), "Persistency", true);
733
734 const auto& [key, value] = GetParam();
735
736 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
737}
738
739TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
740{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100741 EXPECT_CALL(storageMock,
742 store(to_file_path(defaultParams().reportId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100743
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100744 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100745
746 const auto& [key, value] = GetParam();
747
748 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
749}
750
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200751class TestReportValidNames :
752 public TestReport,
753 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200754{
755 public:
Patrick Williams3a1c2972023-05-10 07:51:04 -0500756 void SetUp() override {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200757};
758
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200759INSTANTIATE_TEST_SUITE_P(
760 ValidNames, TestReportValidNames,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100761 Values(defaultParams().reportName("Valid_1"),
762 defaultParams().reportName("Valid_1/Valid_2"),
763 defaultParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200764
765TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
766{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200767 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200768}
769
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100770class TestReportInvalidIds :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200771 public TestReport,
772 public WithParamInterface<ReportParams>
773{
774 public:
Patrick Williams3a1c2972023-05-10 07:51:04 -0500775 void SetUp() override {}
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200776};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200777
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100778INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidIds,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100779 Values(defaultParams().reportId("/"),
780 defaultParams().reportId("/Invalid"),
781 defaultParams().reportId("Invalid/"),
782 defaultParams().reportId("Invalid/Invalid/"),
783 defaultParams().reportId("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200784
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100785TEST_P(TestReportInvalidIds, failsToCreateReportWithInvalidName)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100786{
787 EXPECT_CALL(storageMock, store).Times(0);
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100788
789 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100790}
791
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200792class TestReportAllReportTypes :
793 public TestReport,
794 public WithParamInterface<ReportParams>
795{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200796 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200797 void SetUp() override
798 {
799 sut = makeReport(GetParam());
800 }
801};
802
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100803INSTANTIATE_TEST_SUITE_P(
804 _, TestReportAllReportTypes,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100805 Values(defaultParams().reportingType(ReportingType::onRequest),
806 defaultParams().reportingType(ReportingType::onChange),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200807 defaultParams()
808 .reportingType(ReportingType::periodic)
809 .interval(ReportManager::minInterval)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200810
811TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
812{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100813 EXPECT_THAT(utils::toReportingType(
814 getProperty<std::string>(sut->getPath(), "ReportingType")),
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200815 Eq(GetParam().reportingType()));
816}
817
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100818TEST_P(TestReportAllReportTypes, readingsAreUpdated)
819{
820 clockFake.system.advance(10ms);
821
822 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Patrick Williams3a1c2972023-05-10 07:51:04 -0500823 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
824 "Readings");
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100825
826 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
827}
828
829TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIsDisabled)
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200830{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100831 clockFake.system.advance(10ms);
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200832
833 setProperty(sut->getPath(), "Enabled", false);
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100834 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Patrick Williams3a1c2972023-05-10 07:51:04 -0500835 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
836 "Readings");
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200837
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100838 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200839}
840
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100841TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIdDiffers)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100842{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100843 clockFake.system.advance(10ms);
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100844
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100845 messanger.send(messages::UpdateReportInd{{sut->getId() + "x"s}});
Patrick Williams3a1c2972023-05-10 07:51:04 -0500846 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
847 "Readings");
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100848
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100849 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100850}
851
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100852class TestReportOnRequestType : public TestReport
853{
854 void SetUp() override
855 {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100856 sut =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100857 makeReport(defaultParams().reportingType(ReportingType::onRequest));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100858 }
859};
860
861TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
862{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100863 clockFake.system.advance(10ms);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100864
865 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
866
Patrick Williams3a1c2972023-05-10 07:51:04 -0500867 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
868 "Readings");
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100869
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100870 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100871}
872
873TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
874{
875 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
876
Patrick Williams3a1c2972023-05-10 07:51:04 -0500877 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
878 "Readings");
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100879
880 EXPECT_THAT(readings,
881 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000882 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100883}
884
885class TestReportNonOnRequestType :
886 public TestReport,
887 public WithParamInterface<ReportParams>
888{
889 void SetUp() override
890 {
891 sut = makeReport(GetParam());
892 }
893};
894
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100895INSTANTIATE_TEST_SUITE_P(
896 _, TestReportNonOnRequestType,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100897 Values(defaultParams().reportingType(ReportingType::periodic),
898 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100899
900TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
901{
902 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
903
904 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
905 Eq(Readings{}));
906}
907
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200908class TestReportNonPeriodicReport :
909 public TestReport,
910 public WithParamInterface<ReportParams>
911{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200912 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200913 void SetUp() override
914 {
915 sut = makeReport(GetParam());
916 }
917};
918
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100919INSTANTIATE_TEST_SUITE_P(
920 _, TestReportNonPeriodicReport,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100921 Values(defaultParams().reportingType(ReportingType::onRequest),
922 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200923
924TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
925{
926 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
927
928 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
929 Eq(Readings{}));
930}
931
932class TestReportPeriodicReport : public TestReport
933{
934 void SetUp() override
935 {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200936 sut = makeReport(defaultParams()
Krzysztof Grobelny18e71012022-11-02 13:17:01 +0000937 .appendLimit(2u)
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200938 .reportingType(ReportingType::periodic)
939 .interval(ReportManager::minInterval));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200940 }
941};
942
943TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
944{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100945 clockFake.system.advance(10ms);
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200946 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
947
Patrick Williams3a1c2972023-05-10 07:51:04 -0500948 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
949 "Readings");
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200950
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100951 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200952}
953
954TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
955{
956 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
957
Patrick Williams3a1c2972023-05-10 07:51:04 -0500958 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
959 "Readings");
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200960
961 EXPECT_THAT(readings,
962 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000963 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200964}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100965
Szymon Dompke3eb56862021-09-20 15:32:04 +0200966struct ReportUpdatesReportParams
967{
968 ReportParams reportParams;
969 std::vector<ReadingData> expectedReadings;
970 bool expectedEnabled;
971};
972
973class TestReportWithReportUpdatesAndLimit :
974 public TestReport,
975 public WithParamInterface<ReportUpdatesReportParams>
976{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200977 public:
Patrick Williams3a1c2972023-05-10 07:51:04 -0500978 void SetUp() override {}
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200979
980 void changeReport(ReportingType rt, Milliseconds interval)
Szymon Dompke3eb56862021-09-20 15:32:04 +0200981 {
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200982 setProperty<std::string>(sut->getPath(), "ReportingType",
983 utils::enumToString(rt));
984 setProperty<uint64_t>(sut->getPath(), "Interval", interval.count());
985 }
986
987 auto readings()
988 {
Patrick Williams3a1c2972023-05-10 07:51:04 -0500989 auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
990 "Readings");
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200991 return readings;
992 }
993
994 void updateReportFourTimes()
995 {
996 for (int i = 0; i < 4; i++)
997 {
998 messanger.send(messages::UpdateReportInd{{sut->getId()}});
999 }
Szymon Dompke3eb56862021-09-20 15:32:04 +02001000 }
1001};
1002
1003INSTANTIATE_TEST_SUITE_P(
1004 _, TestReportWithReportUpdatesAndLimit,
1005 Values(
1006 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001007 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001008 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1009 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001010 std::vector<ReadingData>{{std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1011 std::make_tuple("a"s, "b"s, 17.1, 114u),
1012 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1013 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1014 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
1015 true},
1016 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001017 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001018 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1019 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001020 std::vector<ReadingData>{
1021 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1022 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1023 std::make_tuple("a"s, "b"s, 17.1, 114u),
1024 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1025 true},
1026 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001027 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001028 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1029 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001030 std::vector<ReadingData>{}, true},
1031 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001032 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001033 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1034 .appendLimit(10),
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 std::make_tuple("a"s, "b"s, 17.1, 114u),
1039 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1040 std::make_tuple("a"s, "b"s, 17.1, 114u),
1041 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1042 std::make_tuple("a"s, "b"s, 17.1, 114u),
1043 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1044 true},
1045 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001046 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001047 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1048 .appendLimit(5),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001049 std::vector<ReadingData>{{std::make_tuple("a"s, "b"s, 17.1, 114u),
1050 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1051 std::make_tuple("a"s, "b"s, 17.1, 114u),
1052 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1053 std::make_tuple("a"s, "b"s, 17.1, 114u)}},
1054 false},
1055 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001056 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001057 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1058 .appendLimit(4),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001059 std::vector<ReadingData>{
1060 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1061 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
1062 std::make_tuple("a"s, "b"s, 17.1, 114u),
1063 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1064 false},
1065 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001066 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001067 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1068 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001069 std::vector<ReadingData>{}, false},
1070 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001071 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001072 .reportUpdates(ReportUpdates::overwrite)
1073 .appendLimit(500),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001074 std::vector<ReadingData>{
1075 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1076 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1077 true},
1078 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001079 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001080 .reportUpdates(ReportUpdates::overwrite)
1081 .appendLimit(1),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001082 std::vector<ReadingData>{
1083 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1084 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1085 true},
1086 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001087 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001088 .reportUpdates(ReportUpdates::overwrite)
1089 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001090 std::vector<ReadingData>{
1091 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1092 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001093 true},
1094 ReportUpdatesReportParams{
1095 defaultParams()
1096 .reportUpdates(ReportUpdates::appendStopsWhenFull)
Krzysztof Grobelny18e71012022-11-02 13:17:01 +00001097 .appendLimit(2u),
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001098 std::vector<ReadingData>{
1099 {std::make_tuple("a"s, "b"s, 17.1, 114u),
1100 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
1101 false}));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001102
1103TEST_P(TestReportWithReportUpdatesAndLimit,
1104 readingsAreUpdatedAfterIntervalExpires)
1105{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001106 sut = makeReport(ReportParams(GetParam().reportParams)
1107 .reportingType(ReportingType::periodic)
1108 .interval(std::chrono::hours(1000)));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001109
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001110 updateReportFourTimes();
Szymon Dompke3eb56862021-09-20 15:32:04 +02001111
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001112 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1113 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1114 Eq(GetParam().expectedEnabled));
1115}
1116
1117TEST_P(TestReportWithReportUpdatesAndLimit,
1118 appendLimitIsRespectedAfterChangingToPeriodic)
1119{
1120 sut = makeReport(ReportParams(GetParam().reportParams)
Krzysztof Grobelny18e71012022-11-02 13:17:01 +00001121 .appendLimit(GetParam().expectedReadings.size())
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001122 .reportingType(ReportingType::onRequest)
1123 .interval(std::chrono::hours(0)));
1124
1125 changeReport(ReportingType::periodic, std::chrono::hours(1000));
1126 updateReportFourTimes();
1127
1128 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1129 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1130 Eq(GetParam().expectedEnabled));
1131}
1132
1133TEST_P(TestReportWithReportUpdatesAndLimit,
1134 appendLimitIsIgnoredAfterChangingToOnRequest)
1135{
1136 sut = makeReport(ReportParams(GetParam().reportParams)
1137 .reportingType(ReportingType::periodic)
1138 .interval(std::chrono::hours(1000)));
1139
1140 changeReport(ReportingType::onRequest, Milliseconds{0});
1141 updateReportFourTimes();
1142
1143 EXPECT_THAT(readings(), SizeIs(2u));
1144 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(true));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001145}
1146
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001147class TestReportInitialization : public TestReport
1148{
1149 public:
1150 void SetUp() override
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001151 {
1152 initMetricMocks(defaultParams().metricParameters());
1153 }
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001154
Patrick Williams39cc6ac2022-07-22 19:26:56 -05001155 void monitorProc(sdbusplus::message_t& msg)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001156 {
1157 std::string iface;
1158 std::vector<std::pair<std::string, std::variant<Readings>>>
1159 changed_properties;
1160 std::vector<std::string> invalidated_properties;
1161
1162 msg.read(iface, changed_properties, invalidated_properties);
1163
1164 if (iface == Report::reportIfaceName)
1165 {
1166 for (const auto& [name, value] : changed_properties)
1167 {
1168 if (name == "Readings")
1169 {
1170 readingsUpdated.Call();
1171 }
1172 }
1173 }
1174 }
1175
1176 void makeMonitor()
1177 {
Patrick Williams3a62ee12021-12-03 10:13:25 -06001178 monitor = std::make_unique<sdbusplus::bus::match_t>(
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001179 *DbusEnvironment::getBus(),
1180 sdbusplus::bus::match::rules::propertiesChanged(
1181 sut->getPath(), Report::reportIfaceName),
1182 [this](auto& msg) { monitorProc(msg); });
1183 }
1184
Patrick Williams3a62ee12021-12-03 10:13:25 -06001185 std::unique_ptr<sdbusplus::bus::match_t> monitor;
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001186 MockFunction<void()> readingsUpdated;
1187};
1188
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001189TEST_F(TestReportInitialization,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001190 registersForMetricUpdatesWhenOnChangeReportCreated)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001191{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001192 std::vector<const interfaces::MetricListener*> args;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001193 for (auto& metric : metricMocks)
1194 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001195 EXPECT_CALL(*metric, registerForUpdates(_))
1196 .WillOnce(Invoke([&args](const interfaces::MetricListener& report) {
1197 args.emplace_back(&report);
1198 }));
1199 ;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001200 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001201
1202 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1203
1204 EXPECT_THAT(args, SizeIs(metricMocks.size()));
1205 for (const auto* reportPtr : args)
1206 {
1207 EXPECT_THAT(reportPtr, Eq(sut.get()));
1208 }
1209}
1210
1211TEST_F(TestReportInitialization,
1212 deregistersForMetricUpdatesWhenOnChangeReportDestroyed)
1213{
1214 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1215
1216 for (auto& metric : metricMocks)
1217 {
1218 EXPECT_CALL(*metric,
1219 unregisterFromUpdates(Ref(
1220 static_cast<interfaces::MetricListener&>(*sut.get()))));
1221 }
1222
1223 sut = nullptr;
1224}
1225
1226TEST_F(TestReportInitialization,
1227 metricsAreInitializedWhenEnabledReportConstructed)
1228{
1229 for (auto& metric : metricMocks)
1230 {
1231 EXPECT_CALL(*metric, initialize());
1232 }
1233 sut = makeReport(defaultParams().enabled(true));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001234}
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001235
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001236TEST_F(TestReportInitialization,
1237 metricsAreNotInitializedWhenDisabledReportConstructed)
1238{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001239 for (auto& metric : metricMocks)
1240 {
1241 EXPECT_CALL(*metric, initialize()).Times(0);
1242 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001243 sut = makeReport(defaultParams().enabled(false));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001244}
1245
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001246TEST_F(TestReportInitialization,
1247 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001248{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001249 EXPECT_CALL(readingsUpdated, Call())
1250 .WillOnce(
1251 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
1252
1253 const auto elapsed = DbusEnvironment::measureTime([this] {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001254 sut = makeReport(defaultParams()
1255 .reportingType(ReportingType::periodic)
1256 .reportActions({ReportAction::emitsReadingsUpdate})
1257 .interval(ReportManager::minInterval));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001258 makeMonitor();
1259 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
1260 });
1261
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001262 EXPECT_THAT(elapsed, AllOf(Ge(ReportManager::minInterval),
1263 Lt(ReportManager::minInterval * 2)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001264}
1265
1266TEST_F(TestReportInitialization,
1267 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
1268{
1269 EXPECT_CALL(readingsUpdated, Call()).Times(0);
1270
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001271 sut = makeReport(defaultParams()
1272 .reportingType(ReportingType::periodic)
1273 .reportActions({}));
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001274 makeMonitor();
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001275 DbusEnvironment::sleepFor(defaultParams().interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001276}
Szymon Dompke3eb56862021-09-20 15:32:04 +02001277
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001278TEST_F(TestReportInitialization, triggerIdsPropertyIsInitialzed)
1279{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001280 for (const auto& triggerId : {"trigger1", "trigger2"})
1281 {
1282 messanger.on_receive<messages::CollectTriggerIdReq>(
Szymon Dompkee0ed5082022-05-20 10:54:25 +02001283 [this, triggerId](const auto& msg) {
Patrick Williams3a1c2972023-05-10 07:51:04 -05001284 messanger.send(messages::CollectTriggerIdResp{triggerId});
1285 });
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001286 }
1287
1288 sut = makeReport(ReportParams());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001289
1290 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +02001291 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
1292 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
1293 utils::constants::triggerDirPath / "trigger2"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001294}
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001295
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +01001296TEST_F(TestReportInitialization,
1297 metricValuesAreNotStoredForReportUpdatesDifferentThanAppendStopsWhenFull)
1298{
1299 sut = makeReport(ReportParams()
1300 .reportingType(ReportingType::periodic)
1301 .interval(1h)
1302 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1303 .readings(Readings{{}, {{}}}));
1304
1305 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1306 Eq(storedConfiguration.end()));
1307}
1308
1309TEST_F(TestReportInitialization, metricValuesAreNotStoredForOnRequestReport)
1310{
1311 sut = makeReport(ReportParams()
1312 .reportingType(ReportingType::onRequest)
1313 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1314 .readings(Readings{{}, {{}}}));
1315
1316 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1317 Eq(storedConfiguration.end()));
1318}
1319
1320TEST_F(TestReportInitialization,
1321 metricValuesAreStoredForNonOnRequestReportWithAppendStopsWhenFull)
1322{
1323 const auto readings = Readings{{}, {{}}};
1324
1325 sut = makeReport(ReportParams()
1326 .reportingType(ReportingType::periodic)
1327 .interval(1h)
1328 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1329 .readings(readings));
1330
1331 ASSERT_THAT(storedConfiguration.at("MetricValues").get<LabeledReadings>(),
1332 Eq(utils::toLabeledReadings(readings)));
1333}
1334
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001335class TestReportInitializationOnChangeReport : public TestReportInitialization
1336{
1337 public:
1338 void SetUp() override
1339 {
1340 initMetricMocks(params.metricParameters());
1341 }
1342
1343 ReportParams params = defaultOnChangeParams();
1344};
1345
1346TEST_F(TestReportInitializationOnChangeReport,
1347 doesntUpdateReadingsWhenNotRequired)
1348{
1349 EXPECT_CALL(*metricMocks[0], updateReadings(_)).Times(0);
1350
1351 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(false));
1352
1353 sut = makeReport(params);
1354
1355 DbusEnvironment::sleepFor(500ms);
1356}
1357
1358TEST_F(TestReportInitializationOnChangeReport, updatesReadingsWhenRequired)
1359{
1360 EXPECT_CALL(*metricMocks[0], updateReadings(_))
1361 .WillOnce(Return())
1362 .WillOnce(
1363 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")))
1364 .WillRepeatedly(Return());
1365
1366 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(true));
1367
1368 sut = makeReport(params);
1369
1370 DbusEnvironment::waitForFuture("readingsUpdated");
1371}