xref: /openbmc/phosphor-dbus-monitor/src/test/propertywatchtest.hpp (revision 2b31c9882ddd7b0cabb6d18484e2887201932401)
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, void(const std::string&,
259                                    const sdbusplus::bus::match_t::callback_t&));
260 
261     static MockDBusInterface* ptr;
262     static MockDBusInterface& instance()
263     {
264         return *ptr;
265     }
266     static void instance(MockDBusInterface& p)
267     {
268         ptr = &p;
269     }
270 
271     /** @brief GMock member template/free function forward. */
272     template <typename Ret, typename... Args>
273     static auto callMethodAndRead(const std::string& busName,
274                                   const std::string& path,
275                                   const std::string& interface,
276                                   const std::string& method, Args&&... args)
277     {
278         return CallMethodAndRead<MockDBusInterface, Ret, Args...>::op(
279             instance(), busName, path, interface, method,
280             std::forward<Args>(args)...);
281     }
282 
283     /** @brief GMock free function forward. */
284     static auto addMatch(const std::string& match,
285                          const sdbusplus::bus::match_t::callback_t& callback)
286     {
287         instance().fwdAddMatch(match, callback);
288     }
289 };
290 
291 /** @class Expect
292  *  @brief Enable use of EXPECT_CALL from a C++ template.
293  */
294 template <typename T>
295 struct Expect
296 {};
297 
298 template <>
299 struct Expect<uint64_t>
300 {
301     template <typename MockObjType>
302     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
303                                const std::string& interface)
304     {
305         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
306                            getPropertiesU64(::testing::_, path,
307                                             "org.freedesktop.DBus.Properties",
308                                             "GetAll", interface));
309     }
310 };
311 
312 template <>
313 struct Expect<uint32_t>
314 {
315     template <typename MockObjType>
316     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
317                                const std::string& interface)
318     {
319         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
320                            getPropertiesU32(::testing::_, path,
321                                             "org.freedesktop.DBus.Properties",
322                                             "GetAll", interface));
323     }
324 };
325 
326 template <>
327 struct Expect<uint16_t>
328 {
329     template <typename MockObjType>
330     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
331                                const std::string& interface)
332     {
333         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
334                            getPropertiesU16(::testing::_, path,
335                                             "org.freedesktop.DBus.Properties",
336                                             "GetAll", interface));
337     }
338 };
339 
340 template <>
341 struct Expect<uint8_t>
342 {
343     template <typename MockObjType>
344     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
345                                const std::string& interface)
346     {
347         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
348                            getPropertiesU8(::testing::_, path,
349                                            "org.freedesktop.DBus.Properties",
350                                            "GetAll", interface));
351     }
352 };
353 
354 template <>
355 struct Expect<int64_t>
356 {
357     template <typename MockObjType>
358     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
359                                const std::string& interface)
360     {
361         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
362                            getPropertiesS64(::testing::_, path,
363                                             "org.freedesktop.DBus.Properties",
364                                             "GetAll", interface));
365     }
366 };
367 
368 template <>
369 struct Expect<int32_t>
370 {
371     template <typename MockObjType>
372     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
373                                const std::string& interface)
374     {
375         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
376                            getPropertiesS32(::testing::_, path,
377                                             "org.freedesktop.DBus.Properties",
378                                             "GetAll", interface));
379     }
380 };
381 
382 template <>
383 struct Expect<int16_t>
384 {
385     template <typename MockObjType>
386     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
387                                const std::string& interface)
388     {
389         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
390                            getPropertiesS16(::testing::_, path,
391                                             "org.freedesktop.DBus.Properties",
392                                             "GetAll", interface));
393     }
394 };
395 
396 template <>
397 struct Expect<int8_t>
398 {
399     template <typename MockObjType>
400     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
401                                const std::string& interface)
402     {
403         return EXPECT_CALL(std::forward<MockObjType>(mockObj),
404                            getPropertiesS8(::testing::_, path,
405                                            "org.freedesktop.DBus.Properties",
406                                            "GetAll", interface));
407     }
408 };
409 
410 template <>
411 struct Expect<std::string>
412 {
413     template <typename MockObjType>
414     static auto& getProperties(MockObjType&& mockObj, const std::string& path,
415                                const std::string& interface)
416     {
417         return EXPECT_CALL(
418             std::forward<MockObjType>(mockObj),
419             getPropertiesString(::testing::_, path,
420                                 "org.freedesktop.DBus.Properties", "GetAll",
421                                 interface));
422     }
423 };
424 
425 } // namespace monitoring
426 } // namespace dbus
427 } // namespace phosphor
428