blob: e4e55106f68347fa382fade5ad09b2ceabc3c2a4 [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 Williamsc7935fa2023-10-20 11:19:30 -0500202 },
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100203 DbusEnvironment::serviceName(), path, interface, method);
204 return DbusEnvironment::waitForFuture(methodPromise.get_future());
205 }
206
207 boost::system::error_code update(const std::string& path)
208 {
209 return call(path, Report::reportIfaceName, "Update");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200210 }
211
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200212 boost::system::error_code deleteReport(const std::string& path)
213 {
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100214 return call(path, Report::deleteIfaceName, "Delete");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200215 }
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200216
217 static std::pair<std::string, std::vector<std::string>>
218 makeStateDetail(const std::string& detailType,
219 std::vector<std::string> detailArgs)
220 {
221 return make_pair(detailType, detailArgs);
222 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200223};
224
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100225TEST_F(TestReport, returnsId)
226{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100227 EXPECT_THAT(sut->getId(), Eq(defaultParams().reportId()));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100228}
229
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200230TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
231{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200232 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100233 Eq(defaultParams().enabled()));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200234 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100235 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100236 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100237 EXPECT_THAT(
238 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100239 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Patrick Williamsc7935fa2023-10-20 11:19:30 -0500240 return utils::enumToString(v);
241 })));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200242 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100243 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100244 ReportAction::emitsReadingsUpdate)));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200245 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "AppendLimit"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100246 Eq(defaultParams().appendLimit()));
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100247 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100248 Eq(utils::enumToString(defaultParams().reportingType())));
Szymon Dompke3eb56862021-09-20 15:32:04 +0200249 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportUpdates"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100250 Eq(utils::enumToString(defaultParams().reportUpdates())));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200251 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200252 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100253 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100254 ReportAction::logToMetricReportsCollection)));
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000255 EXPECT_THAT(
256 getProperty<ReadingParameters>(sut->getPath(), "ReadingParameters"),
257 Eq(toReadingParameters(defaultParams().metricParameters())));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100258 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100259 Eq(defaultParams().reportName()));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100260 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200261 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200262 IsEmpty());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200263}
264
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200265TEST_F(TestReport, readingsAreInitialyEmpty)
266{
267 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
268 Eq(Readings{}));
269}
270
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100271TEST_F(TestReport, setReadingParametersWithNewParams)
272{
273 ReadingParameters newParams = toReadingParameters(
274 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{
275 {LabeledSensorInfo{"Service",
276 "/xyz/openbmc_project/sensors/power/psu",
277 "NewMetadata123"}},
278 OperationType::avg,
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100279 CollectionTimeScope::startup,
280 CollectionDuration(250ms)}}});
281 auto metrics = getMetricsFromReadingParams(newParams);
282
283 EXPECT_CALL(*reportFactoryMock, updateMetrics(_, _, _))
284 .WillOnce(SetArgReferee<0>(metrics));
285 EXPECT_THAT(
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000286 setProperty(sut->getPath(), "ReadingParameters", newParams).value(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100287 Eq(boost::system::errc::success));
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000288 EXPECT_THAT(
289 getProperty<ReadingParameters>(sut->getPath(), "ReadingParameters"),
290 Eq(newParams));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100291}
292
Michal Orzel5e7cbf42024-08-01 15:44:42 +0200293TEST_F(TestReport, setReadingParametersFailsWhenMetricCountExceedsAllowedValue)
294{
295 std::vector<LabeledMetricParameters> readingParams{{LabeledMetricParameters{
296 {LabeledSensorInfo{"Service", "/xyz/openbmc_project/sensors/power/psu",
297 "NewMetadata123"}},
298 OperationType::avg,
299 CollectionTimeScope::startup,
300 CollectionDuration(250ms)}}};
301
302 auto& metricParamsVec =
303 readingParams[0].at_label<utils::tstring::SensorPath>();
304 for (size_t i = 0; i < ReportManager::maxNumberMetrics; i++)
305 {
306 metricParamsVec.emplace_back(LabeledSensorInfo{
307 "Service", "/xyz/openbmc_project/sensors/power/psu",
308 "NewMetadata123"});
309 }
310
311 ReadingParameters newParams = toReadingParameters(readingParams);
312
313 EXPECT_THAT(
314 setProperty(sut->getPath(), "ReadingParameters", newParams).value(),
315 Eq(boost::system::errc::invalid_argument));
316}
317
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100318TEST_F(TestReport, setReportActionsWithValidNewActions)
319{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000320 std::vector<std::string> newActions = {
321 utils::enumToString(ReportAction::emitsReadingsUpdate)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100322 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100323 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100324 [](const auto v) { return utils::enumToString(v); });
325
326 EXPECT_THAT(newActions, Ne(currActions));
327 EXPECT_THAT(
328 setProperty(sut->getPath(), "ReportActions", newActions).value(),
329 Eq(boost::system::errc::success));
330 EXPECT_THAT(
331 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000332 UnorderedElementsAre(
333 utils::enumToString(ReportAction::emitsReadingsUpdate),
334 utils::enumToString(ReportAction::logToMetricReportsCollection)));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100335}
336
337TEST_F(TestReport, setReportActionsWithValidUnsortedActions)
338{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000339 std::vector<std::string> newActions = {
340 utils::enumToString(ReportAction::logToMetricReportsCollection),
341 utils::enumToString(ReportAction::emitsReadingsUpdate)};
342 std::vector<std::string> expectedActions = {
343 utils::enumToString(ReportAction::emitsReadingsUpdate),
344 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100345 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100346 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100347 [](const auto v) { return utils::enumToString(v); });
348
349 EXPECT_THAT(newActions, Ne(currActions));
350 EXPECT_THAT(
351 setProperty(sut->getPath(), "ReportActions", newActions).value(),
352 Eq(boost::system::errc::success));
353 EXPECT_THAT(
354 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
355 Eq(expectedActions));
356}
357
358TEST_F(TestReport, setReportActionsWithEmptyActions)
359{
360 std::vector<std::string> newActions = {};
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000361 std::vector<std::string> expectedActions = {
362 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100363 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100364 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100365 [](const auto v) { return utils::enumToString(v); });
366
367 EXPECT_THAT(newActions, Ne(currActions));
368 EXPECT_THAT(
369 setProperty(sut->getPath(), "ReportActions", newActions).value(),
370 Eq(boost::system::errc::success));
371 EXPECT_THAT(
372 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
373 Eq(expectedActions));
374}
375
376TEST_F(TestReport, setReportActionsWithInvalidActions)
377{
378 std::vector<std::string> invalidActions = {"EmitsReadingsUpdate_1"};
379 EXPECT_THAT(
380 setProperty(sut->getPath(), "ReportActions", invalidActions).value(),
381 Eq(boost::system::errc::invalid_argument));
382 EXPECT_THAT(
383 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100384 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Patrick Williamsc7935fa2023-10-20 11:19:30 -0500385 return utils::enumToString(v);
386 })));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100387}
388
389TEST_F(TestReport, createReportWithEmptyActions)
390{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000391 std::vector<std::string> expectedActions = {
392 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100393
394 sut = makeReport(ReportParams().reportId("TestId_1").reportActions({}));
395 EXPECT_THAT(
396 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
397 Eq(expectedActions));
398}
399
400TEST_F(TestReport, createReportWithValidUnsortedActions)
401{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000402 std::vector<std::string> newActions = {
403 utils::enumToString(ReportAction::logToMetricReportsCollection),
404 utils::enumToString(ReportAction::emitsReadingsUpdate)};
405 std::vector<std::string> expectedActions = {
406 utils::enumToString(ReportAction::emitsReadingsUpdate),
407 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100408
409 sut = makeReport(
410 ReportParams()
411 .reportId("TestId_1")
412 .reportActions(utils::transform(newActions, [](const auto& action) {
Patrick Williamsc7935fa2023-10-20 11:19:30 -0500413 return utils::toReportAction(action);
414 })));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100415 EXPECT_THAT(
416 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
417 Eq(expectedActions));
418}
419
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200420TEST_F(TestReport, setEnabledWithNewValue)
421{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100422 bool newValue = !defaultParams().enabled();
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200423 EXPECT_THAT(setProperty(sut->getPath(), "Enabled", newValue).value(),
424 Eq(boost::system::errc::success));
425 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(newValue));
426}
427
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000428TEST_F(TestReport, setReportingPropertiesWithValidValues)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200429{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200430 uint64_t newValue = ReportManager::minInterval.count() * 42;
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000431 EXPECT_THAT(callMethod(sut->getPath(), "SetReportingProperties",
432 utils::enumToString(ReportingType::periodic),
433 newValue),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200434 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200435 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
436 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200437}
438
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000439TEST_F(TestReport, failsToSetInvalidInterval)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200440{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200441 uint64_t newValue = ReportManager::minInterval.count() - 1;
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000442
443 EXPECT_THAT(
444 callMethod(sut->getPath(), "SetReportingProperties", "", newValue),
445 Eq(boost::system::errc::invalid_argument));
446
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200447 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100448 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100449}
450
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000451TEST_F(TestReport, failsToSetIncompatibleInterval)
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200452{
453 auto report = makeReport(defaultParams()
454 .reportId("report2")
455 .reportingType(ReportingType::onRequest)
456 .interval(Milliseconds{0}));
457
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000458 uint64_t newValue = ReportManager::minInterval.count();
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200459
460 EXPECT_THAT(
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000461 callMethod(report->getPath(), "SetReportingProperties", "", newValue),
462 Eq(boost::system::errc::invalid_argument));
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200463
464 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000465 Eq(defaultParams().interval().count()));
466}
467
468TEST_F(TestReport, failsToSetInvalidReportingType)
469{
470 auto report = makeReport(defaultParams()
471 .reportId("report2")
472 .reportingType(ReportingType::onRequest)
473 .interval(Milliseconds{0}));
474
475 EXPECT_THAT(callMethod(sut->getPath(), "SetReportingProperties", "XYZ",
476 std::numeric_limits<uint64_t>::max()),
477 Eq(boost::system::errc::invalid_argument));
478
479 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
480 Eq(utils::enumToString(ReportingType::onRequest)));
481}
482
483TEST_F(TestReport, failsToSetIncompatibleReportingType)
484{
485 auto report = makeReport(defaultParams()
486 .reportId("report2")
487 .reportingType(ReportingType::onRequest)
488 .interval(Milliseconds{0}));
489
490 EXPECT_THAT(callMethod(sut->getPath(), "SetReportingProperties",
491 utils::enumToString(ReportingType::periodic),
492 std::numeric_limits<uint64_t>::max()),
493 Eq(boost::system::errc::invalid_argument));
494
495 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
496 Eq(utils::enumToString(ReportingType::onRequest)));
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200497}
498
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200499TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
500{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100501 EXPECT_THAT(
502 setProperty(sut->getPath(), "EmitsReadingsUpdate", true).value(),
503 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200504 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100505 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100506 ReportAction::emitsReadingsUpdate)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200507}
508
509TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
510{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100511 EXPECT_THAT(
512 setProperty(sut->getPath(), "LogToMetricReportsCollection", true)
513 .value(),
514 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200515 EXPECT_THAT(
516 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100517 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100518 ReportAction::logToMetricReportsCollection)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200519}
520
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100521TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
522{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100523 EXPECT_CALL(storageMock, store(_, _)).Times(0);
524 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
525 .Times(AtLeast(1));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100526
527 bool persistency = false;
528 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
529 Eq(boost::system::errc::success));
530 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
531 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200532}
533
534TEST_F(TestReport, deleteReport)
535{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200536 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
537 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200538 EXPECT_THAT(ec, Eq(boost::system::errc::success));
539}
540
541TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
542{
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200543 auto ec =
544 deleteReport(utils::constants::reportDirPath.str + "NonExisting"s);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200545 EXPECT_THAT(ec.value(), Eq(EBADR));
546}
547
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100548TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
549{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100550 EXPECT_CALL(storageMock, store(_, _)).Times(0);
551 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
552 .Times(AtLeast(1));
553
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100554 auto ec = deleteReport(sut->getPath());
555 EXPECT_THAT(ec, Eq(boost::system::errc::success));
556}
557
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100558TEST_F(TestReport, updatesTriggerIdWhenTriggerIsAdded)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100559{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100560 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100561
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100562 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100563 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100564 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100565 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100566 messanger.send(messages::TriggerPresenceChangedInd{
567 messages::Presence::Exist, "trigger2", {"someOtherReport"}});
568 messanger.send(messages::TriggerPresenceChangedInd{
569 messages::Presence::Exist,
570 "trigger3",
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100571 {"someOtherReport", defaultParams().reportId()}});
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100572
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100573 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200574 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
575 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
576 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100577}
578
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100579TEST_F(TestReport, updatesTriggerIdWhenTriggerIsRemoved)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100580{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100581 utils::Messanger messanger(DbusEnvironment::getIoc());
582
583 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100584 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100585 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100586 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100587 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100588 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100589
590 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100591 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100592 messanger.send(messages::TriggerPresenceChangedInd{
593 messages::Presence::Removed, "trigger2", {}});
594 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100595 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100596
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100597 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200598 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
599 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100600}
601
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100602TEST_F(TestReport, updatesTriggerIdWhenTriggerIsModified)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100603{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100604 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100605
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100606 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100607 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100608 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100609 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100610 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100611 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100612
613 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100614 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100615 messanger.send(messages::TriggerPresenceChangedInd{
616 messages::Presence::Exist, "trigger2", {}});
617 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100618 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100619
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100620 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200621 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
622 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
623 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100624}
625
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100626class TestReportStore :
627 public TestReport,
628 public WithParamInterface<std::pair<std::string, nlohmann::json>>
629{
Patrick Williams3a1c2972023-05-10 07:51:04 -0500630 void SetUp() override {}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100631};
632
633INSTANTIATE_TEST_SUITE_P(
634 _, TestReportStore,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100635 Values(
636 std::make_pair("Enabled"s, nlohmann::json(defaultParams().enabled())),
Krzysztof Grobelny18e71012022-11-02 13:17:01 +0000637 std::make_pair("Version"s, nlohmann::json(7)),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100638 std::make_pair("Id"s, nlohmann::json(defaultParams().reportId())),
639 std::make_pair("Name"s, nlohmann::json(defaultParams().reportName())),
640 std::make_pair("ReportingType",
641 nlohmann::json(defaultParams().reportingType())),
642 std::make_pair("ReportActions", nlohmann::json(utils::transform(
643 defaultParams().reportActions(),
644 [](const auto v) {
Patrick Williams3a1c2972023-05-10 07:51:04 -0500645 return utils::toUnderlying(v);
Patrick Williamsc7935fa2023-10-20 11:19:30 -0500646}))),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100647 std::make_pair("Interval",
648 nlohmann::json(defaultParams().interval().count())),
649 std::make_pair("AppendLimit",
650 nlohmann::json(ReportParams().appendLimit())),
651 std::make_pair(
652 "ReadingParameters",
653 nlohmann::json(
654 {{{tstring::SensorPath::str(),
655 {{{tstring::Service::str(), "Service"},
656 {tstring::Path::str(),
657 "/xyz/openbmc_project/sensors/power/p1"},
658 {tstring::Metadata::str(), "metadata1"}}}},
659 {tstring::OperationType::str(), OperationType::avg},
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100660 {tstring::CollectionTimeScope::str(),
661 CollectionTimeScope::point},
662 {tstring::CollectionDuration::str(), 0}},
663 {{tstring::SensorPath::str(),
664 {{{tstring::Service::str(), "Service"},
665 {tstring::Path::str(),
666 "/xyz/openbmc_project/sensors/power/p2"},
667 {tstring::Metadata::str(), "metadata2"}}}},
668 {tstring::OperationType::str(), OperationType::avg},
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100669 {tstring::CollectionTimeScope::str(),
670 CollectionTimeScope::point},
671 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100672
673TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
674{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100675 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100676
677 {
678 InSequence seq;
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100679 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100680 EXPECT_CALL(checkPoint, Call());
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100681 EXPECT_CALL(storageMock, store(to_file_path(sut->getId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100682 }
683
684 setProperty(sut->getPath(), "Persistency", false);
685 checkPoint.Call();
686 setProperty(sut->getPath(), "Persistency", true);
687
688 const auto& [key, value] = GetParam();
689
690 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
691}
692
693TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
694{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100695 EXPECT_CALL(storageMock,
696 store(to_file_path(defaultParams().reportId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100697
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100698 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100699
700 const auto& [key, value] = GetParam();
701
702 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
703}
704
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200705class TestReportValidNames :
706 public TestReport,
707 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200708{
709 public:
Patrick Williams3a1c2972023-05-10 07:51:04 -0500710 void SetUp() override {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200711};
712
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200713INSTANTIATE_TEST_SUITE_P(
714 ValidNames, TestReportValidNames,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100715 Values(defaultParams().reportName("Valid_1"),
716 defaultParams().reportName("Valid_1/Valid_2"),
717 defaultParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200718
719TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
720{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200721 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200722}
723
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100724class TestReportInvalidIds :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200725 public TestReport,
726 public WithParamInterface<ReportParams>
727{
728 public:
Patrick Williams3a1c2972023-05-10 07:51:04 -0500729 void SetUp() override {}
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200730};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200731
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100732INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidIds,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100733 Values(defaultParams().reportId("/"),
734 defaultParams().reportId("/Invalid"),
735 defaultParams().reportId("Invalid/"),
736 defaultParams().reportId("Invalid/Invalid/"),
737 defaultParams().reportId("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200738
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100739TEST_P(TestReportInvalidIds, failsToCreateReportWithInvalidName)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100740{
741 EXPECT_CALL(storageMock, store).Times(0);
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100742
743 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100744}
745
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200746class TestReportAllReportTypes :
747 public TestReport,
748 public WithParamInterface<ReportParams>
749{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200750 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200751 void SetUp() override
752 {
753 sut = makeReport(GetParam());
754 }
755};
756
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100757INSTANTIATE_TEST_SUITE_P(
758 _, TestReportAllReportTypes,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100759 Values(defaultParams().reportingType(ReportingType::onRequest),
760 defaultParams().reportingType(ReportingType::onChange),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200761 defaultParams()
762 .reportingType(ReportingType::periodic)
763 .interval(ReportManager::minInterval)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200764
765TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
766{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100767 EXPECT_THAT(utils::toReportingType(
768 getProperty<std::string>(sut->getPath(), "ReportingType")),
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200769 Eq(GetParam().reportingType()));
770}
771
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100772TEST_P(TestReportAllReportTypes, readingsAreUpdated)
773{
774 clockFake.system.advance(10ms);
775
776 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Patrick Williams3a1c2972023-05-10 07:51:04 -0500777 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
778 "Readings");
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100779
780 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
781}
782
783TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIsDisabled)
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200784{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100785 clockFake.system.advance(10ms);
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200786
787 setProperty(sut->getPath(), "Enabled", false);
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100788 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Patrick Williams3a1c2972023-05-10 07:51:04 -0500789 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
790 "Readings");
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200791
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100792 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200793}
794
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100795TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIdDiffers)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100796{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100797 clockFake.system.advance(10ms);
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100798
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100799 messanger.send(messages::UpdateReportInd{{sut->getId() + "x"s}});
Patrick Williams3a1c2972023-05-10 07:51:04 -0500800 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
801 "Readings");
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100802
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100803 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100804}
805
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100806class TestReportOnRequestType : public TestReport
807{
808 void SetUp() override
809 {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100810 sut =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100811 makeReport(defaultParams().reportingType(ReportingType::onRequest));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100812 }
813};
814
815TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
816{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100817 clockFake.system.advance(10ms);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100818
819 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
820
Patrick Williams3a1c2972023-05-10 07:51:04 -0500821 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
822 "Readings");
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100823
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100824 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100825}
826
827TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
828{
829 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
830
Patrick Williams3a1c2972023-05-10 07:51:04 -0500831 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
832 "Readings");
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100833
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000834 EXPECT_THAT(readings, ElementsAre(std::make_tuple("b"s, 17.1, 114u),
835 std::make_tuple("bb"s, 42.0, 74u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100836}
837
838class TestReportNonOnRequestType :
839 public TestReport,
840 public WithParamInterface<ReportParams>
841{
842 void SetUp() override
843 {
844 sut = makeReport(GetParam());
845 }
846};
847
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000848INSTANTIATE_TEST_SUITE_P(_, TestReportNonOnRequestType,
849 Values(defaultParams()
850 .reportingType(ReportingType::periodic)
851 .interval(ReportManager::minInterval * 10),
852 defaultParams()
853 .reportingType(ReportingType::onChange)
854 .interval(Milliseconds(0))));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100855
856TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
857{
858 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
859
860 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
861 Eq(Readings{}));
862}
863
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200864class TestReportNonPeriodicReport :
865 public TestReport,
866 public WithParamInterface<ReportParams>
867{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200868 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200869 void SetUp() override
870 {
871 sut = makeReport(GetParam());
872 }
873};
874
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100875INSTANTIATE_TEST_SUITE_P(
876 _, TestReportNonPeriodicReport,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100877 Values(defaultParams().reportingType(ReportingType::onRequest),
878 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200879
880TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
881{
882 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
883
884 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
885 Eq(Readings{}));
886}
887
888class TestReportPeriodicReport : public TestReport
889{
890 void SetUp() override
891 {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200892 sut = makeReport(defaultParams()
Krzysztof Grobelny18e71012022-11-02 13:17:01 +0000893 .appendLimit(2u)
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200894 .reportingType(ReportingType::periodic)
895 .interval(ReportManager::minInterval));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200896 }
897};
898
899TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
900{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100901 clockFake.system.advance(10ms);
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200902 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
903
Patrick Williams3a1c2972023-05-10 07:51:04 -0500904 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
905 "Readings");
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200906
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100907 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200908}
909
910TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
911{
912 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
913
Patrick Williams3a1c2972023-05-10 07:51:04 -0500914 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
915 "Readings");
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200916
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000917 EXPECT_THAT(readings, ElementsAre(std::make_tuple("b"s, 17.1, 114u),
918 std::make_tuple("bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200919}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100920
Szymon Dompke3eb56862021-09-20 15:32:04 +0200921struct ReportUpdatesReportParams
922{
923 ReportParams reportParams;
924 std::vector<ReadingData> expectedReadings;
925 bool expectedEnabled;
Michal Orzelb3e03d22024-06-28 13:55:47 +0200926
927 friend void PrintTo(const ReportUpdatesReportParams& params,
928 std::ostream* os)
929 {
930 *os << "{ ReportParams: ";
931 PrintTo(params.reportParams, os);
932 *os << ", ExpectedReadings: ";
933 PrintTo(params.expectedReadings, os);
934 *os << ", ExpectedEnabled: " << params.expectedEnabled << " }";
935 }
Szymon Dompke3eb56862021-09-20 15:32:04 +0200936};
937
938class TestReportWithReportUpdatesAndLimit :
939 public TestReport,
940 public WithParamInterface<ReportUpdatesReportParams>
941{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200942 public:
Patrick Williams3a1c2972023-05-10 07:51:04 -0500943 void SetUp() override {}
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200944
945 void changeReport(ReportingType rt, Milliseconds interval)
Szymon Dompke3eb56862021-09-20 15:32:04 +0200946 {
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000947 callMethod(sut->getPath(), "SetReportingProperties",
948 utils::enumToString(rt), interval.count());
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200949 }
950
951 auto readings()
952 {
Patrick Williams3a1c2972023-05-10 07:51:04 -0500953 auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
954 "Readings");
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200955 return readings;
956 }
957
958 void updateReportFourTimes()
959 {
960 for (int i = 0; i < 4; i++)
961 {
962 messanger.send(messages::UpdateReportInd{{sut->getId()}});
963 }
Szymon Dompke3eb56862021-09-20 15:32:04 +0200964 }
965};
966
967INSTANTIATE_TEST_SUITE_P(
968 _, TestReportWithReportUpdatesAndLimit,
969 Values(
970 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100971 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100972 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
973 .appendLimit(5),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000974 std::vector<ReadingData>{{std::make_tuple("bb"s, 42.0, 74u),
975 std::make_tuple("b"s, 17.1, 114u),
976 std::make_tuple("bb"s, 42.0, 74u),
977 std::make_tuple("bb"s, 42.0, 74u),
978 std::make_tuple("b"s, 17.1, 114u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +0200979 true},
980 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100981 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100982 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
983 .appendLimit(4),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000984 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
985 std::make_tuple("bb"s, 42.0, 74u),
986 std::make_tuple("b"s, 17.1, 114u),
987 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +0200988 true},
989 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100990 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100991 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
992 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200993 std::vector<ReadingData>{}, true},
994 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100995 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100996 .reportUpdates(ReportUpdates::appendStopsWhenFull)
997 .appendLimit(10),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000998 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
999 std::make_tuple("bb"s, 42.0, 74u),
1000 std::make_tuple("b"s, 17.1, 114u),
1001 std::make_tuple("bb"s, 42.0, 74u),
1002 std::make_tuple("b"s, 17.1, 114u),
1003 std::make_tuple("bb"s, 42.0, 74u),
1004 std::make_tuple("b"s, 17.1, 114u),
1005 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001006 true},
1007 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001008 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001009 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1010 .appendLimit(5),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001011 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1012 std::make_tuple("bb"s, 42.0, 74u),
1013 std::make_tuple("b"s, 17.1, 114u),
1014 std::make_tuple("bb"s, 42.0, 74u),
1015 std::make_tuple("b"s, 17.1, 114u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001016 false},
1017 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001018 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001019 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1020 .appendLimit(4),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001021 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1022 std::make_tuple("bb"s, 42.0, 74u),
1023 std::make_tuple("b"s, 17.1, 114u),
1024 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001025 false},
1026 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001027 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001028 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1029 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +02001030 std::vector<ReadingData>{}, false},
1031 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001032 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001033 .reportUpdates(ReportUpdates::overwrite)
1034 .appendLimit(500),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001035 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1036 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001037 true},
1038 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001039 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001040 .reportUpdates(ReportUpdates::overwrite)
1041 .appendLimit(1),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001042 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1043 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001044 true},
1045 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001046 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001047 .reportUpdates(ReportUpdates::overwrite)
1048 .appendLimit(0),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001049 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1050 std::make_tuple("bb"s, 42.0, 74u)}},
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001051 true},
1052 ReportUpdatesReportParams{
1053 defaultParams()
1054 .reportUpdates(ReportUpdates::appendStopsWhenFull)
Krzysztof Grobelny18e71012022-11-02 13:17:01 +00001055 .appendLimit(2u),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001056 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1057 std::make_tuple("bb"s, 42.0, 74u)}},
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001058 false}));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001059
1060TEST_P(TestReportWithReportUpdatesAndLimit,
1061 readingsAreUpdatedAfterIntervalExpires)
1062{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001063 sut = makeReport(ReportParams(GetParam().reportParams)
1064 .reportingType(ReportingType::periodic)
1065 .interval(std::chrono::hours(1000)));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001066
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001067 updateReportFourTimes();
Szymon Dompke3eb56862021-09-20 15:32:04 +02001068
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001069 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1070 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1071 Eq(GetParam().expectedEnabled));
1072}
1073
1074TEST_P(TestReportWithReportUpdatesAndLimit,
1075 appendLimitIsRespectedAfterChangingToPeriodic)
1076{
1077 sut = makeReport(ReportParams(GetParam().reportParams)
Krzysztof Grobelny18e71012022-11-02 13:17:01 +00001078 .appendLimit(GetParam().expectedReadings.size())
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001079 .reportingType(ReportingType::onRequest)
1080 .interval(std::chrono::hours(0)));
1081
1082 changeReport(ReportingType::periodic, std::chrono::hours(1000));
1083 updateReportFourTimes();
1084
1085 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1086 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1087 Eq(GetParam().expectedEnabled));
1088}
1089
1090TEST_P(TestReportWithReportUpdatesAndLimit,
1091 appendLimitIsIgnoredAfterChangingToOnRequest)
1092{
1093 sut = makeReport(ReportParams(GetParam().reportParams)
1094 .reportingType(ReportingType::periodic)
1095 .interval(std::chrono::hours(1000)));
1096
1097 changeReport(ReportingType::onRequest, Milliseconds{0});
1098 updateReportFourTimes();
1099
1100 EXPECT_THAT(readings(), SizeIs(2u));
1101 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(true));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001102}
1103
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001104class TestReportInitialization : public TestReport
1105{
1106 public:
1107 void SetUp() override
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001108 {
1109 initMetricMocks(defaultParams().metricParameters());
1110 }
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001111
Patrick Williams39cc6ac2022-07-22 19:26:56 -05001112 void monitorProc(sdbusplus::message_t& msg)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001113 {
1114 std::string iface;
1115 std::vector<std::pair<std::string, std::variant<Readings>>>
1116 changed_properties;
1117 std::vector<std::string> invalidated_properties;
1118
1119 msg.read(iface, changed_properties, invalidated_properties);
1120
1121 if (iface == Report::reportIfaceName)
1122 {
1123 for (const auto& [name, value] : changed_properties)
1124 {
1125 if (name == "Readings")
1126 {
1127 readingsUpdated.Call();
1128 }
1129 }
1130 }
1131 }
1132
1133 void makeMonitor()
1134 {
Patrick Williams3a62ee12021-12-03 10:13:25 -06001135 monitor = std::make_unique<sdbusplus::bus::match_t>(
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001136 *DbusEnvironment::getBus(),
1137 sdbusplus::bus::match::rules::propertiesChanged(
1138 sut->getPath(), Report::reportIfaceName),
1139 [this](auto& msg) { monitorProc(msg); });
1140 }
1141
Patrick Williams3a62ee12021-12-03 10:13:25 -06001142 std::unique_ptr<sdbusplus::bus::match_t> monitor;
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001143 MockFunction<void()> readingsUpdated;
1144};
1145
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001146TEST_F(TestReportInitialization,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001147 registersForMetricUpdatesWhenOnChangeReportCreated)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001148{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001149 std::vector<const interfaces::MetricListener*> args;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001150 for (auto& metric : metricMocks)
1151 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001152 EXPECT_CALL(*metric, registerForUpdates(_))
1153 .WillOnce(Invoke([&args](const interfaces::MetricListener& report) {
Patrick Williamsc7935fa2023-10-20 11:19:30 -05001154 args.emplace_back(&report);
1155 }));
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001156 ;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001157 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001158
1159 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1160
1161 EXPECT_THAT(args, SizeIs(metricMocks.size()));
1162 for (const auto* reportPtr : args)
1163 {
1164 EXPECT_THAT(reportPtr, Eq(sut.get()));
1165 }
1166}
1167
1168TEST_F(TestReportInitialization,
1169 deregistersForMetricUpdatesWhenOnChangeReportDestroyed)
1170{
1171 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1172
1173 for (auto& metric : metricMocks)
1174 {
1175 EXPECT_CALL(*metric,
1176 unregisterFromUpdates(Ref(
1177 static_cast<interfaces::MetricListener&>(*sut.get()))));
1178 }
1179
1180 sut = nullptr;
1181}
1182
1183TEST_F(TestReportInitialization,
1184 metricsAreInitializedWhenEnabledReportConstructed)
1185{
1186 for (auto& metric : metricMocks)
1187 {
1188 EXPECT_CALL(*metric, initialize());
1189 }
1190 sut = makeReport(defaultParams().enabled(true));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001191}
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001192
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001193TEST_F(TestReportInitialization,
1194 metricsAreNotInitializedWhenDisabledReportConstructed)
1195{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001196 for (auto& metric : metricMocks)
1197 {
1198 EXPECT_CALL(*metric, initialize()).Times(0);
1199 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001200 sut = makeReport(defaultParams().enabled(false));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001201}
1202
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001203TEST_F(TestReportInitialization,
1204 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001205{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001206 EXPECT_CALL(readingsUpdated, Call())
1207 .WillOnce(
1208 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
1209
1210 const auto elapsed = DbusEnvironment::measureTime([this] {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001211 sut = makeReport(defaultParams()
1212 .reportingType(ReportingType::periodic)
1213 .reportActions({ReportAction::emitsReadingsUpdate})
1214 .interval(ReportManager::minInterval));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001215 makeMonitor();
1216 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
1217 });
1218
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001219 EXPECT_THAT(elapsed, AllOf(Ge(ReportManager::minInterval),
1220 Lt(ReportManager::minInterval * 2)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001221}
1222
1223TEST_F(TestReportInitialization,
1224 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
1225{
1226 EXPECT_CALL(readingsUpdated, Call()).Times(0);
1227
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001228 sut = makeReport(defaultParams()
1229 .reportingType(ReportingType::periodic)
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001230 .reportActions({})
1231 .interval(Milliseconds(1000)));
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001232 makeMonitor();
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001233 DbusEnvironment::sleepFor(defaultParams().interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001234}
Szymon Dompke3eb56862021-09-20 15:32:04 +02001235
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001236TEST_F(TestReportInitialization, triggerIdsPropertyIsInitialzed)
1237{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001238 for (const auto& triggerId : {"trigger1", "trigger2"})
1239 {
1240 messanger.on_receive<messages::CollectTriggerIdReq>(
Szymon Dompkee0ed5082022-05-20 10:54:25 +02001241 [this, triggerId](const auto& msg) {
Patrick Williams3a1c2972023-05-10 07:51:04 -05001242 messanger.send(messages::CollectTriggerIdResp{triggerId});
1243 });
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001244 }
1245
1246 sut = makeReport(ReportParams());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001247
1248 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +02001249 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
1250 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
1251 utils::constants::triggerDirPath / "trigger2"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001252}
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001253
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +01001254TEST_F(TestReportInitialization,
1255 metricValuesAreNotStoredForReportUpdatesDifferentThanAppendStopsWhenFull)
1256{
1257 sut = makeReport(ReportParams()
1258 .reportingType(ReportingType::periodic)
1259 .interval(1h)
1260 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1261 .readings(Readings{{}, {{}}}));
1262
1263 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1264 Eq(storedConfiguration.end()));
1265}
1266
1267TEST_F(TestReportInitialization, metricValuesAreNotStoredForOnRequestReport)
1268{
1269 sut = makeReport(ReportParams()
1270 .reportingType(ReportingType::onRequest)
1271 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1272 .readings(Readings{{}, {{}}}));
1273
1274 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1275 Eq(storedConfiguration.end()));
1276}
1277
1278TEST_F(TestReportInitialization,
1279 metricValuesAreStoredForNonOnRequestReportWithAppendStopsWhenFull)
1280{
1281 const auto readings = Readings{{}, {{}}};
1282
1283 sut = makeReport(ReportParams()
1284 .reportingType(ReportingType::periodic)
1285 .interval(1h)
1286 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1287 .readings(readings));
1288
1289 ASSERT_THAT(storedConfiguration.at("MetricValues").get<LabeledReadings>(),
1290 Eq(utils::toLabeledReadings(readings)));
1291}
1292
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001293class TestReportInitializationOnChangeReport : public TestReportInitialization
1294{
1295 public:
1296 void SetUp() override
1297 {
1298 initMetricMocks(params.metricParameters());
1299 }
1300
1301 ReportParams params = defaultOnChangeParams();
1302};
1303
1304TEST_F(TestReportInitializationOnChangeReport,
1305 doesntUpdateReadingsWhenNotRequired)
1306{
1307 EXPECT_CALL(*metricMocks[0], updateReadings(_)).Times(0);
1308
1309 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(false));
1310
1311 sut = makeReport(params);
1312
1313 DbusEnvironment::sleepFor(500ms);
1314}
1315
1316TEST_F(TestReportInitializationOnChangeReport, updatesReadingsWhenRequired)
1317{
1318 EXPECT_CALL(*metricMocks[0], updateReadings(_))
1319 .WillOnce(Return())
1320 .WillOnce(
1321 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")))
1322 .WillRepeatedly(Return());
1323
1324 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(true));
1325
1326 sut = makeReport(params);
1327
1328 DbusEnvironment::waitForFuture("readingsUpdated");
1329}