blob: 96f74f007eff4b13984930a19982f61dfb311889 [file] [log] [blame]
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +02001#include "dbus_environment.hpp"
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +00002#include "helpers.hpp"
Wludzik, Jozefe2362792020-10-27 17:23:55 +01003#include "mocks/json_storage_mock.hpp"
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +02004#include "mocks/metric_mock.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +02005#include "mocks/report_manager_mock.hpp"
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +02006#include "params/report_params.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +02007#include "report.hpp"
8#include "report_manager.hpp"
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +02009#include "utils/conv_container.hpp"
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +010010#include "utils/set_exception.hpp"
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000011#include "utils/tstring.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020012
13#include <sdbusplus/exception.hpp>
14
15using namespace testing;
16using namespace std::literals::string_literals;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020017using namespace std::chrono_literals;
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000018namespace tstring = utils::tstring;
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020019
20class TestReport : public Test
21{
22 public:
Wludzik, Jozefe2362792020-10-27 17:23:55 +010023 ReportParams defaultParams;
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020024
25 std::unique_ptr<ReportManagerMock> reportManagerMock =
Wludzik, Jozefe2362792020-10-27 17:23:55 +010026 std::make_unique<NiceMock<ReportManagerMock>>();
27 testing::NiceMock<StorageMock> storageMock;
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000028 std::vector<std::shared_ptr<MetricMock>> metricMocks;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020029 std::unique_ptr<Report> sut;
30
Wludzik, Jozefe2362792020-10-27 17:23:55 +010031 MockFunction<void()> checkPoint;
32
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000033 void initMetricMocks(
34 const std::vector<LabeledMetricParameters>& metricParameters)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010035 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000036 for (auto i = metricMocks.size(); i < metricParameters.size(); ++i)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010037 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000038 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>());
39 }
40 metricMocks.resize(metricParameters.size());
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000041
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000042 std::vector<MetricValue> readings{{MetricValue{"a", "b", 17.1, 114},
43 MetricValue{"aa", "bb", 42.0, 74}}};
44 readings.resize(metricParameters.size());
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000045
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000046 for (size_t i = 0; i < metricParameters.size(); ++i)
47 {
48 ON_CALL(*metricMocks[i], getReadings())
49 .WillByDefault(ReturnRefOfCopy(std::vector({readings[i]})));
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000050 ON_CALL(*metricMocks[i], dumpConfiguration())
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000051 .WillByDefault(Return(metricParameters[i]));
Wludzik, Jozefe2362792020-10-27 17:23:55 +010052 }
53 }
54
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020055 void SetUp() override
56 {
57 sut = makeReport(ReportParams());
58 }
59
Wludzik, Jozefe2362792020-10-27 17:23:55 +010060 static interfaces::JsonStorage::FilePath to_file_path(std::string name)
61 {
62 return interfaces::JsonStorage::FilePath(
63 std::to_string(std::hash<std::string>{}(name)));
64 }
65
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020066 std::unique_ptr<Report> makeReport(const ReportParams& params)
67 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000068 initMetricMocks(params.metricParameters());
69
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020070 return std::make_unique<Report>(
71 DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
72 params.reportName(), params.reportingType(),
Wludzik, Jozefe2362792020-10-27 17:23:55 +010073 params.emitReadingUpdate(), params.logToMetricReportCollection(),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000074 params.interval(), *reportManagerMock, storageMock,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020075 utils::convContainer<std::shared_ptr<interfaces::Metric>>(
76 metricMocks));
77 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020078
79 template <class T>
80 static T getProperty(const std::string& path, const std::string& property)
81 {
Ed Tanous0e7ae5d2021-02-23 14:06:49 -080082 auto propertyPromise = std::promise<T>();
83 auto propertyFuture = propertyPromise.get_future();
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020084 sdbusplus::asio::getProperty<T>(
85 *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
86 Report::reportIfaceName, property,
Ed Tanous0e7ae5d2021-02-23 14:06:49 -080087 [&propertyPromise](const boost::system::error_code& ec, T t) {
88 if (ec)
89 {
90 utils::setException(propertyPromise, "GetProperty failed");
91 return;
92 }
93 propertyPromise.set_value(t);
94 });
95 return DbusEnvironment::waitForFuture(std::move(propertyFuture));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +010096 }
97
98 boost::system::error_code call(const std::string& path,
99 const std::string& interface,
100 const std::string& method)
101 {
102 std::promise<boost::system::error_code> methodPromise;
103 DbusEnvironment::getBus()->async_method_call(
104 [&methodPromise](boost::system::error_code ec) {
105 methodPromise.set_value(ec);
106 },
107 DbusEnvironment::serviceName(), path, interface, method);
108 return DbusEnvironment::waitForFuture(methodPromise.get_future());
109 }
110
111 boost::system::error_code update(const std::string& path)
112 {
113 return call(path, Report::reportIfaceName, "Update");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200114 }
115
116 template <class T>
117 static boost::system::error_code setProperty(const std::string& path,
118 const std::string& property,
119 const T& newValue)
120 {
Ed Tanous0e7ae5d2021-02-23 14:06:49 -0800121 auto setPromise = std::promise<boost::system::error_code>();
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000122 auto future = setPromise.get_future();
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200123 sdbusplus::asio::setProperty(
124 *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
125 Report::reportIfaceName, property, std::move(newValue),
Ed Tanous0e7ae5d2021-02-23 14:06:49 -0800126 [setPromise =
127 std::move(setPromise)](boost::system::error_code ec) mutable {
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200128 setPromise.set_value(ec);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200129 });
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000130 return DbusEnvironment::waitForFuture(std::move(future));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200131 }
132
133 boost::system::error_code deleteReport(const std::string& path)
134 {
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100135 return call(path, Report::deleteIfaceName, "Delete");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200136 }
137};
138
139TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
140{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200141 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100142 Eq(defaultParams.interval().count()));
143 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200144 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100145 Eq(defaultParams.emitReadingUpdate()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200146 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200147 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100148 Eq(defaultParams.logToMetricReportCollection()));
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000149 EXPECT_THAT(getProperty<ReadingParameters>(
150 sut->getPath(), "ReadingParametersFutureVersion"),
151 Eq(toReadingParameters(defaultParams.metricParameters())));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200152}
153
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200154TEST_F(TestReport, readingsAreInitialyEmpty)
155{
156 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
157 Eq(Readings{}));
158}
159
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200160TEST_F(TestReport, setIntervalWithValidValue)
161{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100162 uint64_t newValue = defaultParams.interval().count() + 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200163 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200164 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200165 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
166 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200167}
168
169TEST_F(TestReport, settingIntervalWithInvalidValueDoesNotChangeProperty)
170{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100171 uint64_t newValue = defaultParams.interval().count() - 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200172 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200173 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200174 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100175 Eq(defaultParams.interval().count()));
176}
177
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200178TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
179{
180 EXPECT_THAT(setProperty(sut->getPath(), "EmitsReadingsUpdate",
181 !defaultParams.emitReadingUpdate())
182 .value(),
183 Eq(boost::system::errc::read_only_file_system));
184 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
185 Eq(defaultParams.emitReadingUpdate()));
186}
187
188TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
189{
190 EXPECT_THAT(setProperty(sut->getPath(), "LogToMetricReportsCollection",
191 !defaultParams.logToMetricReportCollection())
192 .value(),
193 Eq(boost::system::errc::read_only_file_system));
194 EXPECT_THAT(
195 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
196 Eq(defaultParams.logToMetricReportCollection()));
197}
198
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100199TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
200{
201 EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
202
203 bool persistency = false;
204 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
205 Eq(boost::system::errc::success));
206 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
207 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200208}
209
210TEST_F(TestReport, deleteReport)
211{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200212 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
213 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200214 EXPECT_THAT(ec, Eq(boost::system::errc::success));
215}
216
217TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
218{
219 auto ec = deleteReport(Report::reportDir + "NonExisting"s);
220 EXPECT_THAT(ec.value(), Eq(EBADR));
221}
222
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100223TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
224{
225 EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
226 auto ec = deleteReport(sut->getPath());
227 EXPECT_THAT(ec, Eq(boost::system::errc::success));
228}
229
230class TestReportStore :
231 public TestReport,
232 public WithParamInterface<std::pair<std::string, nlohmann::json>>
233{
234 public:
235 void SetUp() override
236 {}
237
238 nlohmann::json storedConfiguration;
239};
240
241INSTANTIATE_TEST_SUITE_P(
242 _, TestReportStore,
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000243 Values(std::make_pair("Version"s, nlohmann::json(4)),
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000244 std::make_pair("Name"s, nlohmann::json(ReportParams().reportName())),
245 std::make_pair("ReportingType",
246 nlohmann::json(ReportParams().reportingType())),
247 std::make_pair("EmitsReadingsUpdate",
248 nlohmann::json(ReportParams().emitReadingUpdate())),
249 std::make_pair(
250 "LogToMetricReportsCollection",
251 nlohmann::json(ReportParams().logToMetricReportCollection())),
252 std::make_pair("Interval",
253 nlohmann::json(ReportParams().interval().count())),
254 std::make_pair(
255 "ReadingParameters",
256 nlohmann::json(
257 {{{tstring::SensorPath::str(),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000258 {{{tstring::Service::str(), "Service"},
259 {tstring::Path::str(),
260 "/xyz/openbmc_project/sensors/power/p1"}}}},
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000261 {tstring::OperationType::str(), OperationType::single},
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000262 {tstring::Id::str(), "MetricId1"},
263 {tstring::MetricMetadata::str(), "Metadata1"},
264 {tstring::CollectionTimeScope::str(),
265 CollectionTimeScope::point},
266 {tstring::CollectionDuration::str(), 0}},
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000267 {{tstring::SensorPath::str(),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000268 {{{tstring::Service::str(), "Service"},
269 {tstring::Path::str(),
270 "/xyz/openbmc_project/sensors/power/p2"}}}},
271 {tstring::OperationType::str(), OperationType::single},
272 {tstring::Id::str(), "MetricId2"},
273 {tstring::MetricMetadata::str(), "Metadata2"},
274 {tstring::CollectionTimeScope::str(),
275 CollectionTimeScope::point},
276 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100277
278TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
279{
280 sut = makeReport(ReportParams());
281
282 {
283 InSequence seq;
284 EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
285 EXPECT_CALL(checkPoint, Call());
286 EXPECT_CALL(storageMock, store(to_file_path(sut->getName()), _))
287 .WillOnce(SaveArg<1>(&storedConfiguration));
288 }
289
290 setProperty(sut->getPath(), "Persistency", false);
291 checkPoint.Call();
292 setProperty(sut->getPath(), "Persistency", true);
293
294 const auto& [key, value] = GetParam();
295
296 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
297}
298
299TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
300{
301 EXPECT_CALL(storageMock,
302 store(to_file_path(ReportParams().reportName()), _))
303 .WillOnce(SaveArg<1>(&storedConfiguration));
304
305 sut = makeReport(ReportParams());
306
307 const auto& [key, value] = GetParam();
308
309 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
310}
311
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200312class TestReportValidNames :
313 public TestReport,
314 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200315{
316 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200317 void SetUp() override
318 {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200319};
320
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200321INSTANTIATE_TEST_SUITE_P(
322 ValidNames, TestReportValidNames,
323 Values(ReportParams().reportName("Valid_1"),
324 ReportParams().reportName("Valid_1/Valid_2"),
325 ReportParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200326
327TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
328{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200329 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200330}
331
332class TestReportInvalidNames :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200333 public TestReport,
334 public WithParamInterface<ReportParams>
335{
336 public:
337 void SetUp() override
338 {}
339};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200340
341INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidNames,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200342 Values(ReportParams().reportName("/"),
343 ReportParams().reportName("/Invalid"),
344 ReportParams().reportName("Invalid/"),
345 ReportParams().reportName("Invalid/Invalid/"),
346 ReportParams().reportName("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200347
348TEST_P(TestReportInvalidNames, reportCtorThrowOnInvalidName)
349{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200350 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
351}
352
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100353TEST_F(TestReportInvalidNames, reportCtorThrowOnInvalidNameAndNoStoreIsCalled)
354{
355 EXPECT_CALL(storageMock, store).Times(0);
356 EXPECT_THROW(makeReport(ReportParams().reportName("/Invalid")),
357 sdbusplus::exception::SdBusError);
358}
359
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200360class TestReportAllReportTypes :
361 public TestReport,
362 public WithParamInterface<ReportParams>
363{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200364 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200365 void SetUp() override
366 {
367 sut = makeReport(GetParam());
368 }
369};
370
371INSTANTIATE_TEST_SUITE_P(_, TestReportAllReportTypes,
372 Values(ReportParams().reportingType("OnRequest"),
373 ReportParams().reportingType("OnChange"),
374 ReportParams().reportingType("Periodic")));
375
376TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
377{
378 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
379 Eq(GetParam().reportingType()));
380}
381
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100382TEST_P(TestReportAllReportTypes, updateReadingsCallUpdateReadingsProperty)
383{
384 const uint64_t expectedTime = std::time(0);
385
386 sut->updateReadings();
387
388 const auto [timestamp, readings] =
389 getProperty<Readings>(sut->getPath(), "Readings");
390
391 EXPECT_THAT(timestamp, Ge(expectedTime));
392}
393
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100394class TestReportOnRequestType : public TestReport
395{
396 void SetUp() override
397 {
398 sut = makeReport(ReportParams().reportingType("OnRequest"));
399 }
400};
401
402TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
403{
404 const uint64_t expectedTime = std::time(0);
405
406 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
407
408 const auto [timestamp, readings] =
409 getProperty<Readings>(sut->getPath(), "Readings");
410
411 EXPECT_THAT(timestamp, Ge(expectedTime));
412}
413
414TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
415{
416 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
417
418 const auto [timestamp, readings] =
419 getProperty<Readings>(sut->getPath(), "Readings");
420
421 EXPECT_THAT(readings,
422 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000423 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100424}
425
426class TestReportNonOnRequestType :
427 public TestReport,
428 public WithParamInterface<ReportParams>
429{
430 void SetUp() override
431 {
432 sut = makeReport(GetParam());
433 }
434};
435
436INSTANTIATE_TEST_SUITE_P(_, TestReportNonOnRequestType,
437 Values(ReportParams().reportingType("Periodic"),
438 ReportParams().reportingType("OnChange")));
439
440TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
441{
442 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
443
444 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
445 Eq(Readings{}));
446}
447
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200448class TestReportNonPeriodicReport :
449 public TestReport,
450 public WithParamInterface<ReportParams>
451{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200452 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200453 void SetUp() override
454 {
455 sut = makeReport(GetParam());
456 }
457};
458
459INSTANTIATE_TEST_SUITE_P(_, TestReportNonPeriodicReport,
460 Values(ReportParams().reportingType("OnRequest"),
461 ReportParams().reportingType("OnChange")));
462
463TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
464{
465 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
466
467 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
468 Eq(Readings{}));
469}
470
471class TestReportPeriodicReport : public TestReport
472{
473 void SetUp() override
474 {
475 sut = makeReport(ReportParams().reportingType("Periodic"));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200476 }
477};
478
479TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
480{
481 const uint64_t expectedTime = std::time(0);
482 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
483
484 const auto [timestamp, readings] =
485 getProperty<Readings>(sut->getPath(), "Readings");
486
487 EXPECT_THAT(timestamp, Ge(expectedTime));
488}
489
490TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
491{
492 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
493
494 const auto [timestamp, readings] =
495 getProperty<Readings>(sut->getPath(), "Readings");
496
497 EXPECT_THAT(readings,
498 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000499 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200500}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100501
502class TestReportInitialization : public TestReport
503{
504 public:
505 void SetUp() override
506 {}
507
508 void monitorProc(sdbusplus::message::message& msg)
509 {
510 std::string iface;
511 std::vector<std::pair<std::string, std::variant<Readings>>>
512 changed_properties;
513 std::vector<std::string> invalidated_properties;
514
515 msg.read(iface, changed_properties, invalidated_properties);
516
517 if (iface == Report::reportIfaceName)
518 {
519 for (const auto& [name, value] : changed_properties)
520 {
521 if (name == "Readings")
522 {
523 readingsUpdated.Call();
524 }
525 }
526 }
527 }
528
529 void makeMonitor()
530 {
531 monitor = std::make_unique<sdbusplus::bus::match::match>(
532 *DbusEnvironment::getBus(),
533 sdbusplus::bus::match::rules::propertiesChanged(
534 sut->getPath(), Report::reportIfaceName),
535 [this](auto& msg) { monitorProc(msg); });
536 }
537
538 std::unique_ptr<sdbusplus::bus::match::match> monitor;
539 MockFunction<void()> readingsUpdated;
540};
541
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100542TEST_F(TestReportInitialization, metricsAreInitializedWhenConstructed)
543{
544 for (auto& metric : metricMocks)
545 {
546 EXPECT_CALL(*metric, initialize());
547 }
548
549 sut = makeReport(ReportParams());
550}
551
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200552TEST_F(TestReportInitialization,
553 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100554{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200555 EXPECT_CALL(readingsUpdated, Call())
556 .WillOnce(
557 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
558
559 const auto elapsed = DbusEnvironment::measureTime([this] {
560 sut = makeReport(
561 defaultParams.reportingType("Periodic").emitReadingUpdate(true));
562 makeMonitor();
563 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
564 });
565
566 EXPECT_THAT(elapsed, AllOf(Ge(defaultParams.interval()),
567 Lt(defaultParams.interval() * 2)));
568}
569
570TEST_F(TestReportInitialization,
571 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
572{
573 EXPECT_CALL(readingsUpdated, Call()).Times(0);
574
575 sut = makeReport(
576 defaultParams.reportingType("Periodic").emitReadingUpdate(false));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100577 makeMonitor();
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200578 DbusEnvironment::sleepFor(defaultParams.interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100579}