blob: 6576bfd4b05d5508fd026ccf1b9d319efd47d98a [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
Brad Bishopd1eac882018-03-29 10:34:05 -04008const std::array<std::string, 4> paths = {
Brad Bishop13fd8722017-05-15 12:44:01 -04009 "/xyz/openbmc_project/testing/inst1"s,
10 "/xyz/openbmc_project/testing/inst2"s,
11 "/xyz/openbmc_project/testing/inst3"s,
12 "/xyz/openbmc_project/testing/inst4"s,
13};
14
Brad Bishopd1eac882018-03-29 10:34:05 -040015const std::array<std::string, 2> interfaces = {
Brad Bishop13fd8722017-05-15 12:44:01 -040016 "xyz.openbmc_project.Iface1"s,
17 "xyz.openbmc_project.Iface2"s,
18};
19
Brad Bishopd1eac882018-03-29 10:34:05 -040020const std::array<std::string, 2> properties = {
Brad Bishop13fd8722017-05-15 12:44:01 -040021 "Value1"s,
22 "Value2"s,
23};
24
25const std::string meta;
26
Brad Bishopd1eac882018-03-29 10:34:05 -040027std::array<std::tuple<any_ns::any, any_ns::any>, 8> storage = {};
Brad Bishop13fd8722017-05-15 12:44:01 -040028
Brad Bishopd1eac882018-03-29 10:34:05 -040029const PropertyIndex watchIndex = {
Brad Bishop13fd8722017-05-15 12:44:01 -040030 {
Brad Bishopd1eac882018-03-29 10:34:05 -040031 {PropertyIndex::key_type{paths[0], interfaces[0], properties[0]},
32 PropertyIndex::mapped_type{meta, meta, storage[0]}},
33 {PropertyIndex::key_type{paths[0], interfaces[1], properties[1]},
34 PropertyIndex::mapped_type{meta, meta, storage[1]}},
35 {PropertyIndex::key_type{paths[1], interfaces[0], properties[0]},
36 PropertyIndex::mapped_type{meta, meta, storage[2]}},
37 {PropertyIndex::key_type{paths[1], interfaces[1], properties[1]},
38 PropertyIndex::mapped_type{meta, meta, storage[3]}},
39 {PropertyIndex::key_type{paths[2], interfaces[0], properties[0]},
40 PropertyIndex::mapped_type{meta, meta, storage[4]}},
41 {PropertyIndex::key_type{paths[2], interfaces[1], properties[1]},
42 PropertyIndex::mapped_type{meta, meta, storage[5]}},
43 {PropertyIndex::key_type{paths[3], interfaces[0], properties[0]},
44 PropertyIndex::mapped_type{meta, meta, storage[6]}},
45 {PropertyIndex::key_type{paths[3], interfaces[1], properties[1]},
46 PropertyIndex::mapped_type{meta, meta, storage[7]}},
Brad Bishop13fd8722017-05-15 12:44:01 -040047 },
48};
49
Brad Bishopd1eac882018-03-29 10:34:05 -040050template <typename T> struct ExpectedValues
51{
52};
Brad Bishop13fd8722017-05-15 12:44:01 -040053template <> struct ExpectedValues<uint8_t>
54{
55 static auto& get(size_t i)
56 {
Brad Bishopd1eac882018-03-29 10:34:05 -040057 static const std::array<uint8_t, 8> values = {
Brad Bishop13fd8722017-05-15 12:44:01 -040058 {0, 1, 2, 3, 4, 5, 6, 7},
59 };
60 return values[i];
61 }
62};
63
64template <> struct ExpectedValues<uint16_t>
65{
66 static auto& get(size_t i)
67 {
Brad Bishopd1eac882018-03-29 10:34:05 -040068 static const std::array<uint16_t, 8> values = {
Brad Bishop13fd8722017-05-15 12:44:01 -040069 {88, 77, 66, 55, 44, 33, 22, 11},
70 };
71 return values[i];
72 }
73};
74
75template <> struct ExpectedValues<uint32_t>
76{
77 static auto& get(size_t i)
78 {
Brad Bishopd1eac882018-03-29 10:34:05 -040079 static const std::array<uint32_t, 8> values = {
Brad Bishop13fd8722017-05-15 12:44:01 -040080 {0xffffffff, 1, 3, 0, 5, 7, 9, 0xffffffff},
81 };
82 return values[i];
83 }
84};
85
86template <> struct ExpectedValues<uint64_t>
87{
88 static auto& get(size_t i)
89 {
Brad Bishopd1eac882018-03-29 10:34:05 -040090 static const std::array<uint64_t, 8> values = {
Brad Bishop13fd8722017-05-15 12:44:01 -040091 {0xffffffffffffffff, 3, 7, 12234, 0, 3, 9, 0xffffffff},
92 };
93 return values[i];
94 }
95};
96
97template <> struct ExpectedValues<std::string>
98{
99 static auto& get(size_t i)
100 {
Brad Bishopd1eac882018-03-29 10:34:05 -0400101 static const std::array<std::string, 8> values = {
Brad Bishop13fd8722017-05-15 12:44:01 -0400102 {""s, "foo"s, "bar"s, "baz"s, "hello"s, "string", "\x2\x3", "\\"},
103 };
104 return values[i];
105 }
106};
107
Brad Bishopd1eac882018-03-29 10:34:05 -0400108template <typename T> void testStart()
Brad Bishop13fd8722017-05-15 12:44:01 -0400109{
110 using ::testing::Return;
111 using ::testing::_;
112
113 MockDBusInterface dbus;
114 MockDBusInterface::instance(dbus);
115
116 const std::vector<std::string> expectedMapperInterfaces;
117 PropertyWatchOfType<T, MockDBusInterface> watch(watchIndex);
118
119 auto ndx = static_cast<size_t>(0);
120 for (const auto& o : convert(watchIndex))
121 {
122 const auto& path = o.first.get();
123 const auto& interfaces = o.second;
124 std::vector<std::string> mapperResponse;
Brad Bishopd1eac882018-03-29 10:34:05 -0400125 std::transform(interfaces.begin(), interfaces.end(),
126 std::back_inserter(mapperResponse),
127 // *INDENT-OFF*
128 [](const auto& item) { return item.first; });
Brad Bishop13fd8722017-05-15 12:44:01 -0400129 // *INDENT-ON*
Brad Bishopd1eac882018-03-29 10:34:05 -0400130 EXPECT_CALL(dbus, mapperGetObject(MAPPER_BUSNAME, MAPPER_PATH,
131 MAPPER_INTERFACE, "GetObject", path,
132 expectedMapperInterfaces))
133 .WillOnce(Return(GetObject({{"", mapperResponse}})));
Brad Bishop13fd8722017-05-15 12:44:01 -0400134 EXPECT_CALL(
Brad Bishopd1eac882018-03-29 10:34:05 -0400135 dbus, fwdAddMatch(
136 sdbusplus::bus::match::rules::member("InterfacesAdded") +
137 sdbusplus::bus::match::rules::path(path) +
138 sdbusplus::bus::match::rules::interface(
139 "org.freedesktop.DBus.ObjectManager"),
140 _));
Brad Bishop13fd8722017-05-15 12:44:01 -0400141 for (const auto& i : interfaces)
142 {
143 const auto& interface = i.first.get();
144 const auto& properties = i.second;
145 EXPECT_CALL(
146 dbus,
147 fwdAddMatch(
148 sdbusplus::bus::match::rules::member("PropertiesChanged") +
Brad Bishopd1eac882018-03-29 10:34:05 -0400149 sdbusplus::bus::match::rules::path(path) +
150 sdbusplus::bus::match::rules::argN(0, interface) +
151 sdbusplus::bus::match::rules::interface(
152 "org.freedesktop.DBus.Properties"),
Brad Bishop13fd8722017-05-15 12:44:01 -0400153 _));
154
155 PropertiesChanged<T> serviceResponse;
156 for (const auto& p : properties)
157 {
158 serviceResponse[p] = ExpectedValues<T>::get(ndx);
159 ++ndx;
160 }
161 Expect<T>::getProperties(dbus, path, interface)
Brad Bishopd1eac882018-03-29 10:34:05 -0400162 .WillOnce(Return(serviceResponse));
Brad Bishop13fd8722017-05-15 12:44:01 -0400163 }
164 }
165
166 watch.start();
167
168 ndx = 0;
169 for (auto s : storage)
170 {
Matt Spinlerabe43ab2018-02-19 13:34:43 -0600171 ASSERT_EQ(std::get<0>(s).empty(), false);
Brad Bishop13fd8722017-05-15 12:44:01 -0400172 ASSERT_EQ(any_ns::any_cast<T>(s), ExpectedValues<T>::get(ndx));
173 ++ndx;
174 }
175
176 // Make sure start logic only runs the first time.
177 watch.start();
178}
179
180TEST(PropertyWatchTest, TestStart)
181{
182 testStart<uint8_t>();
183 testStart<uint16_t>();
184 testStart<uint32_t>();
185 testStart<uint64_t>();
186 testStart<std::string>();
187}
188
189MockDBusInterface* MockDBusInterface::ptr = nullptr;