blob: 9fbd30b30f672356a38c957aec313a50af0a8c0d [file] [log] [blame]
Brad Bishop13fd8722017-05-15 12:44:01 -04001#include "propertywatchtest.hpp"
2
Patrick Venture3d6d3182018-08-31 09:33:09 -07003#include "propertywatchimpl.hpp"
4
5#include <array>
Matthew Barth39c82152019-10-17 15:47:29 -05006#include <functional>
Patrick Venture3d6d3182018-08-31 09:33:09 -07007
Brad Bishop13fd8722017-05-15 12:44:01 -04008using namespace std::string_literals;
9using namespace phosphor::dbus::monitoring;
10
Brad Bishopd1eac882018-03-29 10:34:05 -040011const std::array<std::string, 4> paths = {
Brad Bishop13fd8722017-05-15 12:44:01 -040012 "/xyz/openbmc_project/testing/inst1"s,
13 "/xyz/openbmc_project/testing/inst2"s,
14 "/xyz/openbmc_project/testing/inst3"s,
15 "/xyz/openbmc_project/testing/inst4"s,
16};
17
Brad Bishopd1eac882018-03-29 10:34:05 -040018const std::array<std::string, 2> interfaces = {
Brad Bishop13fd8722017-05-15 12:44:01 -040019 "xyz.openbmc_project.Iface1"s,
20 "xyz.openbmc_project.Iface2"s,
21};
22
Brad Bishopd1eac882018-03-29 10:34:05 -040023const std::array<std::string, 2> properties = {
Brad Bishop13fd8722017-05-15 12:44:01 -040024 "Value1"s,
25 "Value2"s,
26};
27
28const std::string meta;
29
Brad Bishopd1eac882018-03-29 10:34:05 -040030std::array<std::tuple<any_ns::any, any_ns::any>, 8> storage = {};
Brad Bishop13fd8722017-05-15 12:44:01 -040031
Brad Bishopd1eac882018-03-29 10:34:05 -040032const PropertyIndex watchIndex = {
Brad Bishop13fd8722017-05-15 12:44:01 -040033 {
Brad Bishopd1eac882018-03-29 10:34:05 -040034 {PropertyIndex::key_type{paths[0], interfaces[0], properties[0]},
35 PropertyIndex::mapped_type{meta, meta, storage[0]}},
36 {PropertyIndex::key_type{paths[0], interfaces[1], properties[1]},
37 PropertyIndex::mapped_type{meta, meta, storage[1]}},
38 {PropertyIndex::key_type{paths[1], interfaces[0], properties[0]},
39 PropertyIndex::mapped_type{meta, meta, storage[2]}},
40 {PropertyIndex::key_type{paths[1], interfaces[1], properties[1]},
41 PropertyIndex::mapped_type{meta, meta, storage[3]}},
42 {PropertyIndex::key_type{paths[2], interfaces[0], properties[0]},
43 PropertyIndex::mapped_type{meta, meta, storage[4]}},
44 {PropertyIndex::key_type{paths[2], interfaces[1], properties[1]},
45 PropertyIndex::mapped_type{meta, meta, storage[5]}},
46 {PropertyIndex::key_type{paths[3], interfaces[0], properties[0]},
47 PropertyIndex::mapped_type{meta, meta, storage[6]}},
48 {PropertyIndex::key_type{paths[3], interfaces[1], properties[1]},
49 PropertyIndex::mapped_type{meta, meta, storage[7]}},
Brad Bishop13fd8722017-05-15 12:44:01 -040050 },
51};
52
Patrick Venture3d6d3182018-08-31 09:33:09 -070053template <typename T>
Matthew Barth52881362019-10-17 15:40:43 -050054struct Values
Brad Bishopd1eac882018-03-29 10:34:05 -040055{
56};
Patrick Venture3d6d3182018-08-31 09:33:09 -070057template <>
Matthew Barth52881362019-10-17 15:40:43 -050058struct Values<uint8_t>
Brad Bishop13fd8722017-05-15 12:44:01 -040059{
60 static auto& get(size_t i)
61 {
Brad Bishopd1eac882018-03-29 10:34:05 -040062 static const std::array<uint8_t, 8> values = {
Brad Bishop13fd8722017-05-15 12:44:01 -040063 {0, 1, 2, 3, 4, 5, 6, 7},
64 };
65 return values[i];
66 }
67};
68
Patrick Venture3d6d3182018-08-31 09:33:09 -070069template <>
Matthew Barth52881362019-10-17 15:40:43 -050070struct Values<uint16_t>
Brad Bishop13fd8722017-05-15 12:44:01 -040071{
72 static auto& get(size_t i)
73 {
Brad Bishopd1eac882018-03-29 10:34:05 -040074 static const std::array<uint16_t, 8> values = {
Brad Bishop13fd8722017-05-15 12:44:01 -040075 {88, 77, 66, 55, 44, 33, 22, 11},
76 };
77 return values[i];
78 }
79};
80
Patrick Venture3d6d3182018-08-31 09:33:09 -070081template <>
Matthew Barth52881362019-10-17 15:40:43 -050082struct Values<uint32_t>
Brad Bishop13fd8722017-05-15 12:44:01 -040083{
84 static auto& get(size_t i)
85 {
Brad Bishopd1eac882018-03-29 10:34:05 -040086 static const std::array<uint32_t, 8> values = {
Brad Bishop13fd8722017-05-15 12:44:01 -040087 {0xffffffff, 1, 3, 0, 5, 7, 9, 0xffffffff},
88 };
89 return values[i];
90 }
91};
92
Patrick Venture3d6d3182018-08-31 09:33:09 -070093template <>
Matthew Barth52881362019-10-17 15:40:43 -050094struct Values<uint64_t>
Brad Bishop13fd8722017-05-15 12:44:01 -040095{
96 static auto& get(size_t i)
97 {
Brad Bishopd1eac882018-03-29 10:34:05 -040098 static const std::array<uint64_t, 8> values = {
Brad Bishop13fd8722017-05-15 12:44:01 -040099 {0xffffffffffffffff, 3, 7, 12234, 0, 3, 9, 0xffffffff},
100 };
101 return values[i];
102 }
103};
104
Patrick Venture3d6d3182018-08-31 09:33:09 -0700105template <>
Matthew Barth52881362019-10-17 15:40:43 -0500106struct Values<std::string>
Brad Bishop13fd8722017-05-15 12:44:01 -0400107{
108 static auto& get(size_t i)
109 {
Brad Bishopd1eac882018-03-29 10:34:05 -0400110 static const std::array<std::string, 8> values = {
Brad Bishop13fd8722017-05-15 12:44:01 -0400111 {""s, "foo"s, "bar"s, "baz"s, "hello"s, "string", "\x2\x3", "\\"},
112 };
113 return values[i];
114 }
115};
116
Patrick Venture3d6d3182018-08-31 09:33:09 -0700117template <typename T>
Matthew Barth39c82152019-10-17 15:47:29 -0500118void nonFilteredCheck(const any_ns::any& value, const size_t ndx)
119{
120 ASSERT_EQ(value.empty(), false);
121 ASSERT_EQ(any_ns::any_cast<T>(value), Values<T>::get(ndx));
122}
123
124template <typename T>
Matthew Barth9b502142019-10-17 15:53:53 -0500125struct FilteredValues
126{
127};
128
129template <>
130struct FilteredValues<uint8_t>
131{
132 static auto& opFilters()
133 {
134 static std::unique_ptr<OperandFilters<uint8_t>> filters =
135 std::make_unique<OperandFilters<uint8_t>>(
136 std::vector<std::function<bool(uint8_t)>>{
137 [](const auto& value) { return value < 4; }});
138 return filters;
139 }
140 static auto& expected(size_t i)
141 {
142 static const std::array<any_ns::any, 8> values = {
143 {any_ns::any(uint8_t(0)), any_ns::any(uint8_t(1)),
144 any_ns::any(uint8_t(2)), any_ns::any(uint8_t(3)), any_ns::any(),
145 any_ns::any(), any_ns::any(), any_ns::any()}};
146 return values[i];
147 }
148};
149
150template <>
151struct FilteredValues<uint16_t>
152{
153 static auto& opFilters()
154 {
155 static std::unique_ptr<OperandFilters<uint16_t>> filters =
156 std::make_unique<OperandFilters<uint16_t>>(
157 std::vector<std::function<bool(uint16_t)>>{
158 [](const auto& value) { return value > 44; },
159 [](const auto& value) { return value != 88; }});
160 return filters;
161 }
162 static auto& expected(size_t i)
163 {
164 static const std::array<any_ns::any, 8> values = {
165 {any_ns::any(), any_ns::any(uint16_t(77)),
166 any_ns::any(uint16_t(66)), any_ns::any(uint16_t(55)),
167 any_ns::any(), any_ns::any(), any_ns::any(), any_ns::any()}};
168 return values[i];
169 }
170};
171
172template <>
173struct FilteredValues<uint32_t>
174{
175 static auto& opFilters()
176 {
177 static std::unique_ptr<OperandFilters<uint32_t>> filters =
178 std::make_unique<OperandFilters<uint32_t>>(
179 std::vector<std::function<bool(uint32_t)>>{
180 [](const auto& value) { return value != 0xffffffff; },
181 [](const auto& value) { return value != 0; }});
182 return filters;
183 }
184 static auto& expected(size_t i)
185 {
186 static const std::array<any_ns::any, 8> values = {
187 {any_ns::any(), any_ns::any(uint32_t(1)), any_ns::any(uint32_t(3)),
188 any_ns::any(), any_ns::any(uint32_t(5)), any_ns::any(uint32_t(7)),
189 any_ns::any(uint32_t(9)), any_ns::any()}};
190 return values[i];
191 }
192};
193
194template <>
195struct FilteredValues<uint64_t>
196{
197 static auto& opFilters()
198 {
199 static std::unique_ptr<OperandFilters<uint64_t>> filters =
200 std::make_unique<OperandFilters<uint64_t>>(
201 std::vector<std::function<bool(uint64_t)>>{
202 [](const auto& value) { return (value % 3) != 0; }});
203 return filters;
204 }
205 static auto& expected(size_t i)
206 {
207 static const std::array<any_ns::any, 8> values = {
208 {any_ns::any(), any_ns::any(), any_ns::any(uint64_t(7)),
209 any_ns::any(), any_ns::any(), any_ns::any(), any_ns::any(),
210 any_ns::any()}};
211 return values[i];
212 }
213};
214
215template <>
216struct FilteredValues<std::string>
217{
218 static auto& opFilters()
219 {
220 static std::unique_ptr<OperandFilters<std::string>> filters =
221 std::make_unique<OperandFilters<std::string>>(
222 std::vector<std::function<bool(std::string)>>{
223 [](const auto& value) { return value != ""s; },
224 [](const auto& value) { return value != "string"s; }});
225 return filters;
226 }
227 static auto& expected(size_t i)
228 {
229 static const std::array<any_ns::any, 8> values = {
230 {any_ns::any(), any_ns::any("foo"s), any_ns::any("bar"s),
231 any_ns::any("baz"s), any_ns::any("hello"s), any_ns::any(),
232 any_ns::any("\x2\x3"s), any_ns::any("\\"s)}};
233 return values[i];
234 }
235};
236
237template <typename T>
238void filteredCheck(const any_ns::any& value, const size_t ndx)
239{
240 ASSERT_EQ(value.empty(), FilteredValues<T>::expected(ndx).empty());
241 if (!value.empty())
242 {
243 ASSERT_EQ(any_ns::any_cast<T>(value),
244 any_ns::any_cast<T>(FilteredValues<T>::expected(ndx)));
245 }
246}
247
248template <typename T>
Matthew Barth39c82152019-10-17 15:47:29 -0500249void testStart(
Matthew Barth9b502142019-10-17 15:53:53 -0500250 std::function<void(const any_ns::any&, const size_t)>&& checkState,
251 OperandFilters<T>* opFilters = nullptr)
Brad Bishop13fd8722017-05-15 12:44:01 -0400252{
Brad Bishop13fd8722017-05-15 12:44:01 -0400253 using ::testing::_;
Patrick Ventureac803952018-08-31 09:28:31 -0700254 using ::testing::Return;
Brad Bishop13fd8722017-05-15 12:44:01 -0400255
256 MockDBusInterface dbus;
257 MockDBusInterface::instance(dbus);
258
259 const std::vector<std::string> expectedMapperInterfaces;
Matthew Barth9b502142019-10-17 15:53:53 -0500260 PropertyWatchOfType<T, MockDBusInterface> watch(watchIndex, opFilters);
Brad Bishop13fd8722017-05-15 12:44:01 -0400261
262 auto ndx = static_cast<size_t>(0);
263 for (const auto& o : convert(watchIndex))
264 {
265 const auto& path = o.first.get();
266 const auto& interfaces = o.second;
267 std::vector<std::string> mapperResponse;
Brad Bishopd1eac882018-03-29 10:34:05 -0400268 std::transform(interfaces.begin(), interfaces.end(),
269 std::back_inserter(mapperResponse),
270 // *INDENT-OFF*
271 [](const auto& item) { return item.first; });
Brad Bishop13fd8722017-05-15 12:44:01 -0400272 // *INDENT-ON*
Brad Bishopd1eac882018-03-29 10:34:05 -0400273 EXPECT_CALL(dbus, mapperGetObject(MAPPER_BUSNAME, MAPPER_PATH,
274 MAPPER_INTERFACE, "GetObject", path,
275 expectedMapperInterfaces))
276 .WillOnce(Return(GetObject({{"", mapperResponse}})));
Brad Bishop13fd8722017-05-15 12:44:01 -0400277 EXPECT_CALL(
Brad Bishopd1eac882018-03-29 10:34:05 -0400278 dbus, fwdAddMatch(
Matthew Barthf79fc092019-10-10 14:01:04 -0500279 sdbusplus::bus::match::rules::interfacesAdded(path), _));
Brad Bishop13fd8722017-05-15 12:44:01 -0400280 for (const auto& i : interfaces)
281 {
282 const auto& interface = i.first.get();
283 const auto& properties = i.second;
284 EXPECT_CALL(
285 dbus,
Matthew Barthf79fc092019-10-10 14:01:04 -0500286 fwdAddMatch(sdbusplus::bus::match::rules::propertiesChanged(
287 path, interface),
288 _));
Brad Bishop13fd8722017-05-15 12:44:01 -0400289
290 PropertiesChanged<T> serviceResponse;
291 for (const auto& p : properties)
292 {
Matthew Barth52881362019-10-17 15:40:43 -0500293 serviceResponse[p] = Values<T>::get(ndx);
Brad Bishop13fd8722017-05-15 12:44:01 -0400294 ++ndx;
295 }
296 Expect<T>::getProperties(dbus, path, interface)
Brad Bishopd1eac882018-03-29 10:34:05 -0400297 .WillOnce(Return(serviceResponse));
Brad Bishop13fd8722017-05-15 12:44:01 -0400298 }
299 }
300
301 watch.start();
302
303 ndx = 0;
304 for (auto s : storage)
305 {
Matthew Barth39c82152019-10-17 15:47:29 -0500306 checkState(std::get<valueIndex>(s), ndx);
Brad Bishop13fd8722017-05-15 12:44:01 -0400307 ++ndx;
308 }
309
310 // Make sure start logic only runs the first time.
311 watch.start();
312}
313
314TEST(PropertyWatchTest, TestStart)
315{
Matthew Barth39c82152019-10-17 15:47:29 -0500316 testStart<uint8_t>(nonFilteredCheck<uint8_t>);
317 testStart<uint16_t>(nonFilteredCheck<uint16_t>);
318 testStart<uint32_t>(nonFilteredCheck<uint32_t>);
319 testStart<uint64_t>(nonFilteredCheck<uint64_t>);
320 testStart<std::string>(nonFilteredCheck<std::string>);
Brad Bishop13fd8722017-05-15 12:44:01 -0400321}
322
Matthew Barth9b502142019-10-17 15:53:53 -0500323TEST(PropertyWatchTest, TestFilters)
324{
325 testStart<uint8_t>(filteredCheck<uint8_t>,
326 FilteredValues<uint8_t>::opFilters().get());
327 testStart<uint16_t>(filteredCheck<uint16_t>,
328 FilteredValues<uint16_t>::opFilters().get());
329 testStart<uint32_t>(filteredCheck<uint32_t>,
330 FilteredValues<uint32_t>::opFilters().get());
331 testStart<uint64_t>(filteredCheck<uint64_t>,
332 FilteredValues<uint64_t>::opFilters().get());
333 testStart<std::string>(filteredCheck<std::string>,
334 FilteredValues<std::string>::opFilters().get());
335}
336
Brad Bishop13fd8722017-05-15 12:44:01 -0400337MockDBusInterface* MockDBusInterface::ptr = nullptr;