blob: 31d49c5f8f8bc5ff9fc2fe3f0d99d61a938a705a [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
293TEST_F(TestReport, setReportActionsWithValidNewActions)
294{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000295 std::vector<std::string> newActions = {
296 utils::enumToString(ReportAction::emitsReadingsUpdate)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100297 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100298 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100299 [](const auto v) { return utils::enumToString(v); });
300
301 EXPECT_THAT(newActions, Ne(currActions));
302 EXPECT_THAT(
303 setProperty(sut->getPath(), "ReportActions", newActions).value(),
304 Eq(boost::system::errc::success));
305 EXPECT_THAT(
306 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000307 UnorderedElementsAre(
308 utils::enumToString(ReportAction::emitsReadingsUpdate),
309 utils::enumToString(ReportAction::logToMetricReportsCollection)));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100310}
311
312TEST_F(TestReport, setReportActionsWithValidUnsortedActions)
313{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000314 std::vector<std::string> newActions = {
315 utils::enumToString(ReportAction::logToMetricReportsCollection),
316 utils::enumToString(ReportAction::emitsReadingsUpdate)};
317 std::vector<std::string> expectedActions = {
318 utils::enumToString(ReportAction::emitsReadingsUpdate),
319 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100320 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100321 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100322 [](const auto v) { return utils::enumToString(v); });
323
324 EXPECT_THAT(newActions, Ne(currActions));
325 EXPECT_THAT(
326 setProperty(sut->getPath(), "ReportActions", newActions).value(),
327 Eq(boost::system::errc::success));
328 EXPECT_THAT(
329 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
330 Eq(expectedActions));
331}
332
333TEST_F(TestReport, setReportActionsWithEmptyActions)
334{
335 std::vector<std::string> newActions = {};
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000336 std::vector<std::string> expectedActions = {
337 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100338 std::vector<std::string> currActions =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100339 utils::transform(defaultParams().reportActions(),
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100340 [](const auto v) { return utils::enumToString(v); });
341
342 EXPECT_THAT(newActions, Ne(currActions));
343 EXPECT_THAT(
344 setProperty(sut->getPath(), "ReportActions", newActions).value(),
345 Eq(boost::system::errc::success));
346 EXPECT_THAT(
347 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
348 Eq(expectedActions));
349}
350
351TEST_F(TestReport, setReportActionsWithInvalidActions)
352{
353 std::vector<std::string> invalidActions = {"EmitsReadingsUpdate_1"};
354 EXPECT_THAT(
355 setProperty(sut->getPath(), "ReportActions", invalidActions).value(),
356 Eq(boost::system::errc::invalid_argument));
357 EXPECT_THAT(
358 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100359 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) {
Patrick Williamsc7935fa2023-10-20 11:19:30 -0500360 return utils::enumToString(v);
361 })));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100362}
363
364TEST_F(TestReport, createReportWithEmptyActions)
365{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000366 std::vector<std::string> expectedActions = {
367 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100368
369 sut = makeReport(ReportParams().reportId("TestId_1").reportActions({}));
370 EXPECT_THAT(
371 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
372 Eq(expectedActions));
373}
374
375TEST_F(TestReport, createReportWithValidUnsortedActions)
376{
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000377 std::vector<std::string> newActions = {
378 utils::enumToString(ReportAction::logToMetricReportsCollection),
379 utils::enumToString(ReportAction::emitsReadingsUpdate)};
380 std::vector<std::string> expectedActions = {
381 utils::enumToString(ReportAction::emitsReadingsUpdate),
382 utils::enumToString(ReportAction::logToMetricReportsCollection)};
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100383
384 sut = makeReport(
385 ReportParams()
386 .reportId("TestId_1")
387 .reportActions(utils::transform(newActions, [](const auto& action) {
Patrick Williamsc7935fa2023-10-20 11:19:30 -0500388 return utils::toReportAction(action);
389 })));
Szymon Dompkefdb06a12022-02-11 11:04:44 +0100390 EXPECT_THAT(
391 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
392 Eq(expectedActions));
393}
394
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200395TEST_F(TestReport, setEnabledWithNewValue)
396{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100397 bool newValue = !defaultParams().enabled();
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200398 EXPECT_THAT(setProperty(sut->getPath(), "Enabled", newValue).value(),
399 Eq(boost::system::errc::success));
400 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(newValue));
401}
402
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000403TEST_F(TestReport, setReportingPropertiesWithValidValues)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200404{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200405 uint64_t newValue = ReportManager::minInterval.count() * 42;
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000406 EXPECT_THAT(callMethod(sut->getPath(), "SetReportingProperties",
407 utils::enumToString(ReportingType::periodic),
408 newValue),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200409 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200410 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
411 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200412}
413
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000414TEST_F(TestReport, failsToSetInvalidInterval)
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200415{
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200416 uint64_t newValue = ReportManager::minInterval.count() - 1;
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000417
418 EXPECT_THAT(
419 callMethod(sut->getPath(), "SetReportingProperties", "", newValue),
420 Eq(boost::system::errc::invalid_argument));
421
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200422 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100423 Eq(defaultParams().interval().count()));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100424}
425
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000426TEST_F(TestReport, failsToSetIncompatibleInterval)
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200427{
428 auto report = makeReport(defaultParams()
429 .reportId("report2")
430 .reportingType(ReportingType::onRequest)
431 .interval(Milliseconds{0}));
432
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000433 uint64_t newValue = ReportManager::minInterval.count();
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200434
435 EXPECT_THAT(
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000436 callMethod(report->getPath(), "SetReportingProperties", "", newValue),
437 Eq(boost::system::errc::invalid_argument));
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200438
439 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000440 Eq(defaultParams().interval().count()));
441}
442
443TEST_F(TestReport, failsToSetInvalidReportingType)
444{
445 auto report = makeReport(defaultParams()
446 .reportId("report2")
447 .reportingType(ReportingType::onRequest)
448 .interval(Milliseconds{0}));
449
450 EXPECT_THAT(callMethod(sut->getPath(), "SetReportingProperties", "XYZ",
451 std::numeric_limits<uint64_t>::max()),
452 Eq(boost::system::errc::invalid_argument));
453
454 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
455 Eq(utils::enumToString(ReportingType::onRequest)));
456}
457
458TEST_F(TestReport, failsToSetIncompatibleReportingType)
459{
460 auto report = makeReport(defaultParams()
461 .reportId("report2")
462 .reportingType(ReportingType::onRequest)
463 .interval(Milliseconds{0}));
464
465 EXPECT_THAT(callMethod(sut->getPath(), "SetReportingProperties",
466 utils::enumToString(ReportingType::periodic),
467 std::numeric_limits<uint64_t>::max()),
468 Eq(boost::system::errc::invalid_argument));
469
470 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"),
471 Eq(utils::enumToString(ReportingType::onRequest)));
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200472}
473
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200474TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
475{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100476 EXPECT_THAT(
477 setProperty(sut->getPath(), "EmitsReadingsUpdate", true).value(),
478 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200479 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100480 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100481 ReportAction::emitsReadingsUpdate)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200482}
483
484TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
485{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100486 EXPECT_THAT(
487 setProperty(sut->getPath(), "LogToMetricReportsCollection", true)
488 .value(),
489 Eq(boost::system::errc::read_only_file_system));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200490 EXPECT_THAT(
491 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100492 Eq(utils::contains(defaultParams().reportActions(),
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100493 ReportAction::logToMetricReportsCollection)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200494}
495
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100496TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
497{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100498 EXPECT_CALL(storageMock, store(_, _)).Times(0);
499 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
500 .Times(AtLeast(1));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100501
502 bool persistency = false;
503 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
504 Eq(boost::system::errc::success));
505 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
506 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200507}
508
509TEST_F(TestReport, deleteReport)
510{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200511 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
512 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200513 EXPECT_THAT(ec, Eq(boost::system::errc::success));
514}
515
516TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
517{
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200518 auto ec =
519 deleteReport(utils::constants::reportDirPath.str + "NonExisting"s);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200520 EXPECT_THAT(ec.value(), Eq(EBADR));
521}
522
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100523TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
524{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100525 EXPECT_CALL(storageMock, store(_, _)).Times(0);
526 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())))
527 .Times(AtLeast(1));
528
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100529 auto ec = deleteReport(sut->getPath());
530 EXPECT_THAT(ec, Eq(boost::system::errc::success));
531}
532
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100533TEST_F(TestReport, updatesTriggerIdWhenTriggerIsAdded)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100534{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100535 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100536
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100537 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100538 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100539 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100540 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100541 messanger.send(messages::TriggerPresenceChangedInd{
542 messages::Presence::Exist, "trigger2", {"someOtherReport"}});
543 messanger.send(messages::TriggerPresenceChangedInd{
544 messages::Presence::Exist,
545 "trigger3",
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100546 {"someOtherReport", defaultParams().reportId()}});
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100547
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100548 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200549 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
550 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
551 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100552}
553
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100554TEST_F(TestReport, updatesTriggerIdWhenTriggerIsRemoved)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100555{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100556 utils::Messanger messanger(DbusEnvironment::getIoc());
557
558 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100559 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100560 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100561 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100562 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100563 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100564
565 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100566 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100567 messanger.send(messages::TriggerPresenceChangedInd{
568 messages::Presence::Removed, "trigger2", {}});
569 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100570 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +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 / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100575}
576
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100577TEST_F(TestReport, updatesTriggerIdWhenTriggerIsModified)
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100578{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100579 utils::Messanger messanger(DbusEnvironment::getIoc());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100580
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100581 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100582 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100583 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100584 messages::Presence::Exist, "trigger2", {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, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100587
588 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100589 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100590 messanger.send(messages::TriggerPresenceChangedInd{
591 messages::Presence::Exist, "trigger2", {}});
592 messanger.send(messages::TriggerPresenceChangedInd{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100593 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100594
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100595 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200596 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
597 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
598 utils::constants::triggerDirPath / "trigger3"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100599}
600
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100601class TestReportStore :
602 public TestReport,
603 public WithParamInterface<std::pair<std::string, nlohmann::json>>
604{
Patrick Williams3a1c2972023-05-10 07:51:04 -0500605 void SetUp() override {}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100606};
607
608INSTANTIATE_TEST_SUITE_P(
609 _, TestReportStore,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100610 Values(
611 std::make_pair("Enabled"s, nlohmann::json(defaultParams().enabled())),
Krzysztof Grobelny18e71012022-11-02 13:17:01 +0000612 std::make_pair("Version"s, nlohmann::json(7)),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100613 std::make_pair("Id"s, nlohmann::json(defaultParams().reportId())),
614 std::make_pair("Name"s, nlohmann::json(defaultParams().reportName())),
615 std::make_pair("ReportingType",
616 nlohmann::json(defaultParams().reportingType())),
617 std::make_pair("ReportActions", nlohmann::json(utils::transform(
618 defaultParams().reportActions(),
619 [](const auto v) {
Patrick Williams3a1c2972023-05-10 07:51:04 -0500620 return utils::toUnderlying(v);
Patrick Williamsc7935fa2023-10-20 11:19:30 -0500621}))),
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100622 std::make_pair("Interval",
623 nlohmann::json(defaultParams().interval().count())),
624 std::make_pair("AppendLimit",
625 nlohmann::json(ReportParams().appendLimit())),
626 std::make_pair(
627 "ReadingParameters",
628 nlohmann::json(
629 {{{tstring::SensorPath::str(),
630 {{{tstring::Service::str(), "Service"},
631 {tstring::Path::str(),
632 "/xyz/openbmc_project/sensors/power/p1"},
633 {tstring::Metadata::str(), "metadata1"}}}},
634 {tstring::OperationType::str(), OperationType::avg},
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100635 {tstring::CollectionTimeScope::str(),
636 CollectionTimeScope::point},
637 {tstring::CollectionDuration::str(), 0}},
638 {{tstring::SensorPath::str(),
639 {{{tstring::Service::str(), "Service"},
640 {tstring::Path::str(),
641 "/xyz/openbmc_project/sensors/power/p2"},
642 {tstring::Metadata::str(), "metadata2"}}}},
643 {tstring::OperationType::str(), OperationType::avg},
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100644 {tstring::CollectionTimeScope::str(),
645 CollectionTimeScope::point},
646 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100647
648TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
649{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100650 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100651
652 {
653 InSequence seq;
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100654 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100655 EXPECT_CALL(checkPoint, Call());
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100656 EXPECT_CALL(storageMock, store(to_file_path(sut->getId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100657 }
658
659 setProperty(sut->getPath(), "Persistency", false);
660 checkPoint.Call();
661 setProperty(sut->getPath(), "Persistency", true);
662
663 const auto& [key, value] = GetParam();
664
665 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
666}
667
668TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
669{
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +0100670 EXPECT_CALL(storageMock,
671 store(to_file_path(defaultParams().reportId()), _));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100672
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100673 sut = makeReport(defaultParams());
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100674
675 const auto& [key, value] = GetParam();
676
677 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
678}
679
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200680class TestReportValidNames :
681 public TestReport,
682 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200683{
684 public:
Patrick Williams3a1c2972023-05-10 07:51:04 -0500685 void SetUp() override {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200686};
687
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200688INSTANTIATE_TEST_SUITE_P(
689 ValidNames, TestReportValidNames,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100690 Values(defaultParams().reportName("Valid_1"),
691 defaultParams().reportName("Valid_1/Valid_2"),
692 defaultParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200693
694TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
695{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200696 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200697}
698
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100699class TestReportInvalidIds :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200700 public TestReport,
701 public WithParamInterface<ReportParams>
702{
703 public:
Patrick Williams3a1c2972023-05-10 07:51:04 -0500704 void SetUp() override {}
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200705};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200706
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100707INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidIds,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100708 Values(defaultParams().reportId("/"),
709 defaultParams().reportId("/Invalid"),
710 defaultParams().reportId("Invalid/"),
711 defaultParams().reportId("Invalid/Invalid/"),
712 defaultParams().reportId("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200713
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100714TEST_P(TestReportInvalidIds, failsToCreateReportWithInvalidName)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100715{
716 EXPECT_CALL(storageMock, store).Times(0);
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100717
718 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100719}
720
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200721class TestReportAllReportTypes :
722 public TestReport,
723 public WithParamInterface<ReportParams>
724{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200725 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200726 void SetUp() override
727 {
728 sut = makeReport(GetParam());
729 }
730};
731
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100732INSTANTIATE_TEST_SUITE_P(
733 _, TestReportAllReportTypes,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100734 Values(defaultParams().reportingType(ReportingType::onRequest),
735 defaultParams().reportingType(ReportingType::onChange),
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200736 defaultParams()
737 .reportingType(ReportingType::periodic)
738 .interval(ReportManager::minInterval)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200739
740TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
741{
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100742 EXPECT_THAT(utils::toReportingType(
743 getProperty<std::string>(sut->getPath(), "ReportingType")),
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200744 Eq(GetParam().reportingType()));
745}
746
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100747TEST_P(TestReportAllReportTypes, readingsAreUpdated)
748{
749 clockFake.system.advance(10ms);
750
751 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Patrick Williams3a1c2972023-05-10 07:51:04 -0500752 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
753 "Readings");
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100754
755 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
756}
757
758TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIsDisabled)
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200759{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100760 clockFake.system.advance(10ms);
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200761
762 setProperty(sut->getPath(), "Enabled", false);
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100763 messanger.send(messages::UpdateReportInd{{sut->getId()}});
Patrick Williams3a1c2972023-05-10 07:51:04 -0500764 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
765 "Readings");
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200766
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100767 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200768}
769
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100770TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIdDiffers)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100771{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100772 clockFake.system.advance(10ms);
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100773
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100774 messanger.send(messages::UpdateReportInd{{sut->getId() + "x"s}});
Patrick Williams3a1c2972023-05-10 07:51:04 -0500775 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
776 "Readings");
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100777
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100778 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100779}
780
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100781class TestReportOnRequestType : public TestReport
782{
783 void SetUp() override
784 {
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100785 sut =
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100786 makeReport(defaultParams().reportingType(ReportingType::onRequest));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100787 }
788};
789
790TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
791{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100792 clockFake.system.advance(10ms);
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100793
794 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
795
Patrick Williams3a1c2972023-05-10 07:51:04 -0500796 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
797 "Readings");
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100798
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100799 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100800}
801
802TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
803{
804 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
805
Patrick Williams3a1c2972023-05-10 07:51:04 -0500806 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
807 "Readings");
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100808
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000809 EXPECT_THAT(readings, ElementsAre(std::make_tuple("b"s, 17.1, 114u),
810 std::make_tuple("bb"s, 42.0, 74u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100811}
812
813class TestReportNonOnRequestType :
814 public TestReport,
815 public WithParamInterface<ReportParams>
816{
817 void SetUp() override
818 {
819 sut = makeReport(GetParam());
820 }
821};
822
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000823INSTANTIATE_TEST_SUITE_P(_, TestReportNonOnRequestType,
824 Values(defaultParams()
825 .reportingType(ReportingType::periodic)
826 .interval(ReportManager::minInterval * 10),
827 defaultParams()
828 .reportingType(ReportingType::onChange)
829 .interval(Milliseconds(0))));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100830
831TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
832{
833 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
834
835 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
836 Eq(Readings{}));
837}
838
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200839class TestReportNonPeriodicReport :
840 public TestReport,
841 public WithParamInterface<ReportParams>
842{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200843 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200844 void SetUp() override
845 {
846 sut = makeReport(GetParam());
847 }
848};
849
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100850INSTANTIATE_TEST_SUITE_P(
851 _, TestReportNonPeriodicReport,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100852 Values(defaultParams().reportingType(ReportingType::onRequest),
853 defaultParams().reportingType(ReportingType::onChange)));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200854
855TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
856{
857 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
858
859 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
860 Eq(Readings{}));
861}
862
863class TestReportPeriodicReport : public TestReport
864{
865 void SetUp() override
866 {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200867 sut = makeReport(defaultParams()
Krzysztof Grobelny18e71012022-11-02 13:17:01 +0000868 .appendLimit(2u)
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +0200869 .reportingType(ReportingType::periodic)
870 .interval(ReportManager::minInterval));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200871 }
872};
873
874TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
875{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100876 clockFake.system.advance(10ms);
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200877 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
878
Patrick Williams3a1c2972023-05-10 07:51:04 -0500879 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
880 "Readings");
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200881
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100882 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200883}
884
885TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
886{
887 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
888
Patrick Williams3a1c2972023-05-10 07:51:04 -0500889 const auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
890 "Readings");
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200891
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000892 EXPECT_THAT(readings, ElementsAre(std::make_tuple("b"s, 17.1, 114u),
893 std::make_tuple("bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200894}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100895
Szymon Dompke3eb56862021-09-20 15:32:04 +0200896struct ReportUpdatesReportParams
897{
898 ReportParams reportParams;
899 std::vector<ReadingData> expectedReadings;
900 bool expectedEnabled;
901};
902
903class TestReportWithReportUpdatesAndLimit :
904 public TestReport,
905 public WithParamInterface<ReportUpdatesReportParams>
906{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200907 public:
Patrick Williams3a1c2972023-05-10 07:51:04 -0500908 void SetUp() override {}
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200909
910 void changeReport(ReportingType rt, Milliseconds interval)
Szymon Dompke3eb56862021-09-20 15:32:04 +0200911 {
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000912 callMethod(sut->getPath(), "SetReportingProperties",
913 utils::enumToString(rt), interval.count());
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200914 }
915
916 auto readings()
917 {
Patrick Williams3a1c2972023-05-10 07:51:04 -0500918 auto [timestamp, readings] = getProperty<Readings>(sut->getPath(),
919 "Readings");
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +0200920 return readings;
921 }
922
923 void updateReportFourTimes()
924 {
925 for (int i = 0; i < 4; i++)
926 {
927 messanger.send(messages::UpdateReportInd{{sut->getId()}});
928 }
Szymon Dompke3eb56862021-09-20 15:32:04 +0200929 }
930};
931
932INSTANTIATE_TEST_SUITE_P(
933 _, TestReportWithReportUpdatesAndLimit,
934 Values(
935 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100936 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100937 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
938 .appendLimit(5),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000939 std::vector<ReadingData>{{std::make_tuple("bb"s, 42.0, 74u),
940 std::make_tuple("b"s, 17.1, 114u),
941 std::make_tuple("bb"s, 42.0, 74u),
942 std::make_tuple("bb"s, 42.0, 74u),
943 std::make_tuple("b"s, 17.1, 114u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +0200944 true},
945 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100946 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100947 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
948 .appendLimit(4),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000949 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
950 std::make_tuple("bb"s, 42.0, 74u),
951 std::make_tuple("b"s, 17.1, 114u),
952 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +0200953 true},
954 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100955 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100956 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
957 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200958 std::vector<ReadingData>{}, true},
959 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100960 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100961 .reportUpdates(ReportUpdates::appendStopsWhenFull)
962 .appendLimit(10),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000963 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
964 std::make_tuple("bb"s, 42.0, 74u),
965 std::make_tuple("b"s, 17.1, 114u),
966 std::make_tuple("bb"s, 42.0, 74u),
967 std::make_tuple("b"s, 17.1, 114u),
968 std::make_tuple("bb"s, 42.0, 74u),
969 std::make_tuple("b"s, 17.1, 114u),
970 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +0200971 true},
972 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100973 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100974 .reportUpdates(ReportUpdates::appendStopsWhenFull)
975 .appendLimit(5),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000976 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
977 std::make_tuple("bb"s, 42.0, 74u),
978 std::make_tuple("b"s, 17.1, 114u),
979 std::make_tuple("bb"s, 42.0, 74u),
980 std::make_tuple("b"s, 17.1, 114u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +0200981 false},
982 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100983 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100984 .reportUpdates(ReportUpdates::appendStopsWhenFull)
985 .appendLimit(4),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000986 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
987 std::make_tuple("bb"s, 42.0, 74u),
988 std::make_tuple("b"s, 17.1, 114u),
989 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +0200990 false},
991 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100992 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100993 .reportUpdates(ReportUpdates::appendStopsWhenFull)
994 .appendLimit(0),
Szymon Dompke3eb56862021-09-20 15:32:04 +0200995 std::vector<ReadingData>{}, false},
996 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100997 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +0100998 .reportUpdates(ReportUpdates::overwrite)
999 .appendLimit(500),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001000 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1001 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001002 true},
1003 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001004 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001005 .reportUpdates(ReportUpdates::overwrite)
1006 .appendLimit(1),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001007 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1008 std::make_tuple("bb"s, 42.0, 74u)}},
Szymon Dompke3eb56862021-09-20 15:32:04 +02001009 true},
1010 ReportUpdatesReportParams{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001011 defaultParams()
Krzysztof Grobelny51497a02021-11-09 14:56:22 +01001012 .reportUpdates(ReportUpdates::overwrite)
1013 .appendLimit(0),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001014 std::vector<ReadingData>{{std::make_tuple("b"s, 17.1, 114u),
1015 std::make_tuple("bb"s, 42.0, 74u)}},
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001016 true},
1017 ReportUpdatesReportParams{
1018 defaultParams()
1019 .reportUpdates(ReportUpdates::appendStopsWhenFull)
Krzysztof Grobelny18e71012022-11-02 13:17:01 +00001020 .appendLimit(2u),
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)}},
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001023 false}));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001024
1025TEST_P(TestReportWithReportUpdatesAndLimit,
1026 readingsAreUpdatedAfterIntervalExpires)
1027{
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001028 sut = makeReport(ReportParams(GetParam().reportParams)
1029 .reportingType(ReportingType::periodic)
1030 .interval(std::chrono::hours(1000)));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001031
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001032 updateReportFourTimes();
Szymon Dompke3eb56862021-09-20 15:32:04 +02001033
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001034 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1035 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1036 Eq(GetParam().expectedEnabled));
1037}
1038
1039TEST_P(TestReportWithReportUpdatesAndLimit,
1040 appendLimitIsRespectedAfterChangingToPeriodic)
1041{
1042 sut = makeReport(ReportParams(GetParam().reportParams)
Krzysztof Grobelny18e71012022-11-02 13:17:01 +00001043 .appendLimit(GetParam().expectedReadings.size())
Krzysztof Grobelnya8182be2022-07-04 11:26:20 +02001044 .reportingType(ReportingType::onRequest)
1045 .interval(std::chrono::hours(0)));
1046
1047 changeReport(ReportingType::periodic, std::chrono::hours(1000));
1048 updateReportFourTimes();
1049
1050 EXPECT_THAT(readings(), ElementsAreArray(GetParam().expectedReadings));
1051 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
1052 Eq(GetParam().expectedEnabled));
1053}
1054
1055TEST_P(TestReportWithReportUpdatesAndLimit,
1056 appendLimitIsIgnoredAfterChangingToOnRequest)
1057{
1058 sut = makeReport(ReportParams(GetParam().reportParams)
1059 .reportingType(ReportingType::periodic)
1060 .interval(std::chrono::hours(1000)));
1061
1062 changeReport(ReportingType::onRequest, Milliseconds{0});
1063 updateReportFourTimes();
1064
1065 EXPECT_THAT(readings(), SizeIs(2u));
1066 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(true));
Szymon Dompke3eb56862021-09-20 15:32:04 +02001067}
1068
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001069class TestReportInitialization : public TestReport
1070{
1071 public:
1072 void SetUp() override
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001073 {
1074 initMetricMocks(defaultParams().metricParameters());
1075 }
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001076
Patrick Williams39cc6ac2022-07-22 19:26:56 -05001077 void monitorProc(sdbusplus::message_t& msg)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001078 {
1079 std::string iface;
1080 std::vector<std::pair<std::string, std::variant<Readings>>>
1081 changed_properties;
1082 std::vector<std::string> invalidated_properties;
1083
1084 msg.read(iface, changed_properties, invalidated_properties);
1085
1086 if (iface == Report::reportIfaceName)
1087 {
1088 for (const auto& [name, value] : changed_properties)
1089 {
1090 if (name == "Readings")
1091 {
1092 readingsUpdated.Call();
1093 }
1094 }
1095 }
1096 }
1097
1098 void makeMonitor()
1099 {
Patrick Williams3a62ee12021-12-03 10:13:25 -06001100 monitor = std::make_unique<sdbusplus::bus::match_t>(
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001101 *DbusEnvironment::getBus(),
1102 sdbusplus::bus::match::rules::propertiesChanged(
1103 sut->getPath(), Report::reportIfaceName),
1104 [this](auto& msg) { monitorProc(msg); });
1105 }
1106
Patrick Williams3a62ee12021-12-03 10:13:25 -06001107 std::unique_ptr<sdbusplus::bus::match_t> monitor;
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001108 MockFunction<void()> readingsUpdated;
1109};
1110
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001111TEST_F(TestReportInitialization,
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001112 registersForMetricUpdatesWhenOnChangeReportCreated)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001113{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001114 std::vector<const interfaces::MetricListener*> args;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001115 for (auto& metric : metricMocks)
1116 {
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001117 EXPECT_CALL(*metric, registerForUpdates(_))
1118 .WillOnce(Invoke([&args](const interfaces::MetricListener& report) {
Patrick Williamsc7935fa2023-10-20 11:19:30 -05001119 args.emplace_back(&report);
1120 }));
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001121 ;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001122 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001123
1124 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1125
1126 EXPECT_THAT(args, SizeIs(metricMocks.size()));
1127 for (const auto* reportPtr : args)
1128 {
1129 EXPECT_THAT(reportPtr, Eq(sut.get()));
1130 }
1131}
1132
1133TEST_F(TestReportInitialization,
1134 deregistersForMetricUpdatesWhenOnChangeReportDestroyed)
1135{
1136 sut = makeReport(defaultParams().reportingType(ReportingType::onChange));
1137
1138 for (auto& metric : metricMocks)
1139 {
1140 EXPECT_CALL(*metric,
1141 unregisterFromUpdates(Ref(
1142 static_cast<interfaces::MetricListener&>(*sut.get()))));
1143 }
1144
1145 sut = nullptr;
1146}
1147
1148TEST_F(TestReportInitialization,
1149 metricsAreInitializedWhenEnabledReportConstructed)
1150{
1151 for (auto& metric : metricMocks)
1152 {
1153 EXPECT_CALL(*metric, initialize());
1154 }
1155 sut = makeReport(defaultParams().enabled(true));
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001156}
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001157
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001158TEST_F(TestReportInitialization,
1159 metricsAreNotInitializedWhenDisabledReportConstructed)
1160{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +02001161 for (auto& metric : metricMocks)
1162 {
1163 EXPECT_CALL(*metric, initialize()).Times(0);
1164 }
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001165 sut = makeReport(defaultParams().enabled(false));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01001166}
1167
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001168TEST_F(TestReportInitialization,
1169 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001170{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001171 EXPECT_CALL(readingsUpdated, Call())
1172 .WillOnce(
1173 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
1174
1175 const auto elapsed = DbusEnvironment::measureTime([this] {
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001176 sut = makeReport(defaultParams()
1177 .reportingType(ReportingType::periodic)
1178 .reportActions({ReportAction::emitsReadingsUpdate})
1179 .interval(ReportManager::minInterval));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001180 makeMonitor();
1181 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
1182 });
1183
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +02001184 EXPECT_THAT(elapsed, AllOf(Ge(ReportManager::minInterval),
1185 Lt(ReportManager::minInterval * 2)));
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +02001186}
1187
1188TEST_F(TestReportInitialization,
1189 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
1190{
1191 EXPECT_CALL(readingsUpdated, Call()).Times(0);
1192
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001193 sut = makeReport(defaultParams()
1194 .reportingType(ReportingType::periodic)
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00001195 .reportActions({})
1196 .interval(Milliseconds(1000)));
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001197 makeMonitor();
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001198 DbusEnvironment::sleepFor(defaultParams().interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001199}
Szymon Dompke3eb56862021-09-20 15:32:04 +02001200
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001201TEST_F(TestReportInitialization, triggerIdsPropertyIsInitialzed)
1202{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001203 for (const auto& triggerId : {"trigger1", "trigger2"})
1204 {
1205 messanger.on_receive<messages::CollectTriggerIdReq>(
Szymon Dompkee0ed5082022-05-20 10:54:25 +02001206 [this, triggerId](const auto& msg) {
Patrick Williams3a1c2972023-05-10 07:51:04 -05001207 messanger.send(messages::CollectTriggerIdResp{triggerId});
1208 });
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01001209 }
1210
1211 sut = makeReport(ReportParams());
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001212
1213 EXPECT_THAT(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +02001214 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"),
1215 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1",
1216 utils::constants::triggerDirPath / "trigger2"));
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +01001217}
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001218
Krzysztof Grobelny493e62e2022-02-14 10:55:50 +01001219TEST_F(TestReportInitialization,
1220 metricValuesAreNotStoredForReportUpdatesDifferentThanAppendStopsWhenFull)
1221{
1222 sut = makeReport(ReportParams()
1223 .reportingType(ReportingType::periodic)
1224 .interval(1h)
1225 .reportUpdates(ReportUpdates::appendWrapsWhenFull)
1226 .readings(Readings{{}, {{}}}));
1227
1228 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1229 Eq(storedConfiguration.end()));
1230}
1231
1232TEST_F(TestReportInitialization, metricValuesAreNotStoredForOnRequestReport)
1233{
1234 sut = makeReport(ReportParams()
1235 .reportingType(ReportingType::onRequest)
1236 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1237 .readings(Readings{{}, {{}}}));
1238
1239 ASSERT_THAT(storedConfiguration.find("MetricValues"),
1240 Eq(storedConfiguration.end()));
1241}
1242
1243TEST_F(TestReportInitialization,
1244 metricValuesAreStoredForNonOnRequestReportWithAppendStopsWhenFull)
1245{
1246 const auto readings = Readings{{}, {{}}};
1247
1248 sut = makeReport(ReportParams()
1249 .reportingType(ReportingType::periodic)
1250 .interval(1h)
1251 .reportUpdates(ReportUpdates::appendStopsWhenFull)
1252 .readings(readings));
1253
1254 ASSERT_THAT(storedConfiguration.at("MetricValues").get<LabeledReadings>(),
1255 Eq(utils::toLabeledReadings(readings)));
1256}
1257
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001258class TestReportInitializationOnChangeReport : public TestReportInitialization
1259{
1260 public:
1261 void SetUp() override
1262 {
1263 initMetricMocks(params.metricParameters());
1264 }
1265
1266 ReportParams params = defaultOnChangeParams();
1267};
1268
1269TEST_F(TestReportInitializationOnChangeReport,
1270 doesntUpdateReadingsWhenNotRequired)
1271{
1272 EXPECT_CALL(*metricMocks[0], updateReadings(_)).Times(0);
1273
1274 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(false));
1275
1276 sut = makeReport(params);
1277
1278 DbusEnvironment::sleepFor(500ms);
1279}
1280
1281TEST_F(TestReportInitializationOnChangeReport, updatesReadingsWhenRequired)
1282{
1283 EXPECT_CALL(*metricMocks[0], updateReadings(_))
1284 .WillOnce(Return())
1285 .WillOnce(
1286 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")))
1287 .WillRepeatedly(Return());
1288
1289 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(true));
1290
1291 sut = makeReport(params);
1292
1293 DbusEnvironment::waitForFuture("readingsUpdated");
1294}