blob: 80c0a9c0e342c6e2c1b6dcbea16a43c8d1b9e067 [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 Grobelnyc8e3a642020-10-23 12:29:16 +020028 std::vector<std::shared_ptr<MetricMock>> metricMocks = {
29 std::make_shared<NiceMock<MetricMock>>(),
30 std::make_shared<NiceMock<MetricMock>>(),
31 std::make_shared<NiceMock<MetricMock>>()};
32 std::unique_ptr<Report> sut;
33
Wludzik, Jozefe2362792020-10-27 17:23:55 +010034 MockFunction<void()> checkPoint;
35
36 TestReport()
37 {
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000038 ON_CALL(*metricMocks[0], getReading())
39 .WillByDefault(ReturnRefOfCopy(MetricValue{"a", "b", 17.1, 114}));
40 ON_CALL(*metricMocks[1], getReading())
41 .WillByDefault(ReturnRefOfCopy(MetricValue{"aa", "bb", 42.0, 74}));
42 ON_CALL(*metricMocks[2], getReading())
43 .WillByDefault(
44 ReturnRefOfCopy(MetricValue{"aaa", "bbb", 100.7, 21}));
Wludzik, Jozefe2362792020-10-27 17:23:55 +010045
46 for (size_t i = 0; i < metricMocks.size(); ++i)
47 {
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000048 using namespace std::string_literals;
49
50 auto id = std::to_string(i);
51
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000052 auto sensorParameters =
53 LabeledSensorParameters("service"s + id, "path"s + id);
54 auto metricParameters = LabeledMetricParameters(
55 std::move(sensorParameters), utils::toOperationType(i),
Krzysztof Grobelny9f9ff902021-03-05 14:57:53 +000056 "id"s + id, "metadata"s + id);
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000057
58 ON_CALL(*metricMocks[i], dumpConfiguration())
59 .WillByDefault(Return(std::move(metricParameters)));
Wludzik, Jozefe2362792020-10-27 17:23:55 +010060 }
61 }
62
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020063 void SetUp() override
64 {
65 sut = makeReport(ReportParams());
66 }
67
Wludzik, Jozefe2362792020-10-27 17:23:55 +010068 static interfaces::JsonStorage::FilePath to_file_path(std::string name)
69 {
70 return interfaces::JsonStorage::FilePath(
71 std::to_string(std::hash<std::string>{}(name)));
72 }
73
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020074 std::unique_ptr<Report> makeReport(const ReportParams& params)
75 {
76 return std::make_unique<Report>(
77 DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
78 params.reportName(), params.reportingType(),
Wludzik, Jozefe2362792020-10-27 17:23:55 +010079 params.emitReadingUpdate(), params.logToMetricReportCollection(),
80 params.interval(), params.readingParameters(), *reportManagerMock,
81 storageMock,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020082 utils::convContainer<std::shared_ptr<interfaces::Metric>>(
83 metricMocks));
84 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020085
86 template <class T>
87 static T getProperty(const std::string& path, const std::string& property)
88 {
Ed Tanous0e7ae5d2021-02-23 14:06:49 -080089 auto propertyPromise = std::promise<T>();
90 auto propertyFuture = propertyPromise.get_future();
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020091 sdbusplus::asio::getProperty<T>(
92 *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
93 Report::reportIfaceName, property,
Ed Tanous0e7ae5d2021-02-23 14:06:49 -080094 [&propertyPromise](const boost::system::error_code& ec, T t) {
95 if (ec)
96 {
97 utils::setException(propertyPromise, "GetProperty failed");
98 return;
99 }
100 propertyPromise.set_value(t);
101 });
102 return DbusEnvironment::waitForFuture(std::move(propertyFuture));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100103 }
104
105 boost::system::error_code call(const std::string& path,
106 const std::string& interface,
107 const std::string& method)
108 {
109 std::promise<boost::system::error_code> methodPromise;
110 DbusEnvironment::getBus()->async_method_call(
111 [&methodPromise](boost::system::error_code ec) {
112 methodPromise.set_value(ec);
113 },
114 DbusEnvironment::serviceName(), path, interface, method);
115 return DbusEnvironment::waitForFuture(methodPromise.get_future());
116 }
117
118 boost::system::error_code update(const std::string& path)
119 {
120 return call(path, Report::reportIfaceName, "Update");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200121 }
122
123 template <class T>
124 static boost::system::error_code setProperty(const std::string& path,
125 const std::string& property,
126 const T& newValue)
127 {
Ed Tanous0e7ae5d2021-02-23 14:06:49 -0800128 auto setPromise = std::promise<boost::system::error_code>();
Krzysztof Grobelny9f9ff902021-03-05 14:57:53 +0000129 auto setFuture = setPromise.get_future();
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200130 sdbusplus::asio::setProperty(
131 *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
132 Report::reportIfaceName, property, std::move(newValue),
Ed Tanous0e7ae5d2021-02-23 14:06:49 -0800133 [setPromise =
134 std::move(setPromise)](boost::system::error_code ec) mutable {
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200135 setPromise.set_value(ec);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200136 });
Krzysztof Grobelny9f9ff902021-03-05 14:57:53 +0000137 return DbusEnvironment::waitForFuture(std::move(setFuture));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200138 }
139
140 boost::system::error_code deleteReport(const std::string& path)
141 {
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100142 return call(path, Report::deleteIfaceName, "Delete");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200143 }
144};
145
146TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
147{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200148 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100149 Eq(defaultParams.interval().count()));
150 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200151 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100152 Eq(defaultParams.emitReadingUpdate()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200153 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200154 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100155 Eq(defaultParams.logToMetricReportCollection()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200156 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200157 getProperty<ReadingParameters>(sut->getPath(), "ReadingParameters"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100158 Eq(defaultParams.readingParameters()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200159}
160
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200161TEST_F(TestReport, readingsAreInitialyEmpty)
162{
163 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
164 Eq(Readings{}));
165}
166
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200167TEST_F(TestReport, setIntervalWithValidValue)
168{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100169 uint64_t newValue = defaultParams.interval().count() + 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200170 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200171 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200172 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
173 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200174}
175
176TEST_F(TestReport, settingIntervalWithInvalidValueDoesNotChangeProperty)
177{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100178 uint64_t newValue = defaultParams.interval().count() - 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200179 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200180 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200181 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100182 Eq(defaultParams.interval().count()));
183}
184
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200185TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
186{
187 EXPECT_THAT(setProperty(sut->getPath(), "EmitsReadingsUpdate",
188 !defaultParams.emitReadingUpdate())
189 .value(),
190 Eq(boost::system::errc::read_only_file_system));
191 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
192 Eq(defaultParams.emitReadingUpdate()));
193}
194
195TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
196{
197 EXPECT_THAT(setProperty(sut->getPath(), "LogToMetricReportsCollection",
198 !defaultParams.logToMetricReportCollection())
199 .value(),
200 Eq(boost::system::errc::read_only_file_system));
201 EXPECT_THAT(
202 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
203 Eq(defaultParams.logToMetricReportCollection()));
204}
205
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100206TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
207{
208 EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
209
210 bool persistency = false;
211 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
212 Eq(boost::system::errc::success));
213 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
214 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200215}
216
217TEST_F(TestReport, deleteReport)
218{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200219 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
220 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200221 EXPECT_THAT(ec, Eq(boost::system::errc::success));
222}
223
224TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
225{
226 auto ec = deleteReport(Report::reportDir + "NonExisting"s);
227 EXPECT_THAT(ec.value(), Eq(EBADR));
228}
229
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100230TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
231{
232 EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
233 auto ec = deleteReport(sut->getPath());
234 EXPECT_THAT(ec, Eq(boost::system::errc::success));
235}
236
237class TestReportStore :
238 public TestReport,
239 public WithParamInterface<std::pair<std::string, nlohmann::json>>
240{
241 public:
242 void SetUp() override
243 {}
244
245 nlohmann::json storedConfiguration;
246};
247
248INSTANTIATE_TEST_SUITE_P(
249 _, TestReportStore,
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000250 Values(std::make_pair("Version"s, nlohmann::json(3)),
251 std::make_pair("Name"s, nlohmann::json(ReportParams().reportName())),
252 std::make_pair("ReportingType",
253 nlohmann::json(ReportParams().reportingType())),
254 std::make_pair("EmitsReadingsUpdate",
255 nlohmann::json(ReportParams().emitReadingUpdate())),
256 std::make_pair(
257 "LogToMetricReportsCollection",
258 nlohmann::json(ReportParams().logToMetricReportCollection())),
259 std::make_pair("Interval",
260 nlohmann::json(ReportParams().interval().count())),
261 std::make_pair(
262 "ReadingParameters",
263 nlohmann::json(
264 {{{tstring::SensorPath::str(),
Krzysztof Grobelny9f9ff902021-03-05 14:57:53 +0000265 {{"service", "service0"}, {"path", "path0"}}},
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000266 {tstring::OperationType::str(), OperationType::single},
267 {tstring::Id::str(), "id0"},
Krzysztof Grobelny9f9ff902021-03-05 14:57:53 +0000268 {tstring::MetricMetadata::str(), "metadata0"}},
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000269 {{tstring::SensorPath::str(),
Krzysztof Grobelny9f9ff902021-03-05 14:57:53 +0000270 {{"service", "service1"}, {"path", "path1"}}},
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000271 {tstring::OperationType::str(), OperationType::max},
272 {tstring::Id::str(), "id1"},
Krzysztof Grobelny9f9ff902021-03-05 14:57:53 +0000273 {tstring::MetricMetadata::str(), "metadata1"}},
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000274 {{tstring::SensorPath::str(),
Krzysztof Grobelny9f9ff902021-03-05 14:57:53 +0000275 {{"service", "service2"}, {"path", "path2"}}},
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000276 {tstring::OperationType::str(), OperationType::min},
277 {tstring::Id::str(), "id2"},
Krzysztof Grobelny9f9ff902021-03-05 14:57:53 +0000278 {tstring::MetricMetadata::str(), "metadata2"}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100279
280TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
281{
282 sut = makeReport(ReportParams());
283
284 {
285 InSequence seq;
286 EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
287 EXPECT_CALL(checkPoint, Call());
288 EXPECT_CALL(storageMock, store(to_file_path(sut->getName()), _))
289 .WillOnce(SaveArg<1>(&storedConfiguration));
290 }
291
292 setProperty(sut->getPath(), "Persistency", false);
293 checkPoint.Call();
294 setProperty(sut->getPath(), "Persistency", true);
295
296 const auto& [key, value] = GetParam();
297
298 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
299}
300
301TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
302{
303 EXPECT_CALL(storageMock,
304 store(to_file_path(ReportParams().reportName()), _))
305 .WillOnce(SaveArg<1>(&storedConfiguration));
306
307 sut = makeReport(ReportParams());
308
309 const auto& [key, value] = GetParam();
310
311 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
312}
313
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200314class TestReportValidNames :
315 public TestReport,
316 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200317{
318 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200319 void SetUp() override
320 {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200321};
322
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200323INSTANTIATE_TEST_SUITE_P(
324 ValidNames, TestReportValidNames,
325 Values(ReportParams().reportName("Valid_1"),
326 ReportParams().reportName("Valid_1/Valid_2"),
327 ReportParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200328
329TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
330{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200331 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200332}
333
334class TestReportInvalidNames :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200335 public TestReport,
336 public WithParamInterface<ReportParams>
337{
338 public:
339 void SetUp() override
340 {}
341};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200342
343INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidNames,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200344 Values(ReportParams().reportName("/"),
345 ReportParams().reportName("/Invalid"),
346 ReportParams().reportName("Invalid/"),
347 ReportParams().reportName("Invalid/Invalid/"),
348 ReportParams().reportName("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200349
350TEST_P(TestReportInvalidNames, reportCtorThrowOnInvalidName)
351{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200352 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
353}
354
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100355TEST_F(TestReportInvalidNames, reportCtorThrowOnInvalidNameAndNoStoreIsCalled)
356{
357 EXPECT_CALL(storageMock, store).Times(0);
358 EXPECT_THROW(makeReport(ReportParams().reportName("/Invalid")),
359 sdbusplus::exception::SdBusError);
360}
361
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200362class TestReportAllReportTypes :
363 public TestReport,
364 public WithParamInterface<ReportParams>
365{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200366 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200367 void SetUp() override
368 {
369 sut = makeReport(GetParam());
370 }
371};
372
373INSTANTIATE_TEST_SUITE_P(_, TestReportAllReportTypes,
374 Values(ReportParams().reportingType("OnRequest"),
375 ReportParams().reportingType("OnChange"),
376 ReportParams().reportingType("Periodic")));
377
378TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
379{
380 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
381 Eq(GetParam().reportingType()));
382}
383
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100384TEST_P(TestReportAllReportTypes, updateReadingsCallUpdateReadingsProperty)
385{
386 const uint64_t expectedTime = std::time(0);
387
388 sut->updateReadings();
389
390 const auto [timestamp, readings] =
391 getProperty<Readings>(sut->getPath(), "Readings");
392
393 EXPECT_THAT(timestamp, Ge(expectedTime));
394}
395
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100396class TestReportOnRequestType : public TestReport
397{
398 void SetUp() override
399 {
400 sut = makeReport(ReportParams().reportingType("OnRequest"));
401 }
402};
403
404TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
405{
406 const uint64_t expectedTime = std::time(0);
407
408 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
409
410 const auto [timestamp, readings] =
411 getProperty<Readings>(sut->getPath(), "Readings");
412
413 EXPECT_THAT(timestamp, Ge(expectedTime));
414}
415
416TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
417{
418 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
419
420 const auto [timestamp, readings] =
421 getProperty<Readings>(sut->getPath(), "Readings");
422
423 EXPECT_THAT(readings,
424 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000425 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
426 std::make_tuple("aaa"s, "bbb"s, 100.7, 21u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100427}
428
429class TestReportNonOnRequestType :
430 public TestReport,
431 public WithParamInterface<ReportParams>
432{
433 void SetUp() override
434 {
435 sut = makeReport(GetParam());
436 }
437};
438
439INSTANTIATE_TEST_SUITE_P(_, TestReportNonOnRequestType,
440 Values(ReportParams().reportingType("Periodic"),
441 ReportParams().reportingType("OnChange")));
442
443TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
444{
445 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
446
447 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
448 Eq(Readings{}));
449}
450
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200451class TestReportNonPeriodicReport :
452 public TestReport,
453 public WithParamInterface<ReportParams>
454{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200455 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200456 void SetUp() override
457 {
458 sut = makeReport(GetParam());
459 }
460};
461
462INSTANTIATE_TEST_SUITE_P(_, TestReportNonPeriodicReport,
463 Values(ReportParams().reportingType("OnRequest"),
464 ReportParams().reportingType("OnChange")));
465
466TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
467{
468 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
469
470 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
471 Eq(Readings{}));
472}
473
474class TestReportPeriodicReport : public TestReport
475{
476 void SetUp() override
477 {
478 sut = makeReport(ReportParams().reportingType("Periodic"));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200479 }
480};
481
482TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
483{
484 const uint64_t expectedTime = std::time(0);
485 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
486
487 const auto [timestamp, readings] =
488 getProperty<Readings>(sut->getPath(), "Readings");
489
490 EXPECT_THAT(timestamp, Ge(expectedTime));
491}
492
493TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
494{
495 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
496
497 const auto [timestamp, readings] =
498 getProperty<Readings>(sut->getPath(), "Readings");
499
500 EXPECT_THAT(readings,
501 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000502 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
503 std::make_tuple("aaa"s, "bbb"s, 100.7, 21u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200504}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100505
506class TestReportInitialization : public TestReport
507{
508 public:
509 void SetUp() override
510 {}
511
512 void monitorProc(sdbusplus::message::message& msg)
513 {
514 std::string iface;
515 std::vector<std::pair<std::string, std::variant<Readings>>>
516 changed_properties;
517 std::vector<std::string> invalidated_properties;
518
519 msg.read(iface, changed_properties, invalidated_properties);
520
521 if (iface == Report::reportIfaceName)
522 {
523 for (const auto& [name, value] : changed_properties)
524 {
525 if (name == "Readings")
526 {
527 readingsUpdated.Call();
528 }
529 }
530 }
531 }
532
533 void makeMonitor()
534 {
535 monitor = std::make_unique<sdbusplus::bus::match::match>(
536 *DbusEnvironment::getBus(),
537 sdbusplus::bus::match::rules::propertiesChanged(
538 sut->getPath(), Report::reportIfaceName),
539 [this](auto& msg) { monitorProc(msg); });
540 }
541
542 std::unique_ptr<sdbusplus::bus::match::match> monitor;
543 MockFunction<void()> readingsUpdated;
544};
545
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100546TEST_F(TestReportInitialization, metricsAreInitializedWhenConstructed)
547{
548 for (auto& metric : metricMocks)
549 {
550 EXPECT_CALL(*metric, initialize());
551 }
552
553 sut = makeReport(ReportParams());
554}
555
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200556TEST_F(TestReportInitialization,
557 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100558{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200559 EXPECT_CALL(readingsUpdated, Call())
560 .WillOnce(
561 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
562
563 const auto elapsed = DbusEnvironment::measureTime([this] {
564 sut = makeReport(
565 defaultParams.reportingType("Periodic").emitReadingUpdate(true));
566 makeMonitor();
567 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
568 });
569
570 EXPECT_THAT(elapsed, AllOf(Ge(defaultParams.interval()),
571 Lt(defaultParams.interval() * 2)));
572}
573
574TEST_F(TestReportInitialization,
575 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
576{
577 EXPECT_CALL(readingsUpdated, Call()).Times(0);
578
579 sut = makeReport(
580 defaultParams.reportingType("Periodic").emitReadingUpdate(false));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100581 makeMonitor();
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200582 DbusEnvironment::sleepFor(defaultParams.interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100583}