xref: /openbmc/phosphor-dbus-monitor/src/test/propertywatchtest.hpp (revision 3fe976cc22e579860f5b1832d920636d93145507)
1 #pragma once
2 #include "data_types.hpp"
3 #include "sdbusplus/bus/match.hpp"
4 
5 #include <string>
6 
7 #include <gmock/gmock.h>
8 #include <gtest/gtest.h>
9 
10 namespace phosphor
11 {
12 namespace dbus
13 {
14 namespace monitoring
15 {
16 
17 /** @class CallMethodAndRead
18  *  @brief GMock template member forwarding helper.
19  *
20  *  The code under test calls callMethodAndRead, which is a templated,
21  *  free function.  Enable this under GMock by forwarding calls to it
22  *  to functions that can be mocked.
23  *
24  *  @tparam DBusInterfaceType - The mock object type.
25  *  @tparam Ret - The return type of the method being called.
26  *  @tparam Args - The argument types of the method being called.
27  *
28  *  Specialize to implement new forwards.
29  */
30 template <typename DBusInterfaceType, typename Ret, typename... Args>
31 struct CallMethodAndRead
32 {
33     static Ret op(DBusInterfaceType& dbus, const std::string& busName,
34                   const std::string& path, const std::string& interface,
35                   const std::string& method, Args&&... args)
36     {
37         static_assert(true, "Missing CallMethodAndRead definition.");
38         return Ret();
39     }
40 };
41 
42 /** @brief CallMethodAndRead specialization for
43  *     xyz.openbmc_project.ObjectMapper.GetObject. */
44 template <typename DBusInterfaceType>
45 struct CallMethodAndRead<DBusInterfaceType, GetObject, const MapperPath&,
46                          const std::vector<std::string>&>
47 {
48     static GetObject op(DBusInterfaceType& dbus, const std::string& busName,
49                         const std::string& path, const std::string& interface,
50                         const std::string& method, const MapperPath& objectPath,
51                         const std::vector<std::string>& interfaces)
52     {
53         return dbus.mapperGetObject(busName, path, interface, method,
54                                     objectPath, interfaces);
55     }
56 };
57 
58 /** @brief CallMethodAndRead specialization for
59  *     org.freedesktop.DBus.Properties.GetAll(uint64_t). */
60 template <typename DBusInterfaceType>
61 struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<uint64_t>,
62                          const std::string&>
63 {
64     static PropertiesChanged<uint64_t>
65         op(DBusInterfaceType& dbus, const std::string& busName,
66            const std::string& path, const std::string& interface,
67            const std::string& method, const std::string& propertiesInterface)
68     {
69         return dbus.getPropertiesU64(busName, path, interface, method,
70                                      propertiesInterface);
71     }
72 };
73 
74 /** @brief CallMethodAndRead specialization for
75  *     org.freedesktop.DBus.Properties.GetAll(uint32_t). */
76 template <typename DBusInterfaceType>
77 struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<uint32_t>,
78                          const std::string&>
79 {
80     static PropertiesChanged<uint32_t>
81         op(DBusInterfaceType& dbus, const std::string& busName,
82            const std::string& path, const std::string& interface,
83            const std::string& method, const std::string& propertiesInterface)
84     {
85         return dbus.getPropertiesU32(busName, path, interface, method,
86                                      propertiesInterface);
87     }
88 };
89 
90 /** @brief CallMethodAndRead specialization for
91  *     org.freedesktop.DBus.Properties.GetAll(uint16_t). */
92 template <typename DBusInterfaceType>
93 struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<uint16_t>,
94                          const std::string&>
95 {
96     static PropertiesChanged<uint16_t>
97         op(DBusInterfaceType& dbus, const std::string& busName,
98            const std::string& path, const std::string& interface,
99            const std::string& method, const std::string& propertiesInterface)
100     {
101         return dbus.getPropertiesU16(busName, path, interface, method,
102                                      propertiesInterface);
103     }
104 };
105 
106 /** @brief CallMethodAndRead specialization for
107  *     org.freedesktop.DBus.Properties.GetAll(uint8_t). */
108 template <typename DBusInterfaceType>
109 struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<uint8_t>,
110                          const std::string&>
111 {
112     static PropertiesChanged<uint8_t>
113         op(DBusInterfaceType& dbus, const std::string& busName,
114            const std::string& path, const std::string& interface,
115            const std::string& method, const std::string& propertiesInterface)
116     {
117         return dbus.getPropertiesU8(busName, path, interface, method,
118                                     propertiesInterface);
119     }
120 };
121 
122 /** @brief CallMethodAndRead specialization for
123  *     org.freedesktop.DBus.Properties.GetAll(int64_t). */
124 template <typename DBusInterfaceType>
125 struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<int64_t>,
126                          const std::string&>
127 {
128     static PropertiesChanged<int64_t>
129         op(DBusInterfaceType& dbus, const std::string& busName,
130            const std::string& path, const std::string& interface,
131            const std::string& method, const std::string& propertiesInterface)
132     {
133         return dbus.getPropertiesU64(busName, path, interface, method,
134                                      propertiesInterface);
135     }
136 };
137 
138 /** @brief CallMethodAndRead specialization for
139  *     org.freedesktop.DBus.Properties.GetAll(int32_t). */
140 template <typename DBusInterfaceType>
141 struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<int32_t>,
142                          const std::string&>
143 {
144     static PropertiesChanged<int32_t>
145         op(DBusInterfaceType& dbus, const std::string& busName,
146            const std::string& path, const std::string& interface,
147            const std::string& method, const std::string& propertiesInterface)
148     {
149         return dbus.getPropertiesU32(busName, path, interface, method,
150                                      propertiesInterface);
151     }
152 };
153 
154 /** @brief CallMethodAndRead specialization for
155  *     org.freedesktop.DBus.Properties.GetAll(int16_t). */
156 template <typename DBusInterfaceType>
157 struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<int16_t>,
158                          const std::string&>
159 {
160     static PropertiesChanged<int16_t>
161         op(DBusInterfaceType& dbus, const std::string& busName,
162            const std::string& path, const std::string& interface,
163            const std::string& method, const std::string& propertiesInterface)
164     {
165         return dbus.getPropertiesU16(busName, path, interface, method,
166                                      propertiesInterface);
167     }
168 };
169 
170 /** @brief CallMethodAndRead specialization for
171  *     org.freedesktop.DBus.Properties.GetAll(int8_t). */
172 template <typename DBusInterfaceType>
173 struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<int8_t>,
174                          const std::string&>
175 {
176     static PropertiesChanged<int8_t>
177         op(DBusInterfaceType& dbus, const std::string& busName,
178            const std::string& path, const std::string& interface,
179            const std::string& method, const std::string& propertiesInterface)
180     {
181         return dbus.getPropertiesU8(busName, path, interface, method,
182                                     propertiesInterface);
183     }
184 };
185 
186 /** @brief CallMethodAndRead specialization for
187  *     org.freedesktop.DBus.Properties.GetAll(std::string). */
188 template <typename DBusInterfaceType>
189 struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<std::string>,
190                          const std::string&>
191 {
192     static PropertiesChanged<std::string>
193         op(DBusInterfaceType& dbus, const std::string& busName,
194            const std::string& path, const std::string& interface,
195            const std::string& method, const std::string& propertiesInterface)
196     {
197         return dbus.getPropertiesString(busName, path, interface, method,
198                                         propertiesInterface);
199     }
200 };
201 
202 /** @class MockDBusInterface
203  *  @brief DBus access delegate implementation for the property watch test
204  *  suite.
205  */
206 struct MockDBusInterface
207 {
208     MOCK_METHOD6(mapperGetObject,
209                  GetObject(const std::string&, const std::string&,
210                            const std::string&, const std::string&,
211                            const MapperPath&, const std::vector<std::string>&));
212 
213     MOCK_METHOD5(getPropertiesU64,
214                  PropertiesChanged<uint64_t>(
215                      const std::string&, const std::string&, const std::string&,
216                      const std::string&, const std::string&));
217 
218     MOCK_METHOD5(getPropertiesU32,
219                  PropertiesChanged<uint32_t>(
220                      const std::string&, const std::string&, const std::string&,
221                      const std::string&, const std::string&));
222 
223     MOCK_METHOD5(getPropertiesU16,
224                  PropertiesChanged<uint16_t>(
225                      const std::string&, const std::string&, const std::string&,
226                      const std::string&, const std::string&));
227 
228     MOCK_METHOD5(getPropertiesU8,
229                  PropertiesChanged<uint8_t>(
230                      const std::string&, const std::string&, const std::string&,
231                      const std::string&, const std::string&));
232 
233     MOCK_METHOD5(getPropertiesS64,
234                  PropertiesChanged<int64_t>(
235                      const std::string&, const std::string&, const std::string&,
236                      const std::string&, const std::string&));
237 
238     MOCK_METHOD5(getPropertiesS32,
239                  PropertiesChanged<int32_t>(
240                      const std::string&, const std::string&, const std::string&,
241                      const std::string&, const std::string&));
242 
243     MOCK_METHOD5(getPropertiesS16,
244                  PropertiesChanged<int16_t>(
245                      const std::string&, const std::string&, const std::string&,
246                      const std::string&, const std::string&));
247 
248     MOCK_METHOD5(getPropertiesS8,
249                  PropertiesChanged<int8_t>(
250                      const std::string&, const std::string&, const std::string&,
251                      const std::string&, const std::string&));
252 
253     MOCK_METHOD5(getPropertiesString,
254                  PropertiesChanged<std::string>(
255                      const std::string&, const std::string&, const std::string&,
256                      const std::string&, const std::string&));
257 
258     MOCK_METHOD2(fwdAddMatch,
259                  void(const std::string&,
260                       const sdbusplus::bus::match::match::callback_t&));
261 
262     static MockDBusInterface* ptr;
263     static MockDBusInterface& instance()
264     {
265         return *ptr;
266     }
267     static void instance(MockDBusInterface& p)
268     {
269         ptr = &p;
270     }
271 
272     /** @brief GMock member template/free function forward. */
273     template <typename Ret, typename... Args>
274     static auto callMethodAndRead(const std::string& busName,
275                                   const std::string& path,
276                                   const std::string& interface,
277                                   const std::string& method, Args&&... args)
278     {
279         return CallMethodAndRead<MockDBusInterface, Ret, Args...>::op(
280             instance(), busName, path, interface, method,
281             std::forward<Args>(args)...);
282     }
283 
284     /** @brief GMock free function forward. */
285     static auto
286         addMatch(const std::string& match,
287                  const sdbusplus::bus::match::match::callback_t& callback)
288     {
289         instance().fwdAddMatch(match, callback);
290     }
291 };
292 
293 /** @class Expect
294  *  @brief Enable use of EXPECT_CALL from a C++ template.
295  */
296 template <typename T>
297 struct Expect
298 {};
299 
300 template <>
301 struct Expect<uint64_t>
302 {
303     template <typename MockObjType>
304     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
305                                const std::string& interface)
306     {
307         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
308                            getPropertiesU64(::testing::_, path,
309                                             "org.freedesktop.DBus.Properties",
310                                             "GetAll", interface));
311     }
312 };
313 
314 template <>
315 struct Expect<uint32_t>
316 {
317     template <typename MockObjType>
318     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
319                                const std::string& interface)
320     {
321         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
322                            getPropertiesU32(::testing::_, path,
323                                             "org.freedesktop.DBus.Properties",
324                                             "GetAll", interface));
325     }
326 };
327 
328 template <>
329 struct Expect<uint16_t>
330 {
331     template <typename MockObjType>
332     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
333                                const std::string& interface)
334     {
335         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
336                            getPropertiesU16(::testing::_, path,
337                                             "org.freedesktop.DBus.Properties",
338                                             "GetAll", interface));
339     }
340 };
341 
342 template <>
343 struct Expect<uint8_t>
344 {
345     template <typename MockObjType>
346     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
347                                const std::string& interface)
348     {
349         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
350                            getPropertiesU8(::testing::_, path,
351                                            "org.freedesktop.DBus.Properties",
352                                            "GetAll", interface));
353     }
354 };
355 
356 template <>
357 struct Expect<int64_t>
358 {
359     template <typename MockObjType>
360     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
361                                const std::string& interface)
362     {
363         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
364                            getPropertiesS64(::testing::_, path,
365                                             "org.freedesktop.DBus.Properties",
366                                             "GetAll", interface));
367     }
368 };
369 
370 template <>
371 struct Expect<int32_t>
372 {
373     template <typename MockObjType>
374     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
375                                const std::string& interface)
376     {
377         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
378                            getPropertiesS32(::testing::_, path,
379                                             "org.freedesktop.DBus.Properties",
380                                             "GetAll", interface));
381     }
382 };
383 
384 template <>
385 struct Expect<int16_t>
386 {
387     template <typename MockObjType>
388     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
389                                const std::string& interface)
390     {
391         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
392                            getPropertiesS16(::testing::_, path,
393                                             "org.freedesktop.DBus.Properties",
394                                             "GetAll", interface));
395     }
396 };
397 
398 template <>
399 struct Expect<int8_t>
400 {
401     template <typename MockObjType>
402     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
403                                const std::string& interface)
404     {
405         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
406                            getPropertiesS8(::testing::_, path,
407                                            "org.freedesktop.DBus.Properties",
408                                            "GetAll", interface));
409     }
410 };
411 
412 template <>
413 struct Expect<std::string>
414 {
415     template <typename MockObjType>
416     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
417                                const std::string& interface)
418     {
419         return EXPECT_CALL(
420             std::forward<MockObjType>(mockObj),
421             getPropertiesString(::testing::_, path,
422                                 "org.freedesktop.DBus.Properties", "GetAll",
423                                 interface));
424     }
425 };
426 
427 } // namespace monitoring
428 } // namespace dbus
429 } // namespace phosphor
430