blob: 79e66ff15d52547acb1fbf8a8b3caf0465dc67bc [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())
Krzysztof Grobelny80697712021-03-04 09:49:27 +000049 .WillByDefault(Return(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>>(
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +020076 metricMocks),
77 params.enabled());
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020078 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020079
80 template <class T>
81 static T getProperty(const std::string& path, const std::string& property)
82 {
Ed Tanous0e7ae5d2021-02-23 14:06:49 -080083 auto propertyPromise = std::promise<T>();
84 auto propertyFuture = propertyPromise.get_future();
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020085 sdbusplus::asio::getProperty<T>(
86 *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
87 Report::reportIfaceName, property,
Ed Tanous0e7ae5d2021-02-23 14:06:49 -080088 [&propertyPromise](const boost::system::error_code& ec, T t) {
89 if (ec)
90 {
91 utils::setException(propertyPromise, "GetProperty failed");
92 return;
93 }
94 propertyPromise.set_value(t);
95 });
96 return DbusEnvironment::waitForFuture(std::move(propertyFuture));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +010097 }
98
99 boost::system::error_code call(const std::string& path,
100 const std::string& interface,
101 const std::string& method)
102 {
103 std::promise<boost::system::error_code> methodPromise;
104 DbusEnvironment::getBus()->async_method_call(
105 [&methodPromise](boost::system::error_code ec) {
106 methodPromise.set_value(ec);
107 },
108 DbusEnvironment::serviceName(), path, interface, method);
109 return DbusEnvironment::waitForFuture(methodPromise.get_future());
110 }
111
112 boost::system::error_code update(const std::string& path)
113 {
114 return call(path, Report::reportIfaceName, "Update");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200115 }
116
117 template <class T>
118 static boost::system::error_code setProperty(const std::string& path,
119 const std::string& property,
120 const T& newValue)
121 {
Ed Tanous0e7ae5d2021-02-23 14:06:49 -0800122 auto setPromise = std::promise<boost::system::error_code>();
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000123 auto future = setPromise.get_future();
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200124 sdbusplus::asio::setProperty(
125 *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
126 Report::reportIfaceName, property, std::move(newValue),
Ed Tanous0e7ae5d2021-02-23 14:06:49 -0800127 [setPromise =
128 std::move(setPromise)](boost::system::error_code ec) mutable {
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200129 setPromise.set_value(ec);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200130 });
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000131 return DbusEnvironment::waitForFuture(std::move(future));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200132 }
133
134 boost::system::error_code deleteReport(const std::string& path)
135 {
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100136 return call(path, Report::deleteIfaceName, "Delete");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200137 }
138};
139
140TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
141{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200142 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"),
143 Eq(defaultParams.enabled()));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200144 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100145 Eq(defaultParams.interval().count()));
146 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200147 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100148 Eq(defaultParams.emitReadingUpdate()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200149 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200150 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100151 Eq(defaultParams.logToMetricReportCollection()));
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000152 EXPECT_THAT(getProperty<ReadingParameters>(
153 sut->getPath(), "ReadingParametersFutureVersion"),
154 Eq(toReadingParameters(defaultParams.metricParameters())));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200155}
156
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200157TEST_F(TestReport, readingsAreInitialyEmpty)
158{
159 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
160 Eq(Readings{}));
161}
162
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200163TEST_F(TestReport, setEnabledWithNewValue)
164{
165 bool newValue = !defaultParams.enabled();
166 EXPECT_THAT(setProperty(sut->getPath(), "Enabled", newValue).value(),
167 Eq(boost::system::errc::success));
168 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(newValue));
169}
170
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200171TEST_F(TestReport, setIntervalWithValidValue)
172{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100173 uint64_t newValue = defaultParams.interval().count() + 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200174 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200175 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200176 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
177 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200178}
179
180TEST_F(TestReport, settingIntervalWithInvalidValueDoesNotChangeProperty)
181{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100182 uint64_t newValue = defaultParams.interval().count() - 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200183 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200184 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200185 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100186 Eq(defaultParams.interval().count()));
187}
188
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200189TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
190{
191 EXPECT_THAT(setProperty(sut->getPath(), "EmitsReadingsUpdate",
192 !defaultParams.emitReadingUpdate())
193 .value(),
194 Eq(boost::system::errc::read_only_file_system));
195 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
196 Eq(defaultParams.emitReadingUpdate()));
197}
198
199TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
200{
201 EXPECT_THAT(setProperty(sut->getPath(), "LogToMetricReportsCollection",
202 !defaultParams.logToMetricReportCollection())
203 .value(),
204 Eq(boost::system::errc::read_only_file_system));
205 EXPECT_THAT(
206 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
207 Eq(defaultParams.logToMetricReportCollection()));
208}
209
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100210TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
211{
212 EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
213
214 bool persistency = false;
215 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
216 Eq(boost::system::errc::success));
217 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
218 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200219}
220
221TEST_F(TestReport, deleteReport)
222{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200223 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
224 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200225 EXPECT_THAT(ec, Eq(boost::system::errc::success));
226}
227
228TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
229{
230 auto ec = deleteReport(Report::reportDir + "NonExisting"s);
231 EXPECT_THAT(ec.value(), Eq(EBADR));
232}
233
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100234TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
235{
236 EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
237 auto ec = deleteReport(sut->getPath());
238 EXPECT_THAT(ec, Eq(boost::system::errc::success));
239}
240
241class TestReportStore :
242 public TestReport,
243 public WithParamInterface<std::pair<std::string, nlohmann::json>>
244{
245 public:
246 void SetUp() override
247 {}
248
249 nlohmann::json storedConfiguration;
250};
251
252INSTANTIATE_TEST_SUITE_P(
253 _, TestReportStore,
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200254 Values(std::make_pair("Enabled"s, nlohmann::json(ReportParams().enabled())),
255 std::make_pair("Version"s, nlohmann::json(4)),
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000256 std::make_pair("Name"s, nlohmann::json(ReportParams().reportName())),
257 std::make_pair("ReportingType",
258 nlohmann::json(ReportParams().reportingType())),
259 std::make_pair("EmitsReadingsUpdate",
260 nlohmann::json(ReportParams().emitReadingUpdate())),
261 std::make_pair(
262 "LogToMetricReportsCollection",
263 nlohmann::json(ReportParams().logToMetricReportCollection())),
264 std::make_pair("Interval",
265 nlohmann::json(ReportParams().interval().count())),
266 std::make_pair(
267 "ReadingParameters",
268 nlohmann::json(
269 {{{tstring::SensorPath::str(),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000270 {{{tstring::Service::str(), "Service"},
271 {tstring::Path::str(),
272 "/xyz/openbmc_project/sensors/power/p1"}}}},
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000273 {tstring::OperationType::str(), OperationType::single},
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000274 {tstring::Id::str(), "MetricId1"},
275 {tstring::MetricMetadata::str(), "Metadata1"},
276 {tstring::CollectionTimeScope::str(),
277 CollectionTimeScope::point},
278 {tstring::CollectionDuration::str(), 0}},
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000279 {{tstring::SensorPath::str(),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000280 {{{tstring::Service::str(), "Service"},
281 {tstring::Path::str(),
282 "/xyz/openbmc_project/sensors/power/p2"}}}},
283 {tstring::OperationType::str(), OperationType::single},
284 {tstring::Id::str(), "MetricId2"},
285 {tstring::MetricMetadata::str(), "Metadata2"},
286 {tstring::CollectionTimeScope::str(),
287 CollectionTimeScope::point},
288 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100289
290TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
291{
292 sut = makeReport(ReportParams());
293
294 {
295 InSequence seq;
296 EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
297 EXPECT_CALL(checkPoint, Call());
298 EXPECT_CALL(storageMock, store(to_file_path(sut->getName()), _))
299 .WillOnce(SaveArg<1>(&storedConfiguration));
300 }
301
302 setProperty(sut->getPath(), "Persistency", false);
303 checkPoint.Call();
304 setProperty(sut->getPath(), "Persistency", true);
305
306 const auto& [key, value] = GetParam();
307
308 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
309}
310
311TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
312{
313 EXPECT_CALL(storageMock,
314 store(to_file_path(ReportParams().reportName()), _))
315 .WillOnce(SaveArg<1>(&storedConfiguration));
316
317 sut = makeReport(ReportParams());
318
319 const auto& [key, value] = GetParam();
320
321 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
322}
323
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200324class TestReportValidNames :
325 public TestReport,
326 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200327{
328 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200329 void SetUp() override
330 {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200331};
332
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200333INSTANTIATE_TEST_SUITE_P(
334 ValidNames, TestReportValidNames,
335 Values(ReportParams().reportName("Valid_1"),
336 ReportParams().reportName("Valid_1/Valid_2"),
337 ReportParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200338
339TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
340{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200341 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200342}
343
344class TestReportInvalidNames :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200345 public TestReport,
346 public WithParamInterface<ReportParams>
347{
348 public:
349 void SetUp() override
350 {}
351};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200352
353INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidNames,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200354 Values(ReportParams().reportName("/"),
355 ReportParams().reportName("/Invalid"),
356 ReportParams().reportName("Invalid/"),
357 ReportParams().reportName("Invalid/Invalid/"),
358 ReportParams().reportName("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200359
360TEST_P(TestReportInvalidNames, reportCtorThrowOnInvalidName)
361{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200362 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
363}
364
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100365TEST_F(TestReportInvalidNames, reportCtorThrowOnInvalidNameAndNoStoreIsCalled)
366{
367 EXPECT_CALL(storageMock, store).Times(0);
368 EXPECT_THROW(makeReport(ReportParams().reportName("/Invalid")),
369 sdbusplus::exception::SdBusError);
370}
371
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200372class TestReportAllReportTypes :
373 public TestReport,
374 public WithParamInterface<ReportParams>
375{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200376 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200377 void SetUp() override
378 {
379 sut = makeReport(GetParam());
380 }
381};
382
383INSTANTIATE_TEST_SUITE_P(_, TestReportAllReportTypes,
384 Values(ReportParams().reportingType("OnRequest"),
385 ReportParams().reportingType("OnChange"),
386 ReportParams().reportingType("Periodic")));
387
388TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
389{
390 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
391 Eq(GetParam().reportingType()));
392}
393
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200394TEST_P(TestReportAllReportTypes, updateReadingsCallEnabledPropertyOff)
395{
396 const uint64_t expectedTime = std::time(0);
397
398 setProperty(sut->getPath(), "Enabled", false);
399 sut->updateReadings();
400 const auto [timestamp, readings] =
401 getProperty<Readings>(sut->getPath(), "Readings");
402
403 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(false));
404 EXPECT_THAT(timestamp, Lt(expectedTime));
405}
406
407TEST_P(TestReportAllReportTypes, updateReadingsCallEnabledPropertyOn)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100408{
409 const uint64_t expectedTime = std::time(0);
410
411 sut->updateReadings();
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100412 const auto [timestamp, readings] =
413 getProperty<Readings>(sut->getPath(), "Readings");
414
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200415 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(true));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100416 EXPECT_THAT(timestamp, Ge(expectedTime));
417}
418
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100419class TestReportOnRequestType : public TestReport
420{
421 void SetUp() override
422 {
423 sut = makeReport(ReportParams().reportingType("OnRequest"));
424 }
425};
426
427TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
428{
429 const uint64_t expectedTime = std::time(0);
430
431 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
432
433 const auto [timestamp, readings] =
434 getProperty<Readings>(sut->getPath(), "Readings");
435
436 EXPECT_THAT(timestamp, Ge(expectedTime));
437}
438
439TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
440{
441 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
442
443 const auto [timestamp, readings] =
444 getProperty<Readings>(sut->getPath(), "Readings");
445
446 EXPECT_THAT(readings,
447 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000448 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100449}
450
451class TestReportNonOnRequestType :
452 public TestReport,
453 public WithParamInterface<ReportParams>
454{
455 void SetUp() override
456 {
457 sut = makeReport(GetParam());
458 }
459};
460
461INSTANTIATE_TEST_SUITE_P(_, TestReportNonOnRequestType,
462 Values(ReportParams().reportingType("Periodic"),
463 ReportParams().reportingType("OnChange")));
464
465TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
466{
467 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
468
469 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
470 Eq(Readings{}));
471}
472
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200473class TestReportNonPeriodicReport :
474 public TestReport,
475 public WithParamInterface<ReportParams>
476{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200477 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200478 void SetUp() override
479 {
480 sut = makeReport(GetParam());
481 }
482};
483
484INSTANTIATE_TEST_SUITE_P(_, TestReportNonPeriodicReport,
485 Values(ReportParams().reportingType("OnRequest"),
486 ReportParams().reportingType("OnChange")));
487
488TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
489{
490 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
491
492 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
493 Eq(Readings{}));
494}
495
496class TestReportPeriodicReport : public TestReport
497{
498 void SetUp() override
499 {
500 sut = makeReport(ReportParams().reportingType("Periodic"));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200501 }
502};
503
504TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
505{
506 const uint64_t expectedTime = std::time(0);
507 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
508
509 const auto [timestamp, readings] =
510 getProperty<Readings>(sut->getPath(), "Readings");
511
512 EXPECT_THAT(timestamp, Ge(expectedTime));
513}
514
515TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
516{
517 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
518
519 const auto [timestamp, readings] =
520 getProperty<Readings>(sut->getPath(), "Readings");
521
522 EXPECT_THAT(readings,
523 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000524 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200525}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100526
527class TestReportInitialization : public TestReport
528{
529 public:
530 void SetUp() override
531 {}
532
533 void monitorProc(sdbusplus::message::message& msg)
534 {
535 std::string iface;
536 std::vector<std::pair<std::string, std::variant<Readings>>>
537 changed_properties;
538 std::vector<std::string> invalidated_properties;
539
540 msg.read(iface, changed_properties, invalidated_properties);
541
542 if (iface == Report::reportIfaceName)
543 {
544 for (const auto& [name, value] : changed_properties)
545 {
546 if (name == "Readings")
547 {
548 readingsUpdated.Call();
549 }
550 }
551 }
552 }
553
554 void makeMonitor()
555 {
556 monitor = std::make_unique<sdbusplus::bus::match::match>(
557 *DbusEnvironment::getBus(),
558 sdbusplus::bus::match::rules::propertiesChanged(
559 sut->getPath(), Report::reportIfaceName),
560 [this](auto& msg) { monitorProc(msg); });
561 }
562
563 std::unique_ptr<sdbusplus::bus::match::match> monitor;
564 MockFunction<void()> readingsUpdated;
565};
566
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200567TEST_F(TestReportInitialization,
568 metricsAreInitializedWhenEnabledReportConstructed)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100569{
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200570 initMetricMocks(defaultParams.metricParameters());
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100571 for (auto& metric : metricMocks)
572 {
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200573 EXPECT_CALL(*metric, initialize()).Times(1);
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100574 }
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200575 sut = makeReport(defaultParams.enabled(true));
576}
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100577
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +0200578TEST_F(TestReportInitialization,
579 metricsAreNotInitializedWhenDisabledReportConstructed)
580{
581 initMetricMocks(defaultParams.metricParameters());
582 for (auto& metric : metricMocks)
583 {
584 EXPECT_CALL(*metric, initialize()).Times(0);
585 }
586 sut = makeReport(defaultParams.enabled(false));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100587}
588
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200589TEST_F(TestReportInitialization,
590 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100591{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200592 EXPECT_CALL(readingsUpdated, Call())
593 .WillOnce(
594 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
595
596 const auto elapsed = DbusEnvironment::measureTime([this] {
597 sut = makeReport(
598 defaultParams.reportingType("Periodic").emitReadingUpdate(true));
599 makeMonitor();
600 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
601 });
602
603 EXPECT_THAT(elapsed, AllOf(Ge(defaultParams.interval()),
604 Lt(defaultParams.interval() * 2)));
605}
606
607TEST_F(TestReportInitialization,
608 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
609{
610 EXPECT_CALL(readingsUpdated, Call()).Times(0);
611
612 sut = makeReport(
613 defaultParams.reportingType("Periodic").emitReadingUpdate(false));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100614 makeMonitor();
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200615 DbusEnvironment::sleepFor(defaultParams.interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100616}