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