blob: b92dbec355b275f5bd086c18f2a9e7873bdac411 [file] [log] [blame]
Brad Bishop13fd8722017-05-15 12:44:01 -04001#include <array>
2#include "propertywatchimpl.hpp"
3#include "propertywatchtest.hpp"
4
5using namespace std::string_literals;
6using namespace phosphor::dbus::monitoring;
7
8const std::array<std::string, 4> paths =
9{
10 "/xyz/openbmc_project/testing/inst1"s,
11 "/xyz/openbmc_project/testing/inst2"s,
12 "/xyz/openbmc_project/testing/inst3"s,
13 "/xyz/openbmc_project/testing/inst4"s,
14};
15
16const std::array<std::string, 2> interfaces =
17{
18 "xyz.openbmc_project.Iface1"s,
19 "xyz.openbmc_project.Iface2"s,
20};
21
22const std::array<std::string, 2> properties =
23{
24 "Value1"s,
25 "Value2"s,
26};
27
28const std::string meta;
29
30std::array<any_ns::any, 8> storage = { };
31
32const PropertyIndex watchIndex =
33{
34 {
35 {
36 PropertyIndex::key_type{paths[0], interfaces[0], properties[0]},
37 PropertyIndex::mapped_type{meta, meta, storage[0]}
38 },
39 {
40 PropertyIndex::key_type{paths[0], interfaces[1], properties[1]},
41 PropertyIndex::mapped_type{meta, meta, storage[1]}
42 },
43 {
44 PropertyIndex::key_type{paths[1], interfaces[0], properties[0]},
45 PropertyIndex::mapped_type{meta, meta, storage[2]}
46 },
47 {
48 PropertyIndex::key_type{paths[1], interfaces[1], properties[1]},
49 PropertyIndex::mapped_type{meta, meta, storage[3]}
50 },
51 {
52 PropertyIndex::key_type{paths[2], interfaces[0], properties[0]},
53 PropertyIndex::mapped_type{meta, meta, storage[4]}
54 },
55 {
56 PropertyIndex::key_type{paths[2], interfaces[1], properties[1]},
57 PropertyIndex::mapped_type{meta, meta, storage[5]}
58 },
59 {
60 PropertyIndex::key_type{paths[3], interfaces[0], properties[0]},
61 PropertyIndex::mapped_type{meta, meta, storage[6]}
62 },
63 {
64 PropertyIndex::key_type{paths[3], interfaces[1], properties[1]},
65 PropertyIndex::mapped_type{meta, meta, storage[7]}
66 },
67 },
68};
69
70template <typename T> struct ExpectedValues {};
71template <> struct ExpectedValues<uint8_t>
72{
73 static auto& get(size_t i)
74 {
75 static const std::array<uint8_t, 8> values =
76 {
77 {0, 1, 2, 3, 4, 5, 6, 7},
78 };
79 return values[i];
80 }
81};
82
83template <> struct ExpectedValues<uint16_t>
84{
85 static auto& get(size_t i)
86 {
87 static const std::array<uint16_t, 8> values =
88 {
89 {88, 77, 66, 55, 44, 33, 22, 11},
90 };
91 return values[i];
92 }
93};
94
95template <> struct ExpectedValues<uint32_t>
96{
97 static auto& get(size_t i)
98 {
99 static const std::array<uint32_t, 8> values =
100 {
101 {0xffffffff, 1, 3, 0, 5, 7, 9, 0xffffffff},
102 };
103 return values[i];
104 }
105};
106
107template <> struct ExpectedValues<uint64_t>
108{
109 static auto& get(size_t i)
110 {
111 static const std::array<uint64_t, 8> values =
112 {
113 {0xffffffffffffffff, 3, 7, 12234, 0, 3, 9, 0xffffffff},
114 };
115 return values[i];
116 }
117};
118
119template <> struct ExpectedValues<std::string>
120{
121 static auto& get(size_t i)
122 {
123 static const std::array<std::string, 8> values =
124 {
125 {""s, "foo"s, "bar"s, "baz"s, "hello"s, "string", "\x2\x3", "\\"},
126 };
127 return values[i];
128 }
129};
130
131template <typename T>
132void testStart()
133{
134 using ::testing::Return;
135 using ::testing::_;
136
137 MockDBusInterface dbus;
138 MockDBusInterface::instance(dbus);
139
140 const std::vector<std::string> expectedMapperInterfaces;
141 PropertyWatchOfType<T, MockDBusInterface> watch(watchIndex);
142
143 auto ndx = static_cast<size_t>(0);
144 for (const auto& o : convert(watchIndex))
145 {
146 const auto& path = o.first.get();
147 const auto& interfaces = o.second;
148 std::vector<std::string> mapperResponse;
149 std::transform(
150 interfaces.begin(),
151 interfaces.end(),
152 std::back_inserter(mapperResponse),
153 // *INDENT-OFF*
154 [](const auto & item)
155 {
156 return item.first;
157 });
158 // *INDENT-ON*
159 EXPECT_CALL(
160 dbus,
161 mapperGetObject(
162 MAPPER_BUSNAME,
163 MAPPER_PATH,
164 MAPPER_INTERFACE,
165 "GetObject",
166 path,
167 expectedMapperInterfaces))
168 .WillOnce(Return(GetObject({{"", mapperResponse}})));
169 EXPECT_CALL(
170 dbus,
171 fwdAddMatch(
172 sdbusplus::bus::match::rules::member("InterfacesAdded") +
173 sdbusplus::bus::match::rules::path(path) +
174 sdbusplus::bus::match::rules::interface(
175 "org.freedesktop.DBus.ObjectManager"),
176 _));
177 for (const auto& i : interfaces)
178 {
179 const auto& interface = i.first.get();
180 const auto& properties = i.second;
181 EXPECT_CALL(
182 dbus,
183 fwdAddMatch(
184 sdbusplus::bus::match::rules::member("PropertiesChanged") +
185 sdbusplus::bus::match::rules::path(path) +
186 sdbusplus::bus::match::rules::argN(0, interface) +
187 sdbusplus::bus::match::rules::interface(
188 "org.freedesktop.DBus.Properties"),
189 _));
190
191 PropertiesChanged<T> serviceResponse;
192 for (const auto& p : properties)
193 {
194 serviceResponse[p] = ExpectedValues<T>::get(ndx);
195 ++ndx;
196 }
197 Expect<T>::getProperties(dbus, path, interface)
198 .WillOnce(Return(serviceResponse));
199 }
200 }
201
202 watch.start();
203
204 ndx = 0;
205 for (auto s : storage)
206 {
207 ASSERT_EQ(s.empty(), false);
208 ASSERT_EQ(any_ns::any_cast<T>(s), ExpectedValues<T>::get(ndx));
209 ++ndx;
210 }
211
212 // Make sure start logic only runs the first time.
213 watch.start();
214}
215
216TEST(PropertyWatchTest, TestStart)
217{
218 testStart<uint8_t>();
219 testStart<uint16_t>();
220 testStart<uint32_t>();
221 testStart<uint64_t>();
222 testStart<std::string>();
223}
224
225MockDBusInterface* MockDBusInterface::ptr = nullptr;