1 #include "../interface_ops.hpp"
2 
3 #include <sdbusplus/test/sdbus_mock.hpp>
4 
5 #include <gtest/gtest.h>
6 
7 using namespace phosphor::inventory::manager;
8 using namespace testing;
9 using namespace std::string_literals;
10 
11 struct MockInterface;
12 struct DummyInterfaceWithProperties;
13 
14 MockInterface* g_currentMock = nullptr;
15 
16 using FakeVariantType = int;
17 using InterfaceVariant = std::map<std::string, FakeVariantType>;
18 
19 struct MockInterface
20 {
MockInterfaceMockInterface21     MockInterface()
22     {
23         g_currentMock = this;
24     }
~MockInterfaceMockInterface25     ~MockInterface()
26     {
27         g_currentMock = nullptr;
28     }
29     MockInterface(const MockInterface&) = delete;
30     MockInterface& operator=(const MockInterface&) = delete;
31     // Not supporting move semantics simply because they aren't needed.
32     MockInterface(MockInterface&&) = delete;
33     MockInterface& operator=(MockInterface&&) = delete;
34 
35     // We'll be getting calls proxyed through other objects.
36     MOCK_METHOD3(constructWithProperties,
37                  void(const char*, const InterfaceVariant& i, bool));
38     MOCK_METHOD1(constructWithoutProperties, void(const char*));
39     MOCK_METHOD3(setPropertyByName, void(std::string, FakeVariantType, bool));
40 
41     MOCK_METHOD2(serializeTwoArgs,
42                  void(const std::string&, const std::string&));
43     MOCK_METHOD3(serializeThreeArgs,
44                  void(const std::string&, const std::string&,
45                       const DummyInterfaceWithProperties&));
46 
47     MOCK_METHOD0(deserializeNoop, void());
48     MOCK_METHOD3(deserializeThreeArgs,
49                  void(const std::string&, const std::string&,
50                       DummyInterfaceWithProperties&));
51 };
52 
53 struct DummyInterfaceWithoutProperties
54 {
DummyInterfaceWithoutPropertiesDummyInterfaceWithoutProperties55     DummyInterfaceWithoutProperties(sdbusplus::bus_t&, const char* name)
56     {
57         g_currentMock->constructWithoutProperties(name);
58     }
59 };
60 
61 struct DummyInterfaceWithProperties
62 {
63     using PropertiesVariant = FakeVariantType;
64 
DummyInterfaceWithPropertiesDummyInterfaceWithProperties65     DummyInterfaceWithProperties(sdbusplus::bus_t&, const char* name,
66                                  const InterfaceVariant& i, bool skipSignal)
67     {
68         g_currentMock->constructWithProperties(name, i, skipSignal);
69     }
70 
setPropertyByNameDummyInterfaceWithProperties71     void setPropertyByName(std::string name, PropertiesVariant val,
72                            bool skipSignal)
73     {
74         g_currentMock->setPropertyByName(name, val, skipSignal);
75     }
76 };
77 
78 struct SerialForwarder
79 {
serializeSerialForwarder80     static void serialize(const std::string& path, const std::string& iface)
81     {
82         g_currentMock->serializeTwoArgs(path, iface);
83     }
84 
serializeSerialForwarder85     static void serialize(const std::string& path, const std::string& iface,
86                           const DummyInterfaceWithProperties& obj)
87     {
88         g_currentMock->serializeThreeArgs(path, iface, obj);
89     }
90 
deserializeSerialForwarder91     static void deserialize(const std::string& /* path */,
92                             const std::string& /* iface */)
93     {
94         g_currentMock->deserializeNoop();
95     }
96 
deserializeSerialForwarder97     static void deserialize(const std::string& path, const std::string& iface,
98                             DummyInterfaceWithProperties& obj)
99     {
100         g_currentMock->deserializeThreeArgs(path, iface, obj);
101     }
102 };
103 
TEST(InterfaceOpsTest,TestHasPropertiesNoProperties)104 TEST(InterfaceOpsTest, TestHasPropertiesNoProperties)
105 {
106     EXPECT_FALSE(HasProperties<DummyInterfaceWithoutProperties>::value);
107 }
108 
TEST(InterfaceOpsTest,TestHasPropertiesHasProperties)109 TEST(InterfaceOpsTest, TestHasPropertiesHasProperties)
110 {
111     EXPECT_TRUE(HasProperties<DummyInterfaceWithProperties>::value);
112 }
113 
TEST(InterfaceOpsTest,TestMakePropertylessInterfaceWithoutArguments)114 TEST(InterfaceOpsTest, TestMakePropertylessInterfaceWithoutArguments)
115 {
116     MockInterface mock;
117     Interface i;
118     sdbusplus::SdBusMock interface;
119 
120     EXPECT_CALL(mock, constructWithoutProperties("foo")).Times(1);
121     EXPECT_CALL(mock, constructWithProperties(_, _, _)).Times(0);
122 
123     auto b = sdbusplus::get_mocked_new(&interface);
124     auto r =
125         MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false);
126 
127     EXPECT_NO_THROW(
128         std::any_cast<std::shared_ptr<DummyInterfaceWithoutProperties>>(r));
129 }
130 
TEST(InterfaceOpsTest,TestMakePropertylessInterfaceWithOneArgument)131 TEST(InterfaceOpsTest, TestMakePropertylessInterfaceWithOneArgument)
132 {
133     MockInterface mock;
134     Interface i{{"foo"s, static_cast<int64_t>(1ll)}};
135     sdbusplus::SdBusMock interface;
136 
137     EXPECT_CALL(mock, constructWithoutProperties("foo")).Times(1);
138     EXPECT_CALL(mock, constructWithProperties(_, _, _)).Times(0);
139 
140     auto b = sdbusplus::get_mocked_new(&interface);
141     auto r =
142         MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false);
143 
144     EXPECT_NO_THROW(
145         std::any_cast<std::shared_ptr<DummyInterfaceWithoutProperties>>(r));
146 }
147 
TEST(InterfaceOpsTest,TestMakeInterfaceWithWithoutArguments)148 TEST(InterfaceOpsTest, TestMakeInterfaceWithWithoutArguments)
149 {
150     MockInterface mock;
151     Interface i;
152     sdbusplus::SdBusMock interface;
153 
154     EXPECT_CALL(mock, constructWithoutProperties(_)).Times(0);
155     EXPECT_CALL(mock, constructWithProperties("bar", _, _)).Times(1);
156 
157     auto b = sdbusplus::get_mocked_new(&interface);
158     auto r =
159         MakeInterface<DummyInterfaceWithProperties>::op(b, "bar", i, false);
160 
161     EXPECT_NO_THROW(
162         std::any_cast<std::shared_ptr<DummyInterfaceWithProperties>>(r));
163 }
164 
TEST(InterfaceOpsTest,TestMakeInterfaceWithOneArgument)165 TEST(InterfaceOpsTest, TestMakeInterfaceWithOneArgument)
166 {
167     MockInterface mock;
168     Interface i{{"foo"s, static_cast<int64_t>(1ll)}};
169     sdbusplus::SdBusMock interface;
170 
171     EXPECT_CALL(mock, constructWithoutProperties(_)).Times(0);
172     EXPECT_CALL(mock, constructWithProperties("foo", _, _)).Times(1);
173 
174     auto b = sdbusplus::get_mocked_new(&interface);
175     auto r =
176         MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false);
177 
178     EXPECT_NO_THROW(
179         std::any_cast<std::shared_ptr<DummyInterfaceWithProperties>>(r));
180 }
181 
TEST(InterfaceOpsTest,TestAssignPropertylessInterfaceWithoutArguments)182 TEST(InterfaceOpsTest, TestAssignPropertylessInterfaceWithoutArguments)
183 {
184     MockInterface mock;
185     Interface i;
186     sdbusplus::SdBusMock interface;
187 
188     EXPECT_CALL(mock, setPropertyByName(_, _, _)).Times(0);
189 
190     auto b = sdbusplus::get_mocked_new(&interface);
191     auto r =
192         MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false);
193 
194     AssignInterface<DummyInterfaceWithoutProperties>::op(i, r, false);
195 }
196 
TEST(InterfaceOpsTest,TestAssignPropertylessInterfaceWithOneArgument)197 TEST(InterfaceOpsTest, TestAssignPropertylessInterfaceWithOneArgument)
198 {
199     MockInterface mock;
200     Interface i{{"foo"s, static_cast<int64_t>(1ll)}};
201     sdbusplus::SdBusMock interface;
202 
203     EXPECT_CALL(mock, setPropertyByName(_, _, _)).Times(0);
204 
205     auto b = sdbusplus::get_mocked_new(&interface);
206     auto r =
207         MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false);
208 
209     AssignInterface<DummyInterfaceWithoutProperties>::op(i, r, false);
210 }
211 
TEST(InterfaceOpsTest,TestAssignInterfaceWithoutArguments)212 TEST(InterfaceOpsTest, TestAssignInterfaceWithoutArguments)
213 {
214     MockInterface mock;
215     Interface i;
216     sdbusplus::SdBusMock interface;
217 
218     EXPECT_CALL(mock, setPropertyByName(_, _, _)).Times(0);
219 
220     auto b = sdbusplus::get_mocked_new(&interface);
221     auto r =
222         MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false);
223 
224     AssignInterface<DummyInterfaceWithProperties>::op(i, r, false);
225 }
226 
TEST(InterfaceOpsTest,TestAssignInterfaceWithOneArgument)227 TEST(InterfaceOpsTest, TestAssignInterfaceWithOneArgument)
228 {
229     MockInterface mock;
230     Interface i{{"foo"s, static_cast<int64_t>(1ll)}};
231     sdbusplus::SdBusMock interface;
232 
233     EXPECT_CALL(mock, setPropertyByName("foo"s, 1ll, _)).Times(1);
234 
235     auto b = sdbusplus::get_mocked_new(&interface);
236     auto r =
237         MakeInterface<DummyInterfaceWithProperties>::op(b, "bar", i, false);
238 
239     AssignInterface<DummyInterfaceWithProperties>::op(i, r, false);
240 }
241 
TEST(InterfaceOpsTest,TestSerializePropertylessInterfaceWithoutArguments)242 TEST(InterfaceOpsTest, TestSerializePropertylessInterfaceWithoutArguments)
243 {
244     MockInterface mock;
245     Interface i;
246     sdbusplus::SdBusMock interface;
247 
248     auto b = sdbusplus::get_mocked_new(&interface);
249     auto r =
250         MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false);
251 
252     EXPECT_CALL(mock, serializeTwoArgs("/foo"s, "bar"s)).Times(1);
253 
254     SerializeInterface<DummyInterfaceWithoutProperties, SerialForwarder>::op(
255         "/foo"s, "bar"s, r);
256 }
257 
TEST(InterfaceOpsTest,TestSerializePropertylessInterfaceWithOneArgument)258 TEST(InterfaceOpsTest, TestSerializePropertylessInterfaceWithOneArgument)
259 {
260     MockInterface mock;
261     Interface i{{"foo"s, static_cast<int64_t>(1ll)}};
262     sdbusplus::SdBusMock interface;
263 
264     auto b = sdbusplus::get_mocked_new(&interface);
265     auto r =
266         MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false);
267 
268     EXPECT_CALL(mock, serializeTwoArgs("/foo"s, "bar"s)).Times(1);
269 
270     SerializeInterface<DummyInterfaceWithoutProperties, SerialForwarder>::op(
271         "/foo"s, "bar"s, r);
272 }
273 
TEST(InterfaceOpsTest,TestSerializeInterfaceWithNoArguments)274 TEST(InterfaceOpsTest, TestSerializeInterfaceWithNoArguments)
275 {
276     MockInterface mock;
277     Interface i;
278     sdbusplus::SdBusMock interface;
279 
280     auto b = sdbusplus::get_mocked_new(&interface);
281     auto r =
282         MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false);
283 
284     EXPECT_CALL(mock, serializeThreeArgs("/foo"s, "bar"s, _)).Times(1);
285 
286     SerializeInterface<DummyInterfaceWithProperties, SerialForwarder>::op(
287         "/foo"s, "bar"s, r);
288 }
289 
TEST(InterfaceOpsTest,TestSerializeInterfaceWithOneArgument)290 TEST(InterfaceOpsTest, TestSerializeInterfaceWithOneArgument)
291 {
292     MockInterface mock;
293     Interface i{{"foo"s, static_cast<int64_t>(1ll)}};
294     sdbusplus::SdBusMock interface;
295 
296     auto b = sdbusplus::get_mocked_new(&interface);
297     auto r =
298         MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false);
299 
300     EXPECT_CALL(mock, serializeThreeArgs("/foo"s, "bar"s, _)).Times(1);
301 
302     SerializeInterface<DummyInterfaceWithProperties, SerialForwarder>::op(
303         "/foo"s, "bar"s, r);
304 }
305 
TEST(InterfaceOpsTest,TestDeserializePropertylessInterfaceWithoutArguments)306 TEST(InterfaceOpsTest, TestDeserializePropertylessInterfaceWithoutArguments)
307 {
308     MockInterface mock;
309     Interface i;
310     sdbusplus::SdBusMock interface;
311 
312     auto b = sdbusplus::get_mocked_new(&interface);
313     auto r =
314         MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false);
315 
316     EXPECT_CALL(mock, deserializeNoop()).Times(1);
317 
318     DeserializeInterface<DummyInterfaceWithoutProperties, SerialForwarder>::op(
319         "/foo"s, "bar"s, r);
320 }
321 
TEST(InterfaceOpsTest,TestDeserializePropertylessInterfaceWithOneArgument)322 TEST(InterfaceOpsTest, TestDeserializePropertylessInterfaceWithOneArgument)
323 {
324     MockInterface mock;
325     Interface i{{"foo"s, static_cast<int64_t>(1ll)}};
326     sdbusplus::SdBusMock interface;
327 
328     auto b = sdbusplus::get_mocked_new(&interface);
329     auto r =
330         MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false);
331 
332     EXPECT_CALL(mock, deserializeNoop()).Times(1);
333 
334     DeserializeInterface<DummyInterfaceWithoutProperties, SerialForwarder>::op(
335         "/foo"s, "bar"s, r);
336 }
337 
TEST(InterfaceOpsTest,TestDeserializeInterfaceWithNoArguments)338 TEST(InterfaceOpsTest, TestDeserializeInterfaceWithNoArguments)
339 {
340     MockInterface mock;
341     Interface i;
342     sdbusplus::SdBusMock interface;
343 
344     auto b = sdbusplus::get_mocked_new(&interface);
345     auto r =
346         MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false);
347 
348     EXPECT_CALL(mock, deserializeThreeArgs("/foo"s, "bar"s, _)).Times(1);
349 
350     DeserializeInterface<DummyInterfaceWithProperties, SerialForwarder>::op(
351         "/foo"s, "bar"s, r);
352 }
353 
TEST(InterfaceOpsTest,TestDeserializeInterfaceWithOneArgument)354 TEST(InterfaceOpsTest, TestDeserializeInterfaceWithOneArgument)
355 {
356     MockInterface mock;
357     Interface i{{"foo"s, static_cast<int64_t>(1ll)}};
358     sdbusplus::SdBusMock interface;
359 
360     auto b = sdbusplus::get_mocked_new(&interface);
361     auto r =
362         MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false);
363 
364     EXPECT_CALL(mock, deserializeThreeArgs("/foo"s, "bar"s, _)).Times(1);
365 
366     DeserializeInterface<DummyInterfaceWithProperties, SerialForwarder>::op(
367         "/foo"s, "bar"s, r);
368 }
369