blob: 709efdd24bf6847ea7ba3bc2580b5b97ac79cb42 [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>>
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 Grobelnycff70c12022-10-27 07:16:08 +0000164 template <class... Args>
165 static boost::system::error_code callMethod(const std::string& path,
166 const std::string& method,
167 Args&&... args)
168 {
169 return DbusEnvironment::callMethod(path, Report::reportIfaceName,
170 "SetReportingProperties",
171 std::forward<Args>(args)...);
172 }
173
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200174 template <class T>
175 struct ChangePropertyParams
176 {
177 Matcher<T> valueBefore = _;
178 T newValue;
179 Matcher<boost::system::error_code> ec =
180 Eq(boost::system::errc::success);
181 Matcher<T> valueAfter = Eq(newValue);
182 };
183
184 template <class T>
185 static void changeProperty(const std::string& path,
186 const std::string& property,
187 ChangePropertyParams<T> p)
188 {
189 ASSERT_THAT(getProperty<T>(path, property), p.valueBefore);
190 ASSERT_THAT(setProperty<T>(path, property, p.newValue), p.ec);
191 EXPECT_THAT(getProperty<T>(path, property), p.valueAfter);
192 }
193
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100194 boost::system::error_code call(const std::string& path,
195 const std::string& interface,
196 const std::string& method)
197 {
198 std::promise<boost::system::error_code> methodPromise;
199 DbusEnvironment::getBus()->async_method_call(
200 [&methodPromise](boost::system::error_code ec) {
Patrick Williams3a1c2972023-05-10 07:51:04 -0500201 methodPromise.set_value(ec);
Patrick Williamsf535cad2024-08-16 15:21:20 -0400202 }, DbusEnvironment::serviceName(), path, interface, method);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100203 return DbusEnvironment::waitForFuture(methodPromise.get_future());
204 }
205
206 boost::system::error_code update(const std::string& path)
207 {
208 return call(path, Report::reportIfaceName, "Update");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200209 }
210
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200211 boost::system::error_code deleteReport(const std::string& path)
212 {
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100213 return call(path, Report::deleteIfaceName, "Delete");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200214 }
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200215
216 static std::pair<std::string, std::vector<std::string>>
217 makeStateDetail(const std::string& detailType,
218 std::vector<std::string> detailArgs)
219 {
220 return make_pair(detailType, detailArgs);
221 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200222};
223
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100224TEST_F(TestReport, returnsId)
225{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100226 EXPECT_THAT(sut->getId(), Eq(defaultParams().reportId()));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100227}
228
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200229TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
230{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200231 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100232 Eq(defaultParams().enabled()));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200233 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100234 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100235 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100236 EXPECT_THAT(
237 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100238 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Patrick Williamsc7935fa2023-10-20 11:19:30 -0500239 return utils::enumToString(v);
240 })));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200241 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100242 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100243 ReportAction::emitsReadingsUpdate)));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200244 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "AppendLimit"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100245 Eq(defaultParams().appendLimit()));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100246 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100247 Eq(utils::enumToString(defaultParams().reportingType())));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200248 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportUpdates"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100249 Eq(utils::enumToString(defaultParams().reportUpdates())));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200250 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200251 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100252 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100253 ReportAction::logToMetricReportsCollection)));
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000254 EXPECT_THAT(
255 getProperty<ReadingParameters>(sut->getPath(), "ReadingParameters"),
256 Eq(toReadingParameters(defaultParams().metricParameters())));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100257 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100258 Eq(defaultParams().reportName()));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100259 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200260 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200261 IsEmpty());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200262}
263
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200264TEST_F(TestReport, readingsAreInitialyEmpty)
265{
266 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
267 Eq(Readings{}));
268}
269
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100270TEST_F(TestReport, setReadingParametersWithNewParams)
271{
272 ReadingParameters newParams = toReadingParameters(
273 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
274 {LabeledSensorInfo{"Service",
275 "/xyz/openbmc_project/sensors/power/psu",
276 "NewMetadata123"}},
277 OperationType::avg,
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100278 CollectionTimeScope::startup,
279 CollectionDuration(250ms)}}});
280 auto metrics = getMetricsFromReadingParams(newParams);
281
282 EXPECT_CALL(*reportFactoryMock, updateMetrics(_, _, _))
283 .WillOnce(SetArgReferee<0>(metrics));
284 EXPECT_THAT(
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000285 setProperty(sut->getPath(), "ReadingParameters", newParams).value(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100286 Eq(boost::system::errc::success));
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000287 EXPECT_THAT(
288 getProperty<ReadingParameters>(sut->getPath(), "ReadingParameters"),
289 Eq(newParams));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100290}
291
Michal Orzel5e7cbf42024-08-01 15:44:42 +0200292TEST_F(TestReport, setReadingParametersFailsWhenMetricCountExceedsAllowedValue)
293{
294 std::vector<LabeledMetricParameters> readingParams{{LabeledMetricParameters{
295 {LabeledSensorInfo{"Service", "/xyz/openbmc_project/sensors/power/psu",
296 "NewMetadata123"}},
297 OperationType::avg,
298 CollectionTimeScope::startup,
299 CollectionDuration(250ms)}}};
300
301 auto& metricParamsVec =
302 readingParams[0].at_label<utils::tstring::SensorPath>();
303 for (size_t i = 0; i < ReportManager::maxNumberMetrics; i++)
304 {
305 metricParamsVec.emplace_back(LabeledSensorInfo{
306 "Service", "/xyz/openbmc_project/sensors/power/psu",
307 "NewMetadata123"});
308 }
309
310 ReadingParameters newParams = toReadingParameters(readingParams);
311
312 EXPECT_THAT(
313 setProperty(sut->getPath(), "ReadingParameters", newParams).value(),
314 Eq(boost::system::errc::invalid_argument));
315}
316
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100317TEST_F(TestReport, setReportActionsWithValidNewActions)
318{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000319 std::vector<std::string> newActions = {
320 utils::enumToString(ReportAction::emitsReadingsUpdate)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100321 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100322 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100323 [](const auto v) { return utils::enumToString(v); });
324
325 EXPECT_THAT(newActions, Ne(currActions));
326 EXPECT_THAT(
327 setProperty(sut->getPath(), "ReportActions", newActions).value(),
328 Eq(boost::system::errc::success));
329 EXPECT_THAT(
330 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000331 UnorderedElementsAre(
332 utils::enumToString(ReportAction::emitsReadingsUpdate),
333 utils::enumToString(ReportAction::logToMetricReportsCollection)));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100334}
335
336TEST_F(TestReport, setReportActionsWithValidUnsortedActions)
337{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000338 std::vector<std::string> newActions = {
339 utils::enumToString(ReportAction::logToMetricReportsCollection),
340 utils::enumToString(ReportAction::emitsReadingsUpdate)};
341 std::vector<std::string> expectedActions = {
342 utils::enumToString(ReportAction::emitsReadingsUpdate),
343 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100344 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100345 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100346 [](const auto v) { return utils::enumToString(v); });
347
348 EXPECT_THAT(newActions, Ne(currActions));
349 EXPECT_THAT(
350 setProperty(sut->getPath(), "ReportActions", newActions).value(),
351 Eq(boost::system::errc::success));
352 EXPECT_THAT(
353 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
354 Eq(expectedActions));
355}
356
357TEST_F(TestReport, setReportActionsWithEmptyActions)
358{
359 std::vector<std::string> newActions = {};
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000360 std::vector<std::string> expectedActions = {
361 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100362 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100363 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100364 [](const auto v) { return utils::enumToString(v); });
365
366 EXPECT_THAT(newActions, Ne(currActions));
367 EXPECT_THAT(
368 setProperty(sut->getPath(), "ReportActions", newActions).value(),
369 Eq(boost::system::errc::success));
370 EXPECT_THAT(
371 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
372 Eq(expectedActions));
373}
374
375TEST_F(TestReport, setReportActionsWithInvalidActions)
376{
377 std::vector<std::string> invalidActions = {"EmitsReadingsUpdate_1"};
378 EXPECT_THAT(
379 setProperty(sut->getPath(), "ReportActions", invalidActions).value(),
380 Eq(boost::system::errc::invalid_argument));
381 EXPECT_THAT(
382 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100383 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Patrick Williamsc7935fa2023-10-20 11:19:30 -0500384 return utils::enumToString(v);
385 })));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100386}
387
388TEST_F(TestReport, createReportWithEmptyActions)
389{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000390 std::vector<std::string> expectedActions = {
391 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100392
393 sut = makeReport(ReportParams().reportId("TestId_1").reportActions({}));
394 EXPECT_THAT(
395 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
396 Eq(expectedActions));
397}
398
399TEST_F(TestReport, createReportWithValidUnsortedActions)
400{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000401 std::vector<std::string> newActions = {
402 utils::enumToString(ReportAction::logToMetricReportsCollection),
403 utils::enumToString(ReportAction::emitsReadingsUpdate)};
404 std::vector<std::string> expectedActions = {
405 utils::enumToString(ReportAction::emitsReadingsUpdate),
406 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100407
408 sut = makeReport(
409 ReportParams()
410 .reportId("TestId_1")
411 .reportActions(utils::transform(newActions, [](const auto& action) {
Patrick Williamsc7935fa2023-10-20 11:19:30 -0500412 return utils::toReportAction(action);
413 })));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100414 EXPECT_THAT(
415 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
416 Eq(expectedActions));
417}
418
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200419TEST_F(TestReport, setEnabledWithNewValue)
420{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100421 bool newValue = !defaultParams().enabled();
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200422 EXPECT_THAT(setProperty(sut->getPath(), "Enabled", newValue).value(),
423 Eq(boost::system::errc::success));
424 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(newValue));
425}
426
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000427TEST_F(TestReport, setReportingPropertiesWithValidValues)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200428{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200429 uint64_t newValue = ReportManager::minInterval.count() * 42;
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000430 EXPECT_THAT(callMethod(sut->getPath(), "SetReportingProperties",
431 utils::enumToString(ReportingType::periodic),
432 newValue),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200433 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200434 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
435 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200436}
437
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000438TEST_F(TestReport, failsToSetInvalidInterval)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200439{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200440 uint64_t newValue = ReportManager::minInterval.count() - 1;
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000441
442 EXPECT_THAT(
443 callMethod(sut->getPath(), "SetReportingProperties", "", newValue),
444 Eq(boost::system::errc::invalid_argument));
445
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200446 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100447 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100448}
449
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000450TEST_F(TestReport, failsToSetIncompatibleInterval)
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200451{
452 auto report = makeReport(defaultParams()
453 .reportId("report2")
454 .reportingType(ReportingType::onRequest)
455 .interval(Milliseconds{0}));
456
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000457 uint64_t newValue = ReportManager::minInterval.count();
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200458
459 EXPECT_THAT(
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000460 callMethod(report->getPath(), "SetReportingProperties", "", newValue),
461 Eq(boost::system::errc::invalid_argument));
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200462
463 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000464 Eq(defaultParams().interval().count()));
465}
466
467TEST_F(TestReport, failsToSetInvalidReportingType)
468{
469 auto report = makeReport(defaultParams()
470 .reportId("report2")
471 .reportingType(ReportingType::onRequest)
472 .interval(Milliseconds{0}));
473
474 EXPECT_THAT(callMethod(sut->getPath(), "SetReportingProperties", "XYZ",
475 std::numeric_limits<uint64_t>::max()),
476 Eq(boost::system::errc::invalid_argument));
477
478 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
479 Eq(utils::enumToString(ReportingType::onRequest)));
480}
481
482TEST_F(TestReport, failsToSetIncompatibleReportingType)
483{
484 auto report = makeReport(defaultParams()
485 .reportId("report2")
486 .reportingType(ReportingType::onRequest)
487 .interval(Milliseconds{0}));
488
489 EXPECT_THAT(callMethod(sut->getPath(), "SetReportingProperties",
490 utils::enumToString(ReportingType::periodic),
491 std::numeric_limits<uint64_t>::max()),
492 Eq(boost::system::errc::invalid_argument));
493
494 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
495 Eq(utils::enumToString(ReportingType::onRequest)));
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200496}
497
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200498TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
499{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100500 EXPECT_THAT(
501 setProperty(sut->getPath(), "EmitsReadingsUpdate", true).value(),
502 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200503 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100504 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100505 ReportAction::emitsReadingsUpdate)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200506}
507
508TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
509{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100510 EXPECT_THAT(
511 setProperty(sut->getPath(), "LogToMetricReportsCollection", true)
512 .value(),
513 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200514 EXPECT_THAT(
515 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100516 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100517 ReportAction::logToMetricReportsCollection)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200518}
519
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100520TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
521{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100522 EXPECT_CALL(storageMock, store(_, _)).Times(0);
523 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
524 .Times(AtLeast(1));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100525
526 bool persistency = false;
527 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
528 Eq(boost::system::errc::success));
529 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
530 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200531}
532
533TEST_F(TestReport, deleteReport)
534{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200535 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
536 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200537 EXPECT_THAT(ec, Eq(boost::system::errc::success));
538}
539
540TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
541{
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200542 auto ec =
543 deleteReport(utils::constants::reportDirPath.str + "NonExisting"s);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200544 EXPECT_THAT(ec.value(), Eq(EBADR));
545}
546
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100547TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
548{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100549 EXPECT_CALL(storageMock, store(_, _)).Times(0);
550 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
551 .Times(AtLeast(1));
552
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100553 auto ec = deleteReport(sut->getPath());
554 EXPECT_THAT(ec, Eq(boost::system::errc::success));
555}
556
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100557TEST_F(TestReport, updatesTriggerIdWhenTriggerIsAdded)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100558{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100559 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100560
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{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100564 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100565 messanger.send(messages::TriggerPresenceChangedInd{
566 messages::Presence::Exist, "trigger2", {"someOtherReport"}});
567 messanger.send(messages::TriggerPresenceChangedInd{
568 messages::Presence::Exist,
569 "trigger3",
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100570 {"someOtherReport", defaultParams().reportId()}});
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100571
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100572 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200573 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
574 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
575 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100576}
577
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100578TEST_F(TestReport, updatesTriggerIdWhenTriggerIsRemoved)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100579{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100580 utils::Messanger messanger(DbusEnvironment::getIoc());
581
582 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100583 messages::Presence::Exist, "trigger1", {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, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100586 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100587 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100588
589 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100590 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100591 messanger.send(messages::TriggerPresenceChangedInd{
592 messages::Presence::Removed, "trigger2", {}});
593 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100594 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100595
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100596 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200597 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
598 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100599}
600
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100601TEST_F(TestReport, updatesTriggerIdWhenTriggerIsModified)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100602{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100603 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100604
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100605 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100606 messages::Presence::Exist, "trigger1", {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, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100609 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100610 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100611
612 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100613 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100614 messanger.send(messages::TriggerPresenceChangedInd{
615 messages::Presence::Exist, "trigger2", {}});
616 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100617 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100618
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100619 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200620 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
621 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
622 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100623}
624
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100625class TestReportStore :
626 public TestReport,
627 public WithParamInterface<std::pair<std::string, nlohmann::json>>
628{
Patrick Williams3a1c2972023-05-10 07:51:04 -0500629 void SetUp() override {}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100630};
631
632INSTANTIATE_TEST_SUITE_P(
633 _, TestReportStore,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100634 Values(
635 std::make_pair("Enabled"s, nlohmann::json(defaultParams().enabled())),
Krzysztof Grobelny18e71012022-11-02 13:17:01 +0000636 std::make_pair("Version"s, nlohmann::json(7)),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100637 std::make_pair("Id"s, nlohmann::json(defaultParams().reportId())),
638 std::make_pair("Name"s, nlohmann::json(defaultParams().reportName())),
639 std::make_pair("ReportingType",
640 nlohmann::json(defaultParams().reportingType())),
641 std::make_pair("ReportActions", nlohmann::json(utils::transform(
642 defaultParams().reportActions(),
643 [](const auto v) {
Patrick Williamsf535cad2024-08-16 15:21:20 -0400644 return utils::toUnderlying(v);
645 }))),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100646 std::make_pair("Interval",
647 nlohmann::json(defaultParams().interval().count())),
648 std::make_pair("AppendLimit",
649 nlohmann::json(ReportParams().appendLimit())),
650 std::make_pair(
651 "ReadingParameters",
652 nlohmann::json(
653 {{{tstring::SensorPath::str(),
654 {{{tstring::Service::str(), "Service"},
655 {tstring::Path::str(),
656 "/xyz/openbmc_project/sensors/power/p1"},
657 {tstring::Metadata::str(), "metadata1"}}}},
658 {tstring::OperationType::str(), OperationType::avg},
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100659 {tstring::CollectionTimeScope::str(),
660 CollectionTimeScope::point},
661 {tstring::CollectionDuration::str(), 0}},
662 {{tstring::SensorPath::str(),
663 {{{tstring::Service::str(), "Service"},
664 {tstring::Path::str(),
665 "/xyz/openbmc_project/sensors/power/p2"},
666 {tstring::Metadata::str(), "metadata2"}}}},
667 {tstring::OperationType::str(), OperationType::avg},
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100668 {tstring::CollectionTimeScope::str(),
669 CollectionTimeScope::point},
670 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100671
672TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
673{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100674 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100675
676 {
677 InSequence seq;
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100678 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100679 EXPECT_CALL(checkPoint, Call());
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100680 EXPECT_CALL(storageMock, store(to_file_path(sut->getId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100681 }
682
683 setProperty(sut->getPath(), "Persistency", false);
684 checkPoint.Call();
685 setProperty(sut->getPath(), "Persistency", true);
686
687 const auto& [key, value] = GetParam();
688
689 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
690}
691
692TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
693{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100694 EXPECT_CALL(storageMock,
695 store(to_file_path(defaultParams().reportId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100696
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100697 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100698
699 const auto& [key, value] = GetParam();
700
701 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
702}
703
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200704class TestReportValidNames :
705 public TestReport,
706 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200707{
708 public:
Patrick Williams3a1c2972023-05-10 07:51:04 -0500709 void SetUp() override {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200710};
711
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200712INSTANTIATE_TEST_SUITE_P(
713 ValidNames, TestReportValidNames,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100714 Values(defaultParams().reportName("Valid_1"),
715 defaultParams().reportName("Valid_1/Valid_2"),
716 defaultParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200717
718TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
719{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200720 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200721}
722
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100723class TestReportInvalidIds :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200724 public TestReport,
725 public WithParamInterface<ReportParams>
726{
727 public:
Patrick Williams3a1c2972023-05-10 07:51:04 -0500728 void SetUp() override {}
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200729};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200730
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100731INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidIds,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100732 Values(defaultParams().reportId("/"),
733 defaultParams().reportId("/Invalid"),
734 defaultParams().reportId("Invalid/"),
735 defaultParams().reportId("Invalid/Invalid/"),
736 defaultParams().reportId("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200737
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100738TEST_P(TestReportInvalidIds, failsToCreateReportWithInvalidName)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100739{
740 EXPECT_CALL(storageMock, store).Times(0);
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100741
742 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100743}
744
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200745class TestReportAllReportTypes :
746 public TestReport,
747 public WithParamInterface<ReportParams>
748{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200749 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200750 void SetUp() override
751 {
752 sut = makeReport(GetParam());
753 }
754};
755
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100756INSTANTIATE_TEST_SUITE_P(
757 _, TestReportAllReportTypes,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100758 Values(defaultParams().reportingType(ReportingType::onRequest),
759 defaultParams().reportingType(ReportingType::onChange),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200760 defaultParams()
761 .reportingType(ReportingType::periodic)
762 .interval(ReportManager::minInterval)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200763
764TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
765{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100766 EXPECT_THAT(utils::toReportingType(
767 getProperty<std::string>(sut->getPath(), "ReportingType")),
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200768 Eq(GetParam().reportingType()));
769}
770
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100771TEST_P(TestReportAllReportTypes, readingsAreUpdated)
772{
773 clockFake.system.advance(10ms);
774
775 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Patrick Williams3a1c2972023-05-10 07:51:04 -0500776 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
777 "Readings");
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100778
779 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
780}
781
782TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIsDisabled)
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200783{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100784 clockFake.system.advance(10ms);
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200785
786 setProperty(sut->getPath(), "Enabled", false);
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100787 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Patrick Williams3a1c2972023-05-10 07:51:04 -0500788 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
789 "Readings");
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200790
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100791 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200792}
793
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100794TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIdDiffers)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100795{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100796 clockFake.system.advance(10ms);
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100797
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100798 messanger.send(messages::UpdateReportInd{{sut->getId() + "x"s}});
Patrick Williams3a1c2972023-05-10 07:51:04 -0500799 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
800 "Readings");
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100801
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100802 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100803}
804
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100805class TestReportOnRequestType : public TestReport
806{
807 void SetUp() override
808 {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100809 sut =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100810 makeReport(defaultParams().reportingType(ReportingType::onRequest));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100811 }
812};
813
814TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
815{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100816 clockFake.system.advance(10ms);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100817
818 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
819
Patrick Williams3a1c2972023-05-10 07:51:04 -0500820 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
821 "Readings");
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100822
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100823 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100824}
825
826TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
827{
828 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
829
Patrick Williams3a1c2972023-05-10 07:51:04 -0500830 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
831 "Readings");
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100832
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000833 EXPECT_THAT(readings, ElementsAre(std::make_tuple("b"s, 17.1, 114u),
834 std::make_tuple("bb"s, 42.0, 74u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100835}
836
837class TestReportNonOnRequestType :
838 public TestReport,
839 public WithParamInterface<ReportParams>
840{
841 void SetUp() override
842 {
843 sut = makeReport(GetParam());
844 }
845};
846
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000847INSTANTIATE_TEST_SUITE_P(_, TestReportNonOnRequestType,
848 Values(defaultParams()
849 .reportingType(ReportingType::periodic)
850 .interval(ReportManager::minInterval * 10),
851 defaultParams()
852 .reportingType(ReportingType::onChange)
853 .interval(Milliseconds(0))));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100854
855TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
856{
857 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
858
859 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
860 Eq(Readings{}));
861}
862
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200863class TestReportNonPeriodicReport :
864 public TestReport,
865 public WithParamInterface<ReportParams>
866{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200867 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200868 void SetUp() override
869 {
870 sut = makeReport(GetParam());
871 }
872};
873
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100874INSTANTIATE_TEST_SUITE_P(
875 _, TestReportNonPeriodicReport,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100876 Values(defaultParams().reportingType(ReportingType::onRequest),
877 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200878
879TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
880{
881 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
882
883 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
884 Eq(Readings{}));
885}
886
887class TestReportPeriodicReport : public TestReport
888{
889 void SetUp() override
890 {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200891 sut = makeReport(defaultParams()
Krzysztof Grobelny18e71012022-11-02 13:17:01 +0000892 .appendLimit(2u)
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200893 .reportingType(ReportingType::periodic)
894 .interval(ReportManager::minInterval));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200895 }
896};
897
898TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
899{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100900 clockFake.system.advance(10ms);
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200901 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
902
Patrick Williams3a1c2972023-05-10 07:51:04 -0500903 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
904 "Readings");
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200905
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100906 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200907}
908
909TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
910{
911 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
912
Patrick Williams3a1c2972023-05-10 07:51:04 -0500913 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
914 "Readings");
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200915
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000916 EXPECT_THAT(readings, ElementsAre(std::make_tuple("b"s, 17.1, 114u),
917 std::make_tuple("bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200918}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100919
Szymon Dompke3eb56862021-09-20 15:32:04 +0200920struct ReportUpdatesReportParams
921{
922 ReportParams reportParams;
923 std::vector<ReadingData> expectedReadings;
924 bool expectedEnabled;
Michal Orzelb3e03d22024-06-28 13:55:47 +0200925
926 friend void PrintTo(const ReportUpdatesReportParams& params,
927 std::ostream* os)
928 {
929 *os << "{ ReportParams: ";
930 PrintTo(params.reportParams, os);
931 *os << ", ExpectedReadings: ";
932 PrintTo(params.expectedReadings, os);
933 *os << ", ExpectedEnabled: " << params.expectedEnabled << " }";
934 }
Szymon Dompke3eb56862021-09-20 15:32:04 +0200935};
936
937class TestReportWithReportUpdatesAndLimit :
938 public TestReport,
939 public WithParamInterface<ReportUpdatesReportParams>
940{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200941 public:
Patrick Williams3a1c2972023-05-10 07:51:04 -0500942 void SetUp() override {}
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200943
944 void changeReport(ReportingType rt, Milliseconds interval)
Szymon Dompke3eb56862021-09-20 15:32:04 +0200945 {
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000946 callMethod(sut->getPath(), "SetReportingProperties",
947 utils::enumToString(rt), interval.count());
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200948 }
949
950 auto readings()
951 {
Patrick Williams3a1c2972023-05-10 07:51:04 -0500952 auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
953 "Readings");
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200954 return readings;
955 }
956
957 void updateReportFourTimes()
958 {
959 for (int i = 0; i < 4; i++)
960 {
961 messanger.send(messages::UpdateReportInd{{sut->getId()}});
962 }
Szymon Dompke3eb56862021-09-20 15:32:04 +0200963 }
964};
965
966INSTANTIATE_TEST_SUITE_P(
967 _, TestReportWithReportUpdatesAndLimit,
968 Values(
969 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100970 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100971 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
972 .appendLimit(5),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000973 std::vector<ReadingData>{{std::make_tuple("bb"s, 42.0, 74u),
974 std::make_tuple("b"s, 17.1, 114u),
975 std::make_tuple("bb"s, 42.0, 74u),
976 std::make_tuple("bb"s, 42.0, 74u),
977 std::make_tuple("b"s, 17.1, 114u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +0200978 true},
979 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100980 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100981 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
982 .appendLimit(4),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000983 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
984 std::make_tuple("bb"s, 42.0, 74u),
985 std::make_tuple("b"s, 17.1, 114u),
986 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +0200987 true},
988 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100989 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100990 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
991 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200992 std::vector<ReadingData>{}, true},
993 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100994 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100995 .reportUpdates(ReportUpdates::appendStopsWhenFull)
996 .appendLimit(10),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000997 std::vector<ReadingData>{{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),
1003 std::make_tuple("b"s, 17.1, 114u),
1004 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001005 true},
1006 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001007 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001008 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1009 .appendLimit(5),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001010 std::vector<ReadingData>{{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),
1013 std::make_tuple("bb"s, 42.0, 74u),
1014 std::make_tuple("b"s, 17.1, 114u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001015 false},
1016 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001017 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001018 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1019 .appendLimit(4),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001020 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1021 std::make_tuple("bb"s, 42.0, 74u),
1022 std::make_tuple("b"s, 17.1, 114u),
1023 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001024 false},
1025 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001026 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001027 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1028 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001029 std::vector<ReadingData>{}, false},
1030 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001031 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001032 .reportUpdates(ReportUpdates::overwrite)
1033 .appendLimit(500),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001034 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1035 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001036 true},
1037 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001038 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001039 .reportUpdates(ReportUpdates::overwrite)
1040 .appendLimit(1),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001041 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1042 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001043 true},
1044 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001045 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001046 .reportUpdates(ReportUpdates::overwrite)
1047 .appendLimit(0),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001048 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1049 std::make_tuple("bb"s, 42.0, 74u)}},
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001050 true},
1051 ReportUpdatesReportParams{
1052 defaultParams()
1053 .reportUpdates(ReportUpdates::appendStopsWhenFull)
Krzysztof Grobelny18e71012022-11-02 13:17:01 +00001054 .appendLimit(2u),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001055 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1056 std::make_tuple("bb"s, 42.0, 74u)}},
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001057 false}));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001058
1059TEST_P(TestReportWithReportUpdatesAndLimit,
1060 readingsAreUpdatedAfterIntervalExpires)
1061{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001062 sut = makeReport(ReportParams(GetParam().reportParams)
1063 .reportingType(ReportingType::periodic)
1064 .interval(std::chrono::hours(1000)));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001065
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001066 updateReportFourTimes();
Szymon Dompke3eb56862021-09-20 15:32:04 +02001067
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001068 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1069 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1070 Eq(GetParam().expectedEnabled));
1071}
1072
1073TEST_P(TestReportWithReportUpdatesAndLimit,
1074 appendLimitIsRespectedAfterChangingToPeriodic)
1075{
1076 sut = makeReport(ReportParams(GetParam().reportParams)
Krzysztof Grobelny18e71012022-11-02 13:17:01 +00001077 .appendLimit(GetParam().expectedReadings.size())
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001078 .reportingType(ReportingType::onRequest)
1079 .interval(std::chrono::hours(0)));
1080
1081 changeReport(ReportingType::periodic, std::chrono::hours(1000));
1082 updateReportFourTimes();
1083
1084 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1085 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1086 Eq(GetParam().expectedEnabled));
1087}
1088
1089TEST_P(TestReportWithReportUpdatesAndLimit,
1090 appendLimitIsIgnoredAfterChangingToOnRequest)
1091{
1092 sut = makeReport(ReportParams(GetParam().reportParams)
1093 .reportingType(ReportingType::periodic)
1094 .interval(std::chrono::hours(1000)));
1095
1096 changeReport(ReportingType::onRequest, Milliseconds{0});
1097 updateReportFourTimes();
1098
1099 EXPECT_THAT(readings(), SizeIs(2u));
1100 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(true));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001101}
1102
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001103class TestReportInitialization : public TestReport
1104{
1105 public:
1106 void SetUp() override
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001107 {
1108 initMetricMocks(defaultParams().metricParameters());
1109 }
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001110
Patrick Williams39cc6ac2022-07-22 19:26:56 -05001111 void monitorProc(sdbusplus::message_t& msg)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001112 {
1113 std::string iface;
1114 std::vector<std::pair<std::string, std::variant<Readings>>>
1115 changed_properties;
1116 std::vector<std::string> invalidated_properties;
1117
1118 msg.read(iface, changed_properties, invalidated_properties);
1119
1120 if (iface == Report::reportIfaceName)
1121 {
1122 for (const auto& [name, value] : changed_properties)
1123 {
1124 if (name == "Readings")
1125 {
1126 readingsUpdated.Call();
1127 }
1128 }
1129 }
1130 }
1131
1132 void makeMonitor()
1133 {
Patrick Williams3a62ee12021-12-03 10:13:25 -06001134 monitor = std::make_unique<sdbusplus::bus::match_t>(
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001135 *DbusEnvironment::getBus(),
1136 sdbusplus::bus::match::rules::propertiesChanged(
1137 sut->getPath(), Report::reportIfaceName),
1138 [this](auto& msg) { monitorProc(msg); });
1139 }
1140
Patrick Williams3a62ee12021-12-03 10:13:25 -06001141 std::unique_ptr<sdbusplus::bus::match_t> monitor;
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001142 MockFunction<void()> readingsUpdated;
1143};
1144
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001145TEST_F(TestReportInitialization,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001146 registersForMetricUpdatesWhenOnChangeReportCreated)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001147{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001148 std::vector<const interfaces::MetricListener*> args;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001149 for (auto& metric : metricMocks)
1150 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001151 EXPECT_CALL(*metric, registerForUpdates(_))
1152 .WillOnce(Invoke([&args](const interfaces::MetricListener& report) {
Patrick Williamsc7935fa2023-10-20 11:19:30 -05001153 args.emplace_back(&report);
1154 }));
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001155 ;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001156 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001157
1158 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1159
1160 EXPECT_THAT(args, SizeIs(metricMocks.size()));
1161 for (const auto* reportPtr : args)
1162 {
1163 EXPECT_THAT(reportPtr, Eq(sut.get()));
1164 }
1165}
1166
1167TEST_F(TestReportInitialization,
1168 deregistersForMetricUpdatesWhenOnChangeReportDestroyed)
1169{
1170 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1171
1172 for (auto& metric : metricMocks)
1173 {
1174 EXPECT_CALL(*metric,
1175 unregisterFromUpdates(Ref(
1176 static_cast<interfaces::MetricListener&>(*sut.get()))));
1177 }
1178
1179 sut = nullptr;
1180}
1181
1182TEST_F(TestReportInitialization,
1183 metricsAreInitializedWhenEnabledReportConstructed)
1184{
1185 for (auto& metric : metricMocks)
1186 {
1187 EXPECT_CALL(*metric, initialize());
1188 }
1189 sut = makeReport(defaultParams().enabled(true));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001190}
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001191
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001192TEST_F(TestReportInitialization,
1193 metricsAreNotInitializedWhenDisabledReportConstructed)
1194{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001195 for (auto& metric : metricMocks)
1196 {
1197 EXPECT_CALL(*metric, initialize()).Times(0);
1198 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001199 sut = makeReport(defaultParams().enabled(false));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001200}
1201
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001202TEST_F(TestReportInitialization,
1203 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001204{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001205 EXPECT_CALL(readingsUpdated, Call())
1206 .WillOnce(
1207 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
1208
1209 const auto elapsed = DbusEnvironment::measureTime([this] {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001210 sut = makeReport(defaultParams()
1211 .reportingType(ReportingType::periodic)
1212 .reportActions({ReportAction::emitsReadingsUpdate})
1213 .interval(ReportManager::minInterval));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001214 makeMonitor();
1215 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
1216 });
1217
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001218 EXPECT_THAT(elapsed, AllOf(Ge(ReportManager::minInterval),
1219 Lt(ReportManager::minInterval * 2)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001220}
1221
1222TEST_F(TestReportInitialization,
1223 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
1224{
1225 EXPECT_CALL(readingsUpdated, Call()).Times(0);
1226
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001227 sut = makeReport(defaultParams()
1228 .reportingType(ReportingType::periodic)
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001229 .reportActions({})
1230 .interval(Milliseconds(1000)));
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001231 makeMonitor();
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001232 DbusEnvironment::sleepFor(defaultParams().interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001233}
Szymon Dompke3eb56862021-09-20 15:32:04 +02001234
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001235TEST_F(TestReportInitialization, triggerIdsPropertyIsInitialzed)
1236{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001237 for (const auto& triggerId : {"trigger1", "trigger2"})
1238 {
1239 messanger.on_receive<messages::CollectTriggerIdReq>(
Szymon Dompkee0ed5082022-05-20 10:54:25 +02001240 [this, triggerId](const auto& msg) {
Patrick Williams3a1c2972023-05-10 07:51:04 -05001241 messanger.send(messages::CollectTriggerIdResp{triggerId});
1242 });
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001243 }
1244
1245 sut = makeReport(ReportParams());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001246
1247 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +02001248 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
1249 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
1250 utils::constants::triggerDirPath / "trigger2"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001251}
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001252
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +01001253TEST_F(TestReportInitialization,
1254 metricValuesAreNotStoredForReportUpdatesDifferentThanAppendStopsWhenFull)
1255{
1256 sut = makeReport(ReportParams()
1257 .reportingType(ReportingType::periodic)
1258 .interval(1h)
1259 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1260 .readings(Readings{{}, {{}}}));
1261
1262 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1263 Eq(storedConfiguration.end()));
1264}
1265
1266TEST_F(TestReportInitialization, metricValuesAreNotStoredForOnRequestReport)
1267{
1268 sut = makeReport(ReportParams()
1269 .reportingType(ReportingType::onRequest)
1270 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1271 .readings(Readings{{}, {{}}}));
1272
1273 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1274 Eq(storedConfiguration.end()));
1275}
1276
1277TEST_F(TestReportInitialization,
1278 metricValuesAreStoredForNonOnRequestReportWithAppendStopsWhenFull)
1279{
1280 const auto readings = Readings{{}, {{}}};
1281
1282 sut = makeReport(ReportParams()
1283 .reportingType(ReportingType::periodic)
1284 .interval(1h)
1285 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1286 .readings(readings));
1287
1288 ASSERT_THAT(storedConfiguration.at("MetricValues").get<LabeledReadings>(),
1289 Eq(utils::toLabeledReadings(readings)));
1290}
1291
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001292class TestReportInitializationOnChangeReport : public TestReportInitialization
1293{
1294 public:
1295 void SetUp() override
1296 {
1297 initMetricMocks(params.metricParameters());
1298 }
1299
1300 ReportParams params = defaultOnChangeParams();
1301};
1302
1303TEST_F(TestReportInitializationOnChangeReport,
1304 doesntUpdateReadingsWhenNotRequired)
1305{
1306 EXPECT_CALL(*metricMocks[0], updateReadings(_)).Times(0);
1307
1308 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(false));
1309
1310 sut = makeReport(params);
1311
1312 DbusEnvironment::sleepFor(500ms);
1313}
1314
1315TEST_F(TestReportInitializationOnChangeReport, updatesReadingsWhenRequired)
1316{
1317 EXPECT_CALL(*metricMocks[0], updateReadings(_))
1318 .WillOnce(Return())
1319 .WillOnce(
1320 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")))
1321 .WillRepeatedly(Return());
1322
1323 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(true));
1324
1325 sut = makeReport(params);
1326
1327 DbusEnvironment::waitForFuture("readingsUpdated");
1328}