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 301 template <> 302 struct Expect<uint64_t> 303 { 304 template <typename MockObjType> 305 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 306 const std::string& interface) 307 { 308 return EXPECT_CALL(std::forward<MockObjType>(mockObj), 309 getPropertiesU64(::testing::_, path, 310 "org.freedesktop.DBus.Properties", 311 "GetAll", interface)); 312 } 313 }; 314 315 template <> 316 struct Expect<uint32_t> 317 { 318 template <typename MockObjType> 319 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 320 const std::string& interface) 321 { 322 return EXPECT_CALL(std::forward<MockObjType>(mockObj), 323 getPropertiesU32(::testing::_, path, 324 "org.freedesktop.DBus.Properties", 325 "GetAll", interface)); 326 } 327 }; 328 329 template <> 330 struct Expect<uint16_t> 331 { 332 template <typename MockObjType> 333 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 334 const std::string& interface) 335 { 336 return EXPECT_CALL(std::forward<MockObjType>(mockObj), 337 getPropertiesU16(::testing::_, path, 338 "org.freedesktop.DBus.Properties", 339 "GetAll", interface)); 340 } 341 }; 342 343 template <> 344 struct Expect<uint8_t> 345 { 346 template <typename MockObjType> 347 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 348 const std::string& interface) 349 { 350 return EXPECT_CALL(std::forward<MockObjType>(mockObj), 351 getPropertiesU8(::testing::_, path, 352 "org.freedesktop.DBus.Properties", 353 "GetAll", interface)); 354 } 355 }; 356 357 template <> 358 struct Expect<int64_t> 359 { 360 template <typename MockObjType> 361 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 362 const std::string& interface) 363 { 364 return EXPECT_CALL(std::forward<MockObjType>(mockObj), 365 getPropertiesS64(::testing::_, path, 366 "org.freedesktop.DBus.Properties", 367 "GetAll", interface)); 368 } 369 }; 370 371 template <> 372 struct Expect<int32_t> 373 { 374 template <typename MockObjType> 375 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 376 const std::string& interface) 377 { 378 return EXPECT_CALL(std::forward<MockObjType>(mockObj), 379 getPropertiesS32(::testing::_, path, 380 "org.freedesktop.DBus.Properties", 381 "GetAll", interface)); 382 } 383 }; 384 385 template <> 386 struct Expect<int16_t> 387 { 388 template <typename MockObjType> 389 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 390 const std::string& interface) 391 { 392 return EXPECT_CALL(std::forward<MockObjType>(mockObj), 393 getPropertiesS16(::testing::_, path, 394 "org.freedesktop.DBus.Properties", 395 "GetAll", interface)); 396 } 397 }; 398 399 template <> 400 struct Expect<int8_t> 401 { 402 template <typename MockObjType> 403 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 404 const std::string& interface) 405 { 406 return EXPECT_CALL(std::forward<MockObjType>(mockObj), 407 getPropertiesS8(::testing::_, path, 408 "org.freedesktop.DBus.Properties", 409 "GetAll", interface)); 410 } 411 }; 412 413 template <> 414 struct Expect<std::string> 415 { 416 template <typename MockObjType> 417 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 418 const std::string& interface) 419 { 420 return EXPECT_CALL( 421 std::forward<MockObjType>(mockObj), 422 getPropertiesString(::testing::_, path, 423 "org.freedesktop.DBus.Properties", "GetAll", 424 interface)); 425 } 426 }; 427 428 } // namespace monitoring 429 } // namespace dbus 430 } // namespace phosphor 431