blob: 28ad3b6e21ae32582f9324429dd637cddc639ad8 [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 Grobelnycff70c12022-10-27 07:16:08 +000086 std::vector<MetricValue> readings{
87 {MetricValue{"b", 17.1, 114}, MetricValue{"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>>
Jayanth Othayothe77b8322024-12-08 06:45:24 -0600101 getMetricsFromReadingParams(const ReadingParameters& params) const
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100102 {
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>
Patrick Williams583ba442025-02-03 14:28:19 -0500156 static boost::system::error_code setProperty(
157 const std::string& path, const std::string& property, const T& newValue)
Szymon Dompkee28aa532021-10-27 12:33:12 +0200158 {
159 return DbusEnvironment::setProperty<T>(path, Report::reportIfaceName,
160 property, newValue);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100161 }
162
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000163 template <class... Args>
Patrick Williams583ba442025-02-03 14:28:19 -0500164 static boost::system::error_code callMethod(
165 const std::string& path, const std::string& method, Args&&... args)
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000166 {
167 return DbusEnvironment::callMethod(path, Report::reportIfaceName,
168 "SetReportingProperties",
169 std::forward<Args>(args)...);
170 }
171
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200172 template <class T>
173 struct ChangePropertyParams
174 {
175 Matcher<T> valueBefore = _;
176 T newValue;
177 Matcher<boost::system::error_code> ec =
178 Eq(boost::system::errc::success);
179 Matcher<T> valueAfter = Eq(newValue);
180 };
181
182 template <class T>
183 static void changeProperty(const std::string& path,
184 const std::string& property,
185 ChangePropertyParams<T> p)
186 {
187 ASSERT_THAT(getProperty<T>(path, property), p.valueBefore);
188 ASSERT_THAT(setProperty<T>(path, property, p.newValue), p.ec);
189 EXPECT_THAT(getProperty<T>(path, property), p.valueAfter);
190 }
191
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100192 boost::system::error_code call(const std::string& path,
193 const std::string& interface,
194 const std::string& method)
195 {
196 std::promise<boost::system::error_code> methodPromise;
197 DbusEnvironment::getBus()->async_method_call(
198 [&methodPromise](boost::system::error_code ec) {
Patrick Williams583ba442025-02-03 14:28:19 -0500199 methodPromise.set_value(ec);
200 },
201 DbusEnvironment::serviceName(), path, interface, method);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100202 return DbusEnvironment::waitForFuture(methodPromise.get_future());
203 }
204
205 boost::system::error_code update(const std::string& path)
206 {
207 return call(path, Report::reportIfaceName, "Update");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200208 }
209
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200210 boost::system::error_code deleteReport(const std::string& path)
211 {
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100212 return call(path, Report::deleteIfaceName, "Delete");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200213 }
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200214
Patrick Williams583ba442025-02-03 14:28:19 -0500215 static std::pair<std::string, std::vector<std::string>> makeStateDetail(
216 const std::string& detailType, std::vector<std::string> detailArgs)
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200217 {
218 return make_pair(detailType, detailArgs);
219 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200220};
221
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100222TEST_F(TestReport, returnsId)
223{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100224 EXPECT_THAT(sut->getId(), Eq(defaultParams().reportId()));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100225}
226
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200227TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
228{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200229 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100230 Eq(defaultParams().enabled()));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200231 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100232 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100233 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100234 EXPECT_THAT(
235 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100236 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Patrick Williams583ba442025-02-03 14:28:19 -0500237 return utils::enumToString(v);
238 })));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200239 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100240 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100241 ReportAction::emitsReadingsUpdate)));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200242 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "AppendLimit"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100243 Eq(defaultParams().appendLimit()));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100244 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100245 Eq(utils::enumToString(defaultParams().reportingType())));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200246 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportUpdates"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100247 Eq(utils::enumToString(defaultParams().reportUpdates())));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200248 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200249 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100250 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100251 ReportAction::logToMetricReportsCollection)));
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000252 EXPECT_THAT(
253 getProperty<ReadingParameters>(sut->getPath(), "ReadingParameters"),
254 Eq(toReadingParameters(defaultParams().metricParameters())));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100255 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100256 Eq(defaultParams().reportName()));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100257 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200258 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200259 IsEmpty());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200260}
261
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200262TEST_F(TestReport, readingsAreInitialyEmpty)
263{
264 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
265 Eq(Readings{}));
266}
267
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100268TEST_F(TestReport, setReadingParametersWithNewParams)
269{
270 ReadingParameters newParams = toReadingParameters(
271 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
272 {LabeledSensorInfo{"Service",
273 "/xyz/openbmc_project/sensors/power/psu",
274 "NewMetadata123"}},
275 OperationType::avg,
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100276 CollectionTimeScope::startup,
277 CollectionDuration(250ms)}}});
278 auto metrics = getMetricsFromReadingParams(newParams);
279
280 EXPECT_CALL(*reportFactoryMock, updateMetrics(_, _, _))
281 .WillOnce(SetArgReferee<0>(metrics));
282 EXPECT_THAT(
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000283 setProperty(sut->getPath(), "ReadingParameters", newParams).value(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100284 Eq(boost::system::errc::success));
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000285 EXPECT_THAT(
286 getProperty<ReadingParameters>(sut->getPath(), "ReadingParameters"),
287 Eq(newParams));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100288}
289
Michal Orzel5e7cbf42024-08-01 15:44:42 +0200290TEST_F(TestReport, setReadingParametersFailsWhenMetricCountExceedsAllowedValue)
291{
292 std::vector<LabeledMetricParameters> readingParams{{LabeledMetricParameters{
293 {LabeledSensorInfo{"Service", "/xyz/openbmc_project/sensors/power/psu",
294 "NewMetadata123"}},
295 OperationType::avg,
296 CollectionTimeScope::startup,
297 CollectionDuration(250ms)}}};
298
299 auto& metricParamsVec =
300 readingParams[0].at_label<utils::tstring::SensorPath>();
301 for (size_t i = 0; i < ReportManager::maxNumberMetrics; i++)
302 {
303 metricParamsVec.emplace_back(LabeledSensorInfo{
304 "Service", "/xyz/openbmc_project/sensors/power/psu",
305 "NewMetadata123"});
306 }
307
308 ReadingParameters newParams = toReadingParameters(readingParams);
309
310 EXPECT_THAT(
311 setProperty(sut->getPath(), "ReadingParameters", newParams).value(),
312 Eq(boost::system::errc::invalid_argument));
313}
314
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100315TEST_F(TestReport, setReportActionsWithValidNewActions)
316{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000317 std::vector<std::string> newActions = {
318 utils::enumToString(ReportAction::emitsReadingsUpdate)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100319 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100320 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100321 [](const auto v) { return utils::enumToString(v); });
322
323 EXPECT_THAT(newActions, Ne(currActions));
324 EXPECT_THAT(
325 setProperty(sut->getPath(), "ReportActions", newActions).value(),
326 Eq(boost::system::errc::success));
327 EXPECT_THAT(
328 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000329 UnorderedElementsAre(
330 utils::enumToString(ReportAction::emitsReadingsUpdate),
331 utils::enumToString(ReportAction::logToMetricReportsCollection)));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100332}
333
334TEST_F(TestReport, setReportActionsWithValidUnsortedActions)
335{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000336 std::vector<std::string> newActions = {
337 utils::enumToString(ReportAction::logToMetricReportsCollection),
338 utils::enumToString(ReportAction::emitsReadingsUpdate)};
339 std::vector<std::string> expectedActions = {
340 utils::enumToString(ReportAction::emitsReadingsUpdate),
341 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100342 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100343 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100344 [](const auto v) { return utils::enumToString(v); });
345
346 EXPECT_THAT(newActions, Ne(currActions));
347 EXPECT_THAT(
348 setProperty(sut->getPath(), "ReportActions", newActions).value(),
349 Eq(boost::system::errc::success));
350 EXPECT_THAT(
351 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
352 Eq(expectedActions));
353}
354
355TEST_F(TestReport, setReportActionsWithEmptyActions)
356{
357 std::vector<std::string> newActions = {};
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000358 std::vector<std::string> expectedActions = {
359 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100360 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100361 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100362 [](const auto v) { return utils::enumToString(v); });
363
364 EXPECT_THAT(newActions, Ne(currActions));
365 EXPECT_THAT(
366 setProperty(sut->getPath(), "ReportActions", newActions).value(),
367 Eq(boost::system::errc::success));
368 EXPECT_THAT(
369 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
370 Eq(expectedActions));
371}
372
373TEST_F(TestReport, setReportActionsWithInvalidActions)
374{
375 std::vector<std::string> invalidActions = {"EmitsReadingsUpdate_1"};
376 EXPECT_THAT(
377 setProperty(sut->getPath(), "ReportActions", invalidActions).value(),
378 Eq(boost::system::errc::invalid_argument));
379 EXPECT_THAT(
380 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100381 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Patrick Williams583ba442025-02-03 14:28:19 -0500382 return utils::enumToString(v);
383 })));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100384}
385
386TEST_F(TestReport, createReportWithEmptyActions)
387{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000388 std::vector<std::string> expectedActions = {
389 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100390
391 sut = makeReport(ReportParams().reportId("TestId_1").reportActions({}));
392 EXPECT_THAT(
393 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
394 Eq(expectedActions));
395}
396
397TEST_F(TestReport, createReportWithValidUnsortedActions)
398{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000399 std::vector<std::string> newActions = {
400 utils::enumToString(ReportAction::logToMetricReportsCollection),
401 utils::enumToString(ReportAction::emitsReadingsUpdate)};
402 std::vector<std::string> expectedActions = {
403 utils::enumToString(ReportAction::emitsReadingsUpdate),
404 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100405
406 sut = makeReport(
407 ReportParams()
408 .reportId("TestId_1")
409 .reportActions(utils::transform(newActions, [](const auto& action) {
Patrick Williams583ba442025-02-03 14:28:19 -0500410 return utils::toReportAction(action);
411 })));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100412 EXPECT_THAT(
413 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
414 Eq(expectedActions));
415}
416
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200417TEST_F(TestReport, setEnabledWithNewValue)
418{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100419 bool newValue = !defaultParams().enabled();
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200420 EXPECT_THAT(setProperty(sut->getPath(), "Enabled", newValue).value(),
421 Eq(boost::system::errc::success));
422 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(newValue));
423}
424
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000425TEST_F(TestReport, setReportingPropertiesWithValidValues)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200426{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200427 uint64_t newValue = ReportManager::minInterval.count() * 42;
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000428 EXPECT_THAT(callMethod(sut->getPath(), "SetReportingProperties",
429 utils::enumToString(ReportingType::periodic),
430 newValue),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200431 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200432 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
433 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200434}
435
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000436TEST_F(TestReport, failsToSetInvalidInterval)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200437{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200438 uint64_t newValue = ReportManager::minInterval.count() - 1;
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000439
Patrick Williams583ba442025-02-03 14:28:19 -0500440 EXPECT_THAT(callMethod(sut->getPath(), "SetReportingProperties", "",
441 newValue),
442 Eq(boost::system::errc::invalid_argument));
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000443
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200444 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100445 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100446}
447
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000448TEST_F(TestReport, failsToSetIncompatibleInterval)
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200449{
450 auto report = makeReport(defaultParams()
451 .reportId("report2")
452 .reportingType(ReportingType::onRequest)
453 .interval(Milliseconds{0}));
454
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000455 uint64_t newValue = ReportManager::minInterval.count();
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200456
Patrick Williams583ba442025-02-03 14:28:19 -0500457 EXPECT_THAT(callMethod(report->getPath(), "SetReportingProperties", "",
458 newValue),
459 Eq(boost::system::errc::invalid_argument));
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200460
461 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000462 Eq(defaultParams().interval().count()));
463}
464
465TEST_F(TestReport, failsToSetInvalidReportingType)
466{
467 auto report = makeReport(defaultParams()
468 .reportId("report2")
469 .reportingType(ReportingType::onRequest)
470 .interval(Milliseconds{0}));
471
472 EXPECT_THAT(callMethod(sut->getPath(), "SetReportingProperties", "XYZ",
473 std::numeric_limits<uint64_t>::max()),
474 Eq(boost::system::errc::invalid_argument));
475
476 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
477 Eq(utils::enumToString(ReportingType::onRequest)));
478}
479
480TEST_F(TestReport, failsToSetIncompatibleReportingType)
481{
482 auto report = makeReport(defaultParams()
483 .reportId("report2")
484 .reportingType(ReportingType::onRequest)
485 .interval(Milliseconds{0}));
486
487 EXPECT_THAT(callMethod(sut->getPath(), "SetReportingProperties",
488 utils::enumToString(ReportingType::periodic),
489 std::numeric_limits<uint64_t>::max()),
490 Eq(boost::system::errc::invalid_argument));
491
492 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
493 Eq(utils::enumToString(ReportingType::onRequest)));
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200494}
495
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200496TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
497{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100498 EXPECT_THAT(
499 setProperty(sut->getPath(), "EmitsReadingsUpdate", true).value(),
500 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200501 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100502 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100503 ReportAction::emitsReadingsUpdate)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200504}
505
506TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
507{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100508 EXPECT_THAT(
509 setProperty(sut->getPath(), "LogToMetricReportsCollection", true)
510 .value(),
511 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200512 EXPECT_THAT(
513 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100514 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100515 ReportAction::logToMetricReportsCollection)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200516}
517
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100518TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
519{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100520 EXPECT_CALL(storageMock, store(_, _)).Times(0);
521 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
522 .Times(AtLeast(1));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100523
524 bool persistency = false;
525 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
526 Eq(boost::system::errc::success));
527 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
528 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200529}
530
531TEST_F(TestReport, deleteReport)
532{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200533 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
534 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200535 EXPECT_THAT(ec, Eq(boost::system::errc::success));
536}
537
538TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
539{
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200540 auto ec =
541 deleteReport(utils::constants::reportDirPath.str + "NonExisting"s);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200542 EXPECT_THAT(ec.value(), Eq(EBADR));
543}
544
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100545TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
546{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100547 EXPECT_CALL(storageMock, store(_, _)).Times(0);
548 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
549 .Times(AtLeast(1));
550
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100551 auto ec = deleteReport(sut->getPath());
552 EXPECT_THAT(ec, Eq(boost::system::errc::success));
553}
554
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100555TEST_F(TestReport, updatesTriggerIdWhenTriggerIsAdded)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100556{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100557 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100558
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100559 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100560 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100561 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100562 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100563 messanger.send(messages::TriggerPresenceChangedInd{
564 messages::Presence::Exist, "trigger2", {"someOtherReport"}});
565 messanger.send(messages::TriggerPresenceChangedInd{
566 messages::Presence::Exist,
567 "trigger3",
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100568 {"someOtherReport", defaultParams().reportId()}});
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100569
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100570 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200571 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
572 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
573 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100574}
575
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100576TEST_F(TestReport, updatesTriggerIdWhenTriggerIsRemoved)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100577{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100578 utils::Messanger messanger(DbusEnvironment::getIoc());
579
580 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100581 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100582 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100583 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100584 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100585 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100586
587 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100588 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100589 messanger.send(messages::TriggerPresenceChangedInd{
590 messages::Presence::Removed, "trigger2", {}});
591 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100592 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100593
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100594 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200595 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
596 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100597}
598
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100599TEST_F(TestReport, updatesTriggerIdWhenTriggerIsModified)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100600{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100601 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100602
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100603 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100604 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100605 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100606 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100607 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100608 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100609
610 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100611 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100612 messanger.send(messages::TriggerPresenceChangedInd{
613 messages::Presence::Exist, "trigger2", {}});
614 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100615 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +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
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100623class TestReportStore :
624 public TestReport,
625 public WithParamInterface<std::pair<std::string, nlohmann::json>>
626{
Patrick Williams3a1c2972023-05-10 07:51:04 -0500627 void SetUp() override {}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100628};
629
630INSTANTIATE_TEST_SUITE_P(
631 _, TestReportStore,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100632 Values(
633 std::make_pair("Enabled"s, nlohmann::json(defaultParams().enabled())),
Krzysztof Grobelny18e71012022-11-02 13:17:01 +0000634 std::make_pair("Version"s, nlohmann::json(7)),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100635 std::make_pair("Id"s, nlohmann::json(defaultParams().reportId())),
636 std::make_pair("Name"s, nlohmann::json(defaultParams().reportName())),
637 std::make_pair("ReportingType",
638 nlohmann::json(defaultParams().reportingType())),
639 std::make_pair("ReportActions", nlohmann::json(utils::transform(
640 defaultParams().reportActions(),
641 [](const auto v) {
Patrick Williamsf535cad2024-08-16 15:21:20 -0400642 return utils::toUnderlying(v);
643 }))),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100644 std::make_pair("Interval",
645 nlohmann::json(defaultParams().interval().count())),
646 std::make_pair("AppendLimit",
647 nlohmann::json(ReportParams().appendLimit())),
648 std::make_pair(
649 "ReadingParameters",
650 nlohmann::json(
651 {{{tstring::SensorPath::str(),
652 {{{tstring::Service::str(), "Service"},
653 {tstring::Path::str(),
654 "/xyz/openbmc_project/sensors/power/p1"},
655 {tstring::Metadata::str(), "metadata1"}}}},
656 {tstring::OperationType::str(), OperationType::avg},
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100657 {tstring::CollectionTimeScope::str(),
658 CollectionTimeScope::point},
659 {tstring::CollectionDuration::str(), 0}},
660 {{tstring::SensorPath::str(),
661 {{{tstring::Service::str(), "Service"},
662 {tstring::Path::str(),
663 "/xyz/openbmc_project/sensors/power/p2"},
664 {tstring::Metadata::str(), "metadata2"}}}},
665 {tstring::OperationType::str(), OperationType::avg},
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100666 {tstring::CollectionTimeScope::str(),
667 CollectionTimeScope::point},
668 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100669
670TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
671{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100672 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100673
674 {
675 InSequence seq;
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100676 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100677 EXPECT_CALL(checkPoint, Call());
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100678 EXPECT_CALL(storageMock, store(to_file_path(sut->getId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100679 }
680
681 setProperty(sut->getPath(), "Persistency", false);
682 checkPoint.Call();
683 setProperty(sut->getPath(), "Persistency", true);
684
685 const auto& [key, value] = GetParam();
686
687 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
688}
689
690TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
691{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100692 EXPECT_CALL(storageMock,
693 store(to_file_path(defaultParams().reportId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100694
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100695 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100696
697 const auto& [key, value] = GetParam();
698
699 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
700}
701
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200702class TestReportValidNames :
703 public TestReport,
704 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200705{
706 public:
Patrick Williams3a1c2972023-05-10 07:51:04 -0500707 void SetUp() override {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200708};
709
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200710INSTANTIATE_TEST_SUITE_P(
711 ValidNames, TestReportValidNames,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100712 Values(defaultParams().reportName("Valid_1"),
713 defaultParams().reportName("Valid_1/Valid_2"),
714 defaultParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200715
716TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
717{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200718 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200719}
720
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100721class TestReportInvalidIds :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200722 public TestReport,
723 public WithParamInterface<ReportParams>
724{
725 public:
Patrick Williams3a1c2972023-05-10 07:51:04 -0500726 void SetUp() override {}
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200727};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200728
Patrick Williams583ba442025-02-03 14:28:19 -0500729INSTANTIATE_TEST_SUITE_P(
730 InvalidNames, TestReportInvalidIds,
731 Values(defaultParams().reportId("/"), defaultParams().reportId("/Invalid"),
732 defaultParams().reportId("Invalid/"),
733 defaultParams().reportId("Invalid/Invalid/"),
734 defaultParams().reportId("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200735
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100736TEST_P(TestReportInvalidIds, failsToCreateReportWithInvalidName)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100737{
738 EXPECT_CALL(storageMock, store).Times(0);
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100739
740 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100741}
742
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200743class TestReportAllReportTypes :
744 public TestReport,
745 public WithParamInterface<ReportParams>
746{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200747 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200748 void SetUp() override
749 {
750 sut = makeReport(GetParam());
751 }
752};
753
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100754INSTANTIATE_TEST_SUITE_P(
755 _, TestReportAllReportTypes,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100756 Values(defaultParams().reportingType(ReportingType::onRequest),
757 defaultParams().reportingType(ReportingType::onChange),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200758 defaultParams()
759 .reportingType(ReportingType::periodic)
760 .interval(ReportManager::minInterval)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200761
762TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
763{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100764 EXPECT_THAT(utils::toReportingType(
765 getProperty<std::string>(sut->getPath(), "ReportingType")),
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200766 Eq(GetParam().reportingType()));
767}
768
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100769TEST_P(TestReportAllReportTypes, readingsAreUpdated)
770{
771 clockFake.system.advance(10ms);
772
773 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Patrick Williams583ba442025-02-03 14:28:19 -0500774 const auto [timestamp, readings] =
775 getProperty<Readings>(sut->getPath(), "Readings");
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100776
777 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
778}
779
780TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIsDisabled)
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200781{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100782 clockFake.system.advance(10ms);
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200783
784 setProperty(sut->getPath(), "Enabled", false);
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100785 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Patrick Williams583ba442025-02-03 14:28:19 -0500786 const auto [timestamp, readings] =
787 getProperty<Readings>(sut->getPath(), "Readings");
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200788
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100789 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200790}
791
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100792TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIdDiffers)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100793{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100794 clockFake.system.advance(10ms);
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100795
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100796 messanger.send(messages::UpdateReportInd{{sut->getId() + "x"s}});
Patrick Williams583ba442025-02-03 14:28:19 -0500797 const auto [timestamp, readings] =
798 getProperty<Readings>(sut->getPath(), "Readings");
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100799
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100800 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100801}
802
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100803class TestReportOnRequestType : public TestReport
804{
805 void SetUp() override
806 {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100807 sut =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100808 makeReport(defaultParams().reportingType(ReportingType::onRequest));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100809 }
810};
811
812TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
813{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100814 clockFake.system.advance(10ms);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100815
816 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
817
Patrick Williams583ba442025-02-03 14:28:19 -0500818 const auto [timestamp, readings] =
819 getProperty<Readings>(sut->getPath(), "Readings");
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100820
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100821 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100822}
823
824TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
825{
826 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
827
Patrick Williams583ba442025-02-03 14:28:19 -0500828 const auto [timestamp, readings] =
829 getProperty<Readings>(sut->getPath(), "Readings");
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100830
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000831 EXPECT_THAT(readings, ElementsAre(std::make_tuple("b"s, 17.1, 114u),
832 std::make_tuple("bb"s, 42.0, 74u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100833}
834
835class TestReportNonOnRequestType :
836 public TestReport,
837 public WithParamInterface<ReportParams>
838{
839 void SetUp() override
840 {
841 sut = makeReport(GetParam());
842 }
843};
844
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000845INSTANTIATE_TEST_SUITE_P(_, TestReportNonOnRequestType,
846 Values(defaultParams()
847 .reportingType(ReportingType::periodic)
848 .interval(ReportManager::minInterval * 10),
849 defaultParams()
850 .reportingType(ReportingType::onChange)
851 .interval(Milliseconds(0))));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100852
853TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
854{
855 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
856
857 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
858 Eq(Readings{}));
859}
860
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200861class TestReportNonPeriodicReport :
862 public TestReport,
863 public WithParamInterface<ReportParams>
864{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200865 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200866 void SetUp() override
867 {
868 sut = makeReport(GetParam());
869 }
870};
871
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100872INSTANTIATE_TEST_SUITE_P(
873 _, TestReportNonPeriodicReport,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100874 Values(defaultParams().reportingType(ReportingType::onRequest),
875 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200876
877TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
878{
879 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
880
881 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
882 Eq(Readings{}));
883}
884
885class TestReportPeriodicReport : public TestReport
886{
887 void SetUp() override
888 {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200889 sut = makeReport(defaultParams()
Krzysztof Grobelny18e71012022-11-02 13:17:01 +0000890 .appendLimit(2u)
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200891 .reportingType(ReportingType::periodic)
892 .interval(ReportManager::minInterval));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200893 }
894};
895
896TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
897{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100898 clockFake.system.advance(10ms);
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200899 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
900
Patrick Williams583ba442025-02-03 14:28:19 -0500901 const auto [timestamp, readings] =
902 getProperty<Readings>(sut->getPath(), "Readings");
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200903
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100904 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200905}
906
907TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
908{
909 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
910
Patrick Williams583ba442025-02-03 14:28:19 -0500911 const auto [timestamp, readings] =
912 getProperty<Readings>(sut->getPath(), "Readings");
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200913
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000914 EXPECT_THAT(readings, ElementsAre(std::make_tuple("b"s, 17.1, 114u),
915 std::make_tuple("bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200916}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100917
Szymon Dompke3eb56862021-09-20 15:32:04 +0200918struct ReportUpdatesReportParams
919{
920 ReportParams reportParams;
921 std::vector<ReadingData> expectedReadings;
922 bool expectedEnabled;
Michal Orzelb3e03d22024-06-28 13:55:47 +0200923
924 friend void PrintTo(const ReportUpdatesReportParams& params,
925 std::ostream* os)
926 {
927 *os << "{ ReportParams: ";
928 PrintTo(params.reportParams, os);
929 *os << ", ExpectedReadings: ";
930 PrintTo(params.expectedReadings, os);
931 *os << ", ExpectedEnabled: " << params.expectedEnabled << " }";
932 }
Szymon Dompke3eb56862021-09-20 15:32:04 +0200933};
934
935class TestReportWithReportUpdatesAndLimit :
936 public TestReport,
937 public WithParamInterface<ReportUpdatesReportParams>
938{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200939 public:
Patrick Williams3a1c2972023-05-10 07:51:04 -0500940 void SetUp() override {}
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200941
942 void changeReport(ReportingType rt, Milliseconds interval)
Szymon Dompke3eb56862021-09-20 15:32:04 +0200943 {
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000944 callMethod(sut->getPath(), "SetReportingProperties",
945 utils::enumToString(rt), interval.count());
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200946 }
947
948 auto readings()
949 {
Patrick Williams583ba442025-02-03 14:28:19 -0500950 auto [timestamp,
951 readings] = getProperty<Readings>(sut->getPath(), "Readings");
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200952 return readings;
953 }
954
955 void updateReportFourTimes()
956 {
957 for (int i = 0; i < 4; i++)
958 {
959 messanger.send(messages::UpdateReportInd{{sut->getId()}});
960 }
Szymon Dompke3eb56862021-09-20 15:32:04 +0200961 }
962};
963
964INSTANTIATE_TEST_SUITE_P(
965 _, TestReportWithReportUpdatesAndLimit,
966 Values(
967 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100968 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100969 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
970 .appendLimit(5),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000971 std::vector<ReadingData>{{std::make_tuple("bb"s, 42.0, 74u),
972 std::make_tuple("b"s, 17.1, 114u),
973 std::make_tuple("bb"s, 42.0, 74u),
974 std::make_tuple("bb"s, 42.0, 74u),
975 std::make_tuple("b"s, 17.1, 114u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +0200976 true},
977 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100978 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100979 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
980 .appendLimit(4),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000981 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
982 std::make_tuple("bb"s, 42.0, 74u),
983 std::make_tuple("b"s, 17.1, 114u),
984 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +0200985 true},
986 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100987 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100988 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
989 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200990 std::vector<ReadingData>{}, true},
991 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100992 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100993 .reportUpdates(ReportUpdates::appendStopsWhenFull)
994 .appendLimit(10),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000995 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
996 std::make_tuple("bb"s, 42.0, 74u),
997 std::make_tuple("b"s, 17.1, 114u),
998 std::make_tuple("bb"s, 42.0, 74u),
999 std::make_tuple("b"s, 17.1, 114u),
1000 std::make_tuple("bb"s, 42.0, 74u),
1001 std::make_tuple("b"s, 17.1, 114u),
1002 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001003 true},
1004 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001005 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001006 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1007 .appendLimit(5),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001008 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1009 std::make_tuple("bb"s, 42.0, 74u),
1010 std::make_tuple("b"s, 17.1, 114u),
1011 std::make_tuple("bb"s, 42.0, 74u),
1012 std::make_tuple("b"s, 17.1, 114u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001013 false},
1014 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001015 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001016 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1017 .appendLimit(4),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001018 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1019 std::make_tuple("bb"s, 42.0, 74u),
1020 std::make_tuple("b"s, 17.1, 114u),
1021 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001022 false},
1023 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001024 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001025 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1026 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001027 std::vector<ReadingData>{}, false},
1028 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001029 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001030 .reportUpdates(ReportUpdates::overwrite)
1031 .appendLimit(500),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001032 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1033 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001034 true},
1035 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001036 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001037 .reportUpdates(ReportUpdates::overwrite)
1038 .appendLimit(1),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001039 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1040 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001041 true},
1042 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001043 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001044 .reportUpdates(ReportUpdates::overwrite)
1045 .appendLimit(0),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001046 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1047 std::make_tuple("bb"s, 42.0, 74u)}},
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001048 true},
1049 ReportUpdatesReportParams{
1050 defaultParams()
1051 .reportUpdates(ReportUpdates::appendStopsWhenFull)
Krzysztof Grobelny18e71012022-11-02 13:17:01 +00001052 .appendLimit(2u),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001053 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1054 std::make_tuple("bb"s, 42.0, 74u)}},
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001055 false}));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001056
1057TEST_P(TestReportWithReportUpdatesAndLimit,
1058 readingsAreUpdatedAfterIntervalExpires)
1059{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001060 sut = makeReport(ReportParams(GetParam().reportParams)
1061 .reportingType(ReportingType::periodic)
1062 .interval(std::chrono::hours(1000)));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001063
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001064 updateReportFourTimes();
Szymon Dompke3eb56862021-09-20 15:32:04 +02001065
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001066 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1067 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1068 Eq(GetParam().expectedEnabled));
1069}
1070
1071TEST_P(TestReportWithReportUpdatesAndLimit,
1072 appendLimitIsRespectedAfterChangingToPeriodic)
1073{
1074 sut = makeReport(ReportParams(GetParam().reportParams)
Krzysztof Grobelny18e71012022-11-02 13:17:01 +00001075 .appendLimit(GetParam().expectedReadings.size())
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001076 .reportingType(ReportingType::onRequest)
1077 .interval(std::chrono::hours(0)));
1078
1079 changeReport(ReportingType::periodic, std::chrono::hours(1000));
1080 updateReportFourTimes();
1081
1082 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1083 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1084 Eq(GetParam().expectedEnabled));
1085}
1086
1087TEST_P(TestReportWithReportUpdatesAndLimit,
1088 appendLimitIsIgnoredAfterChangingToOnRequest)
1089{
1090 sut = makeReport(ReportParams(GetParam().reportParams)
1091 .reportingType(ReportingType::periodic)
1092 .interval(std::chrono::hours(1000)));
1093
1094 changeReport(ReportingType::onRequest, Milliseconds{0});
1095 updateReportFourTimes();
1096
1097 EXPECT_THAT(readings(), SizeIs(2u));
1098 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(true));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001099}
1100
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001101class TestReportInitialization : public TestReport
1102{
1103 public:
1104 void SetUp() override
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001105 {
1106 initMetricMocks(defaultParams().metricParameters());
1107 }
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001108
Patrick Williams39cc6ac2022-07-22 19:26:56 -05001109 void monitorProc(sdbusplus::message_t& msg)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001110 {
1111 std::string iface;
1112 std::vector<std::pair<std::string, std::variant<Readings>>>
1113 changed_properties;
1114 std::vector<std::string> invalidated_properties;
1115
1116 msg.read(iface, changed_properties, invalidated_properties);
1117
1118 if (iface == Report::reportIfaceName)
1119 {
1120 for (const auto& [name, value] : changed_properties)
1121 {
1122 if (name == "Readings")
1123 {
1124 readingsUpdated.Call();
1125 }
1126 }
1127 }
1128 }
1129
1130 void makeMonitor()
1131 {
Patrick Williams3a62ee12021-12-03 10:13:25 -06001132 monitor = std::make_unique<sdbusplus::bus::match_t>(
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001133 *DbusEnvironment::getBus(),
1134 sdbusplus::bus::match::rules::propertiesChanged(
1135 sut->getPath(), Report::reportIfaceName),
1136 [this](auto& msg) { monitorProc(msg); });
1137 }
1138
Patrick Williams3a62ee12021-12-03 10:13:25 -06001139 std::unique_ptr<sdbusplus::bus::match_t> monitor;
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001140 MockFunction<void()> readingsUpdated;
1141};
1142
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001143TEST_F(TestReportInitialization,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001144 registersForMetricUpdatesWhenOnChangeReportCreated)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001145{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001146 std::vector<const interfaces::MetricListener*> args;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001147 for (auto& metric : metricMocks)
1148 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001149 EXPECT_CALL(*metric, registerForUpdates(_))
1150 .WillOnce(Invoke([&args](const interfaces::MetricListener& report) {
Patrick Williams583ba442025-02-03 14:28:19 -05001151 args.emplace_back(&report);
1152 }));
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001153 ;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001154 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001155
1156 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1157
1158 EXPECT_THAT(args, SizeIs(metricMocks.size()));
1159 for (const auto* reportPtr : args)
1160 {
1161 EXPECT_THAT(reportPtr, Eq(sut.get()));
1162 }
1163}
1164
1165TEST_F(TestReportInitialization,
1166 deregistersForMetricUpdatesWhenOnChangeReportDestroyed)
1167{
1168 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1169
1170 for (auto& metric : metricMocks)
1171 {
1172 EXPECT_CALL(*metric,
1173 unregisterFromUpdates(Ref(
1174 static_cast<interfaces::MetricListener&>(*sut.get()))));
1175 }
1176
1177 sut = nullptr;
1178}
1179
1180TEST_F(TestReportInitialization,
1181 metricsAreInitializedWhenEnabledReportConstructed)
1182{
1183 for (auto& metric : metricMocks)
1184 {
1185 EXPECT_CALL(*metric, initialize());
1186 }
1187 sut = makeReport(defaultParams().enabled(true));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001188}
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001189
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001190TEST_F(TestReportInitialization,
1191 metricsAreNotInitializedWhenDisabledReportConstructed)
1192{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001193 for (auto& metric : metricMocks)
1194 {
1195 EXPECT_CALL(*metric, initialize()).Times(0);
1196 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001197 sut = makeReport(defaultParams().enabled(false));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001198}
1199
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001200TEST_F(TestReportInitialization,
1201 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001202{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001203 EXPECT_CALL(readingsUpdated, Call())
1204 .WillOnce(
1205 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
1206
1207 const auto elapsed = DbusEnvironment::measureTime([this] {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001208 sut = makeReport(defaultParams()
1209 .reportingType(ReportingType::periodic)
1210 .reportActions({ReportAction::emitsReadingsUpdate})
1211 .interval(ReportManager::minInterval));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001212 makeMonitor();
1213 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
1214 });
1215
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001216 EXPECT_THAT(elapsed, AllOf(Ge(ReportManager::minInterval),
1217 Lt(ReportManager::minInterval * 2)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001218}
1219
1220TEST_F(TestReportInitialization,
1221 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
1222{
1223 EXPECT_CALL(readingsUpdated, Call()).Times(0);
1224
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001225 sut = makeReport(defaultParams()
1226 .reportingType(ReportingType::periodic)
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001227 .reportActions({})
1228 .interval(Milliseconds(1000)));
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001229 makeMonitor();
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001230 DbusEnvironment::sleepFor(defaultParams().interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001231}
Szymon Dompke3eb56862021-09-20 15:32:04 +02001232
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001233TEST_F(TestReportInitialization, triggerIdsPropertyIsInitialzed)
1234{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001235 for (const auto& triggerId : {"trigger1", "trigger2"})
1236 {
1237 messanger.on_receive<messages::CollectTriggerIdReq>(
Szymon Dompkee0ed5082022-05-20 10:54:25 +02001238 [this, triggerId](const auto& msg) {
Patrick Williams583ba442025-02-03 14:28:19 -05001239 messanger.send(messages::CollectTriggerIdResp{triggerId});
1240 });
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001241 }
1242
1243 sut = makeReport(ReportParams());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001244
1245 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +02001246 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
1247 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
1248 utils::constants::triggerDirPath / "trigger2"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001249}
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001250
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +01001251TEST_F(TestReportInitialization,
1252 metricValuesAreNotStoredForReportUpdatesDifferentThanAppendStopsWhenFull)
1253{
1254 sut = makeReport(ReportParams()
1255 .reportingType(ReportingType::periodic)
1256 .interval(1h)
1257 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1258 .readings(Readings{{}, {{}}}));
1259
1260 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1261 Eq(storedConfiguration.end()));
1262}
1263
1264TEST_F(TestReportInitialization, metricValuesAreNotStoredForOnRequestReport)
1265{
1266 sut = makeReport(ReportParams()
1267 .reportingType(ReportingType::onRequest)
1268 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1269 .readings(Readings{{}, {{}}}));
1270
1271 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1272 Eq(storedConfiguration.end()));
1273}
1274
1275TEST_F(TestReportInitialization,
1276 metricValuesAreStoredForNonOnRequestReportWithAppendStopsWhenFull)
1277{
1278 const auto readings = Readings{{}, {{}}};
1279
1280 sut = makeReport(ReportParams()
1281 .reportingType(ReportingType::periodic)
1282 .interval(1h)
1283 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1284 .readings(readings));
1285
1286 ASSERT_THAT(storedConfiguration.at("MetricValues").get<LabeledReadings>(),
1287 Eq(utils::toLabeledReadings(readings)));
1288}
1289
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001290class TestReportInitializationOnChangeReport : public TestReportInitialization
1291{
1292 public:
1293 void SetUp() override
1294 {
1295 initMetricMocks(params.metricParameters());
1296 }
1297
1298 ReportParams params = defaultOnChangeParams();
1299};
1300
1301TEST_F(TestReportInitializationOnChangeReport,
1302 doesntUpdateReadingsWhenNotRequired)
1303{
1304 EXPECT_CALL(*metricMocks[0], updateReadings(_)).Times(0);
1305
1306 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(false));
1307
1308 sut = makeReport(params);
1309
1310 DbusEnvironment::sleepFor(500ms);
1311}
1312
1313TEST_F(TestReportInitializationOnChangeReport, updatesReadingsWhenRequired)
1314{
1315 EXPECT_CALL(*metricMocks[0], updateReadings(_))
1316 .WillOnce(Return())
1317 .WillOnce(
1318 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")))
1319 .WillRepeatedly(Return());
1320
1321 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(true));
1322
1323 sut = makeReport(params);
1324
1325 DbusEnvironment::waitForFuture("readingsUpdated");
1326}