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