blob: ece4be8bb337d51f099db652dbada5c3b20eab00 [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 Grobelny753e4b32021-02-11 12:58:58 +000056 "id"s + id, "metadata"s + id, CollectionTimeScope::point,
57 CollectionDuration(0ms));
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +000058
59 ON_CALL(*metricMocks[i], dumpConfiguration())
60 .WillByDefault(Return(std::move(metricParameters)));
Wludzik, Jozefe2362792020-10-27 17:23:55 +010061 }
62 }
63
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020064 void SetUp() override
65 {
66 sut = makeReport(ReportParams());
67 }
68
Wludzik, Jozefe2362792020-10-27 17:23:55 +010069 static interfaces::JsonStorage::FilePath to_file_path(std::string name)
70 {
71 return interfaces::JsonStorage::FilePath(
72 std::to_string(std::hash<std::string>{}(name)));
73 }
74
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020075 std::unique_ptr<Report> makeReport(const ReportParams& params)
76 {
77 return std::make_unique<Report>(
78 DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
79 params.reportName(), params.reportingType(),
Wludzik, Jozefe2362792020-10-27 17:23:55 +010080 params.emitReadingUpdate(), params.logToMetricReportCollection(),
81 params.interval(), params.readingParameters(), *reportManagerMock,
82 storageMock,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020083 utils::convContainer<std::shared_ptr<interfaces::Metric>>(
84 metricMocks));
85 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020086
87 template <class T>
88 static T getProperty(const std::string& path, const std::string& property)
89 {
Ed Tanous0e7ae5d2021-02-23 14:06:49 -080090 auto propertyPromise = std::promise<T>();
91 auto propertyFuture = propertyPromise.get_future();
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020092 sdbusplus::asio::getProperty<T>(
93 *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
94 Report::reportIfaceName, property,
Ed Tanous0e7ae5d2021-02-23 14:06:49 -080095 [&propertyPromise](const boost::system::error_code& ec, T t) {
96 if (ec)
97 {
98 utils::setException(propertyPromise, "GetProperty failed");
99 return;
100 }
101 propertyPromise.set_value(t);
102 });
103 return DbusEnvironment::waitForFuture(std::move(propertyFuture));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100104 }
105
106 boost::system::error_code call(const std::string& path,
107 const std::string& interface,
108 const std::string& method)
109 {
110 std::promise<boost::system::error_code> methodPromise;
111 DbusEnvironment::getBus()->async_method_call(
112 [&methodPromise](boost::system::error_code ec) {
113 methodPromise.set_value(ec);
114 },
115 DbusEnvironment::serviceName(), path, interface, method);
116 return DbusEnvironment::waitForFuture(methodPromise.get_future());
117 }
118
119 boost::system::error_code update(const std::string& path)
120 {
121 return call(path, Report::reportIfaceName, "Update");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200122 }
123
124 template <class T>
125 static boost::system::error_code setProperty(const std::string& path,
126 const std::string& property,
127 const T& newValue)
128 {
Ed Tanous0e7ae5d2021-02-23 14:06:49 -0800129 auto setPromise = std::promise<boost::system::error_code>();
130 auto future = setPromise.get_future();
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200131 sdbusplus::asio::setProperty(
132 *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
133 Report::reportIfaceName, property, std::move(newValue),
Ed Tanous0e7ae5d2021-02-23 14:06:49 -0800134 [setPromise =
135 std::move(setPromise)](boost::system::error_code ec) mutable {
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200136 setPromise.set_value(ec);
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200137 });
Ed Tanous0e7ae5d2021-02-23 14:06:49 -0800138 return DbusEnvironment::waitForFuture(std::move(future));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200139 }
140
141 boost::system::error_code deleteReport(const std::string& path)
142 {
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100143 return call(path, Report::deleteIfaceName, "Delete");
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200144 }
145};
146
147TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
148{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200149 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100150 Eq(defaultParams.interval().count()));
151 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200152 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100153 Eq(defaultParams.emitReadingUpdate()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200154 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200155 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100156 Eq(defaultParams.logToMetricReportCollection()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200157 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200158 getProperty<ReadingParameters>(sut->getPath(), "ReadingParameters"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100159 Eq(defaultParams.readingParameters()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200160}
161
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200162TEST_F(TestReport, readingsAreInitialyEmpty)
163{
164 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
165 Eq(Readings{}));
166}
167
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200168TEST_F(TestReport, setIntervalWithValidValue)
169{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100170 uint64_t newValue = defaultParams.interval().count() + 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200171 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200172 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200173 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
174 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200175}
176
177TEST_F(TestReport, settingIntervalWithInvalidValueDoesNotChangeProperty)
178{
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100179 uint64_t newValue = defaultParams.interval().count() - 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200180 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200181 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200182 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100183 Eq(defaultParams.interval().count()));
184}
185
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200186TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
187{
188 EXPECT_THAT(setProperty(sut->getPath(), "EmitsReadingsUpdate",
189 !defaultParams.emitReadingUpdate())
190 .value(),
191 Eq(boost::system::errc::read_only_file_system));
192 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
193 Eq(defaultParams.emitReadingUpdate()));
194}
195
196TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
197{
198 EXPECT_THAT(setProperty(sut->getPath(), "LogToMetricReportsCollection",
199 !defaultParams.logToMetricReportCollection())
200 .value(),
201 Eq(boost::system::errc::read_only_file_system));
202 EXPECT_THAT(
203 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
204 Eq(defaultParams.logToMetricReportCollection()));
205}
206
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100207TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
208{
209 EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
210
211 bool persistency = false;
212 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(),
213 Eq(boost::system::errc::success));
214 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"),
215 Eq(persistency));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200216}
217
218TEST_F(TestReport, deleteReport)
219{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200220 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
221 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200222 EXPECT_THAT(ec, Eq(boost::system::errc::success));
223}
224
225TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
226{
227 auto ec = deleteReport(Report::reportDir + "NonExisting"s);
228 EXPECT_THAT(ec.value(), Eq(EBADR));
229}
230
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100231TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage)
232{
233 EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
234 auto ec = deleteReport(sut->getPath());
235 EXPECT_THAT(ec, Eq(boost::system::errc::success));
236}
237
238class TestReportStore :
239 public TestReport,
240 public WithParamInterface<std::pair<std::string, nlohmann::json>>
241{
242 public:
243 void SetUp() override
244 {}
245
246 nlohmann::json storedConfiguration;
247};
248
249INSTANTIATE_TEST_SUITE_P(
250 _, TestReportStore,
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000251 Values(std::make_pair("Version"s, nlohmann::json(3)),
252 std::make_pair("Name"s, nlohmann::json(ReportParams().reportName())),
253 std::make_pair("ReportingType",
254 nlohmann::json(ReportParams().reportingType())),
255 std::make_pair("EmitsReadingsUpdate",
256 nlohmann::json(ReportParams().emitReadingUpdate())),
257 std::make_pair(
258 "LogToMetricReportsCollection",
259 nlohmann::json(ReportParams().logToMetricReportCollection())),
260 std::make_pair("Interval",
261 nlohmann::json(ReportParams().interval().count())),
262 std::make_pair(
263 "ReadingParameters",
264 nlohmann::json(
265 {{{tstring::SensorPath::str(),
Krzysztof Grobelny753e4b32021-02-11 12:58:58 +0000266 {{tstring::Service::str(), "service0"},
267 {tstring::Path::str(), "path0"}}},
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000268 {tstring::OperationType::str(), OperationType::single},
269 {tstring::Id::str(), "id0"},
Krzysztof Grobelny753e4b32021-02-11 12:58:58 +0000270 {tstring::MetricMetadata::str(), "metadata0"},
271 {tstring::CollectionTimeScope::str(),
272 CollectionTimeScope::point},
273 {tstring::CollectionDuration::str(), 0}},
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000274 {{tstring::SensorPath::str(),
Krzysztof Grobelny753e4b32021-02-11 12:58:58 +0000275 {{tstring::Service::str(), "service1"},
276 {tstring::Path::str(), "path1"}}},
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000277 {tstring::OperationType::str(), OperationType::max},
278 {tstring::Id::str(), "id1"},
Krzysztof Grobelny753e4b32021-02-11 12:58:58 +0000279 {tstring::MetricMetadata::str(), "metadata1"},
280 {tstring::CollectionTimeScope::str(),
281 CollectionTimeScope::point},
282 {tstring::CollectionDuration::str(), 0}},
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000283 {{tstring::SensorPath::str(),
Krzysztof Grobelny753e4b32021-02-11 12:58:58 +0000284 {{tstring::Service::str(), "service2"},
285 {tstring::Path::str(), "path2"}}},
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000286 {tstring::OperationType::str(), OperationType::min},
287 {tstring::Id::str(), "id2"},
Krzysztof Grobelny753e4b32021-02-11 12:58:58 +0000288 {tstring::MetricMetadata::str(), "metadata2"},
289 {tstring::CollectionTimeScope::str(),
290 CollectionTimeScope::point},
291 {tstring::CollectionDuration::str(), 0}}}))));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100292
293TEST_P(TestReportStore, settingPersistencyToTrueStoresReport)
294{
295 sut = makeReport(ReportParams());
296
297 {
298 InSequence seq;
299 EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
300 EXPECT_CALL(checkPoint, Call());
301 EXPECT_CALL(storageMock, store(to_file_path(sut->getName()), _))
302 .WillOnce(SaveArg<1>(&storedConfiguration));
303 }
304
305 setProperty(sut->getPath(), "Persistency", false);
306 checkPoint.Call();
307 setProperty(sut->getPath(), "Persistency", true);
308
309 const auto& [key, value] = GetParam();
310
311 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
312}
313
314TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated)
315{
316 EXPECT_CALL(storageMock,
317 store(to_file_path(ReportParams().reportName()), _))
318 .WillOnce(SaveArg<1>(&storedConfiguration));
319
320 sut = makeReport(ReportParams());
321
322 const auto& [key, value] = GetParam();
323
324 ASSERT_THAT(storedConfiguration.at(key), Eq(value));
325}
326
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200327class TestReportValidNames :
328 public TestReport,
329 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200330{
331 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200332 void SetUp() override
333 {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200334};
335
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200336INSTANTIATE_TEST_SUITE_P(
337 ValidNames, TestReportValidNames,
338 Values(ReportParams().reportName("Valid_1"),
339 ReportParams().reportName("Valid_1/Valid_2"),
340 ReportParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200341
342TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
343{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200344 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200345}
346
347class TestReportInvalidNames :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200348 public TestReport,
349 public WithParamInterface<ReportParams>
350{
351 public:
352 void SetUp() override
353 {}
354};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200355
356INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidNames,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200357 Values(ReportParams().reportName("/"),
358 ReportParams().reportName("/Invalid"),
359 ReportParams().reportName("Invalid/"),
360 ReportParams().reportName("Invalid/Invalid/"),
361 ReportParams().reportName("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200362
363TEST_P(TestReportInvalidNames, reportCtorThrowOnInvalidName)
364{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200365 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
366}
367
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100368TEST_F(TestReportInvalidNames, reportCtorThrowOnInvalidNameAndNoStoreIsCalled)
369{
370 EXPECT_CALL(storageMock, store).Times(0);
371 EXPECT_THROW(makeReport(ReportParams().reportName("/Invalid")),
372 sdbusplus::exception::SdBusError);
373}
374
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200375class TestReportAllReportTypes :
376 public TestReport,
377 public WithParamInterface<ReportParams>
378{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200379 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200380 void SetUp() override
381 {
382 sut = makeReport(GetParam());
383 }
384};
385
386INSTANTIATE_TEST_SUITE_P(_, TestReportAllReportTypes,
387 Values(ReportParams().reportingType("OnRequest"),
388 ReportParams().reportingType("OnChange"),
389 ReportParams().reportingType("Periodic")));
390
391TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
392{
393 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
394 Eq(GetParam().reportingType()));
395}
396
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100397TEST_P(TestReportAllReportTypes, updateReadingsCallUpdateReadingsProperty)
398{
399 const uint64_t expectedTime = std::time(0);
400
401 sut->updateReadings();
402
403 const auto [timestamp, readings] =
404 getProperty<Readings>(sut->getPath(), "Readings");
405
406 EXPECT_THAT(timestamp, Ge(expectedTime));
407}
408
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100409class TestReportOnRequestType : public TestReport
410{
411 void SetUp() override
412 {
413 sut = makeReport(ReportParams().reportingType("OnRequest"));
414 }
415};
416
417TEST_F(TestReportOnRequestType, updatesReadingTimestamp)
418{
419 const uint64_t expectedTime = std::time(0);
420
421 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
422
423 const auto [timestamp, readings] =
424 getProperty<Readings>(sut->getPath(), "Readings");
425
426 EXPECT_THAT(timestamp, Ge(expectedTime));
427}
428
429TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled)
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(readings,
437 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000438 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
439 std::make_tuple("aaa"s, "bbb"s, 100.7, 21u)));
Krzysztof Grobelnyf32f6fe2020-10-30 13:51:58 +0100440}
441
442class TestReportNonOnRequestType :
443 public TestReport,
444 public WithParamInterface<ReportParams>
445{
446 void SetUp() override
447 {
448 sut = makeReport(GetParam());
449 }
450};
451
452INSTANTIATE_TEST_SUITE_P(_, TestReportNonOnRequestType,
453 Values(ReportParams().reportingType("Periodic"),
454 ReportParams().reportingType("OnChange")));
455
456TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
457{
458 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success));
459
460 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
461 Eq(Readings{}));
462}
463
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200464class TestReportNonPeriodicReport :
465 public TestReport,
466 public WithParamInterface<ReportParams>
467{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200468 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200469 void SetUp() override
470 {
471 sut = makeReport(GetParam());
472 }
473};
474
475INSTANTIATE_TEST_SUITE_P(_, TestReportNonPeriodicReport,
476 Values(ReportParams().reportingType("OnRequest"),
477 ReportParams().reportingType("OnChange")));
478
479TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
480{
481 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
482
483 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
484 Eq(Readings{}));
485}
486
487class TestReportPeriodicReport : public TestReport
488{
489 void SetUp() override
490 {
491 sut = makeReport(ReportParams().reportingType("Periodic"));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200492 }
493};
494
495TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
496{
497 const uint64_t expectedTime = std::time(0);
498 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
499
500 const auto [timestamp, readings] =
501 getProperty<Readings>(sut->getPath(), "Readings");
502
503 EXPECT_THAT(timestamp, Ge(expectedTime));
504}
505
506TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
507{
508 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
509
510 const auto [timestamp, readings] =
511 getProperty<Readings>(sut->getPath(), "Readings");
512
513 EXPECT_THAT(readings,
514 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000515 std::make_tuple("aa"s, "bb"s, 42.0, 74u),
516 std::make_tuple("aaa"s, "bbb"s, 100.7, 21u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200517}
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100518
519class TestReportInitialization : public TestReport
520{
521 public:
522 void SetUp() override
523 {}
524
525 void monitorProc(sdbusplus::message::message& msg)
526 {
527 std::string iface;
528 std::vector<std::pair<std::string, std::variant<Readings>>>
529 changed_properties;
530 std::vector<std::string> invalidated_properties;
531
532 msg.read(iface, changed_properties, invalidated_properties);
533
534 if (iface == Report::reportIfaceName)
535 {
536 for (const auto& [name, value] : changed_properties)
537 {
538 if (name == "Readings")
539 {
540 readingsUpdated.Call();
541 }
542 }
543 }
544 }
545
546 void makeMonitor()
547 {
548 monitor = std::make_unique<sdbusplus::bus::match::match>(
549 *DbusEnvironment::getBus(),
550 sdbusplus::bus::match::rules::propertiesChanged(
551 sut->getPath(), Report::reportIfaceName),
552 [this](auto& msg) { monitorProc(msg); });
553 }
554
555 std::unique_ptr<sdbusplus::bus::match::match> monitor;
556 MockFunction<void()> readingsUpdated;
557};
558
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100559TEST_F(TestReportInitialization, metricsAreInitializedWhenConstructed)
560{
561 for (auto& metric : metricMocks)
562 {
563 EXPECT_CALL(*metric, initialize());
564 }
565
566 sut = makeReport(ReportParams());
567}
568
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200569TEST_F(TestReportInitialization,
570 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits)
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100571{
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200572 EXPECT_CALL(readingsUpdated, Call())
573 .WillOnce(
574 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
575
576 const auto elapsed = DbusEnvironment::measureTime([this] {
577 sut = makeReport(
578 defaultParams.reportingType("Periodic").emitReadingUpdate(true));
579 makeMonitor();
580 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
581 });
582
583 EXPECT_THAT(elapsed, AllOf(Ge(defaultParams.interval()),
584 Lt(defaultParams.interval() * 2)));
585}
586
587TEST_F(TestReportInitialization,
588 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits)
589{
590 EXPECT_CALL(readingsUpdated, Call()).Times(0);
591
592 sut = makeReport(
593 defaultParams.reportingType("Periodic").emitReadingUpdate(false));
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100594 makeMonitor();
Wludzik, Jozefb1ff1f62020-10-23 13:20:52 +0200595 DbusEnvironment::sleepFor(defaultParams.interval() * 2);
Wludzik, Jozefe2362792020-10-27 17:23:55 +0100596}