blob: bb0f4c596b75b2bcfbacaac2524f948d04a36c71 [file] [log] [blame]
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +02001#include "dbus_environment.hpp"
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +02002#include "mocks/metric_mock.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +02003#include "mocks/report_manager_mock.hpp"
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +02004#include "params/report_params.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +02005#include "report.hpp"
6#include "report_manager.hpp"
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +02007#include "utils/conv_container.hpp"
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +02008
9#include <sdbusplus/exception.hpp>
10
11using namespace testing;
12using namespace std::literals::string_literals;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020013using namespace std::chrono_literals;
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020014
15class TestReport : public Test
16{
17 public:
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020018 bool defaultEmitReadingSignal = true;
19 bool defaultLogToMetricReportCollection = true;
20 uint64_t defaultInterval = ReportManager::minInterval.count();
21 ReadingParameters defaultReadingParams = {};
22
23 std::unique_ptr<ReportManagerMock> reportManagerMock =
24 std::make_unique<StrictMock<ReportManagerMock>>();
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020025 std::vector<std::shared_ptr<MetricMock>> metricMocks = {
26 std::make_shared<NiceMock<MetricMock>>(),
27 std::make_shared<NiceMock<MetricMock>>(),
28 std::make_shared<NiceMock<MetricMock>>()};
29 std::unique_ptr<Report> sut;
30
31 void SetUp() override
32 {
33 sut = makeReport(ReportParams());
34 }
35
36 std::unique_ptr<Report> makeReport(const ReportParams& params)
37 {
38 return std::make_unique<Report>(
39 DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
40 params.reportName(), params.reportingType(),
41 defaultEmitReadingSignal, defaultLogToMetricReportCollection,
42 std::chrono::milliseconds(defaultInterval), defaultReadingParams,
43 *reportManagerMock,
44 utils::convContainer<std::shared_ptr<interfaces::Metric>>(
45 metricMocks));
46 }
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +020047
48 template <class T>
49 static T getProperty(const std::string& path, const std::string& property)
50 {
51 std::promise<T> propertyPromise;
52 sdbusplus::asio::getProperty<T>(
53 *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
54 Report::reportIfaceName, property,
55 [&propertyPromise](boost::system::error_code ec) {
56 EXPECT_THAT(static_cast<bool>(ec), ::testing::Eq(false));
57 propertyPromise.set_value(T{});
58 },
59 [&propertyPromise](T t) { propertyPromise.set_value(t); });
60 return DbusEnvironment::waitForFuture(propertyPromise.get_future())
61 .value_or(T{});
62 }
63
64 template <class T>
65 static boost::system::error_code setProperty(const std::string& path,
66 const std::string& property,
67 const T& newValue)
68 {
69 std::promise<boost::system::error_code> setPromise;
70 sdbusplus::asio::setProperty(
71 *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
72 Report::reportIfaceName, property, std::move(newValue),
73 [&setPromise](boost::system::error_code ec) {
74 setPromise.set_value(ec);
75 },
76 [&setPromise]() {
77 setPromise.set_value(boost::system::error_code{});
78 });
79 return DbusEnvironment::waitForFuture(setPromise.get_future())
80 .value_or(boost::system::error_code{});
81 }
82
83 boost::system::error_code deleteReport(const std::string& path)
84 {
85 std::promise<boost::system::error_code> deleteReportPromise;
86 DbusEnvironment::getBus()->async_method_call(
87 [&deleteReportPromise](boost::system::error_code ec) {
88 deleteReportPromise.set_value(ec);
89 },
90 DbusEnvironment::serviceName(), path, Report::deleteIfaceName,
91 "Delete");
92 return DbusEnvironment::waitForFuture(deleteReportPromise.get_future())
93 .value_or(boost::system::error_code{});
94 }
95};
96
97TEST_F(TestReport, verifyIfPropertiesHaveValidValue)
98{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +020099 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200100 Eq(defaultInterval));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200101 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(false));
102 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200103 Eq(defaultEmitReadingSignal));
104 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200105 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200106 Eq(defaultLogToMetricReportCollection));
107 EXPECT_THAT(
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200108 getProperty<ReadingParameters>(sut->getPath(), "ReadingParameters"),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200109 Eq(defaultReadingParams));
110}
111
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200112TEST_F(TestReport, readingsAreInitialyEmpty)
113{
114 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
115 Eq(Readings{}));
116}
117
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200118TEST_F(TestReport, setIntervalWithValidValue)
119{
120 uint64_t newValue = defaultInterval + 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200121 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200122 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200123 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
124 Eq(newValue));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200125}
126
127TEST_F(TestReport, settingIntervalWithInvalidValueDoesNotChangeProperty)
128{
129 uint64_t newValue = defaultInterval - 1;
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200130 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200131 Eq(boost::system::errc::success));
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200132 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200133 Eq(defaultInterval));
134}
135
136TEST_F(TestReport, deleteReport)
137{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200138 EXPECT_CALL(*reportManagerMock, removeReport(sut.get()));
139 auto ec = deleteReport(sut->getPath());
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200140 EXPECT_THAT(ec, Eq(boost::system::errc::success));
141}
142
143TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor)
144{
145 auto ec = deleteReport(Report::reportDir + "NonExisting"s);
146 EXPECT_THAT(ec.value(), Eq(EBADR));
147}
148
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200149class TestReportValidNames :
150 public TestReport,
151 public WithParamInterface<ReportParams>
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200152{
153 public:
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200154 void SetUp() override
155 {}
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200156};
157
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200158INSTANTIATE_TEST_SUITE_P(
159 ValidNames, TestReportValidNames,
160 Values(ReportParams().reportName("Valid_1"),
161 ReportParams().reportName("Valid_1/Valid_2"),
162 ReportParams().reportName("Valid_1/Valid_2/Valid_3")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200163
164TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName)
165{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200166 EXPECT_NO_THROW(makeReport(GetParam()));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200167}
168
169class TestReportInvalidNames :
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200170 public TestReport,
171 public WithParamInterface<ReportParams>
172{
173 public:
174 void SetUp() override
175 {}
176};
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200177
178INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidNames,
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200179 Values(ReportParams().reportName("/"),
180 ReportParams().reportName("/Invalid"),
181 ReportParams().reportName("Invalid/"),
182 ReportParams().reportName("Invalid/Invalid/"),
183 ReportParams().reportName("Invalid?")));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200184
185TEST_P(TestReportInvalidNames, reportCtorThrowOnInvalidName)
186{
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +0200187 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError);
188}
189
190class TestReportAllReportTypes :
191 public TestReport,
192 public WithParamInterface<ReportParams>
193{
194 void SetUp() override
195 {
196 sut = makeReport(GetParam());
197 }
198};
199
200INSTANTIATE_TEST_SUITE_P(_, TestReportAllReportTypes,
201 Values(ReportParams().reportingType("OnRequest"),
202 ReportParams().reportingType("OnChange"),
203 ReportParams().reportingType("Periodic")));
204
205TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
206{
207 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
208 Eq(GetParam().reportingType()));
209}
210
211class TestReportNonPeriodicReport :
212 public TestReport,
213 public WithParamInterface<ReportParams>
214{
215 void SetUp() override
216 {
217 sut = makeReport(GetParam());
218 }
219};
220
221INSTANTIATE_TEST_SUITE_P(_, TestReportNonPeriodicReport,
222 Values(ReportParams().reportingType("OnRequest"),
223 ReportParams().reportingType("OnChange")));
224
225TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
226{
227 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
228
229 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"),
230 Eq(Readings{}));
231}
232
233class TestReportPeriodicReport : public TestReport
234{
235 void SetUp() override
236 {
237 sut = makeReport(ReportParams().reportingType("Periodic"));
238
239 ASSERT_THAT(metricMocks, SizeIs(Ge(2)));
240 ON_CALL(*metricMocks[0], getReadings())
241 .WillByDefault(ReturnRefOfCopy(std::vector<MetricValue>(
242 {MetricValue{"a", "b", 17.1, 114},
243 MetricValue{"aaa", "bbb", 21.7, 100}})));
244 ON_CALL(*metricMocks[1], getReadings())
245 .WillByDefault(ReturnRefOfCopy(
246 std::vector<MetricValue>({MetricValue{"aa", "bb", 42.0, 74}})));
247 }
248};
249
250TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires)
251{
252 const uint64_t expectedTime = std::time(0);
253 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
254
255 const auto [timestamp, readings] =
256 getProperty<Readings>(sut->getPath(), "Readings");
257
258 EXPECT_THAT(timestamp, Ge(expectedTime));
259}
260
261TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires)
262{
263 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms);
264
265 const auto [timestamp, readings] =
266 getProperty<Readings>(sut->getPath(), "Readings");
267
268 EXPECT_THAT(readings,
269 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u),
270 std::make_tuple("aaa"s, "bbb"s, 21.7, 100u),
271 std::make_tuple("aa"s, "bb"s, 42.0, 74u)));
Wludzik, Jozef2f9f9b82020-10-13 09:07:45 +0200272}