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 { opphosphor::dbus::monitoring::CallMethodAndRead33 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 { opphosphor::dbus::monitoring::CallMethodAndRead48 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> opphosphor::dbus::monitoring::CallMethodAndRead65 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> opphosphor::dbus::monitoring::CallMethodAndRead81 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> opphosphor::dbus::monitoring::CallMethodAndRead97 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> opphosphor::dbus::monitoring::CallMethodAndRead113 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> opphosphor::dbus::monitoring::CallMethodAndRead129 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> opphosphor::dbus::monitoring::CallMethodAndRead145 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> opphosphor::dbus::monitoring::CallMethodAndRead161 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> opphosphor::dbus::monitoring::CallMethodAndRead177 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> opphosphor::dbus::monitoring::CallMethodAndRead193 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; instancephosphor::dbus::monitoring::MockDBusInterface262 static MockDBusInterface& instance() 263 { 264 return *ptr; 265 } instancephosphor::dbus::monitoring::MockDBusInterface266 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> callMethodAndReadphosphor::dbus::monitoring::MockDBusInterface273 static auto callMethodAndRead( 274 const std::string& busName, const std::string& path, 275 const std::string& interface, const std::string& method, Args&&... args) 276 { 277 return CallMethodAndRead<MockDBusInterface, Ret, Args...>::op( 278 instance(), busName, path, interface, method, 279 std::forward<Args>(args)...); 280 } 281 282 /** @brief GMock free function forward. */ addMatchphosphor::dbus::monitoring::MockDBusInterface283 static auto addMatch(const std::string& match, 284 const sdbusplus::bus::match_t::callback_t& callback) 285 { 286 instance().fwdAddMatch(match, callback); 287 } 288 }; 289 290 /** @class Expect 291 * @brief Enable use of EXPECT_CALL from a C++ template. 292 */ 293 template <typename T> 294 struct Expect 295 {}; 296 297 template <> 298 struct Expect<uint64_t> 299 { 300 template <typename MockObjType> getPropertiesphosphor::dbus::monitoring::Expect301 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 302 const std::string& interface) 303 { 304 return EXPECT_CALL(std::forward<MockObjType>(mockObj), 305 getPropertiesU64(::testing::_, path, 306 "org.freedesktop.DBus.Properties", 307 "GetAll", interface)); 308 } 309 }; 310 311 template <> 312 struct Expect<uint32_t> 313 { 314 template <typename MockObjType> getPropertiesphosphor::dbus::monitoring::Expect315 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 <> 326 struct Expect<uint16_t> 327 { 328 template <typename MockObjType> getPropertiesphosphor::dbus::monitoring::Expect329 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 330 const std::string& interface) 331 { 332 return EXPECT_CALL(std::forward<MockObjType>(mockObj), 333 getPropertiesU16(::testing::_, path, 334 "org.freedesktop.DBus.Properties", 335 "GetAll", interface)); 336 } 337 }; 338 339 template <> 340 struct Expect<uint8_t> 341 { 342 template <typename MockObjType> getPropertiesphosphor::dbus::monitoring::Expect343 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 344 const std::string& interface) 345 { 346 return EXPECT_CALL(std::forward<MockObjType>(mockObj), 347 getPropertiesU8(::testing::_, path, 348 "org.freedesktop.DBus.Properties", 349 "GetAll", interface)); 350 } 351 }; 352 353 template <> 354 struct Expect<int64_t> 355 { 356 template <typename MockObjType> getPropertiesphosphor::dbus::monitoring::Expect357 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 358 const std::string& interface) 359 { 360 return EXPECT_CALL(std::forward<MockObjType>(mockObj), 361 getPropertiesS64(::testing::_, path, 362 "org.freedesktop.DBus.Properties", 363 "GetAll", interface)); 364 } 365 }; 366 367 template <> 368 struct Expect<int32_t> 369 { 370 template <typename MockObjType> getPropertiesphosphor::dbus::monitoring::Expect371 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 372 const std::string& interface) 373 { 374 return EXPECT_CALL(std::forward<MockObjType>(mockObj), 375 getPropertiesS32(::testing::_, path, 376 "org.freedesktop.DBus.Properties", 377 "GetAll", interface)); 378 } 379 }; 380 381 template <> 382 struct Expect<int16_t> 383 { 384 template <typename MockObjType> getPropertiesphosphor::dbus::monitoring::Expect385 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 386 const std::string& interface) 387 { 388 return EXPECT_CALL(std::forward<MockObjType>(mockObj), 389 getPropertiesS16(::testing::_, path, 390 "org.freedesktop.DBus.Properties", 391 "GetAll", interface)); 392 } 393 }; 394 395 template <> 396 struct Expect<int8_t> 397 { 398 template <typename MockObjType> getPropertiesphosphor::dbus::monitoring::Expect399 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 400 const std::string& interface) 401 { 402 return EXPECT_CALL(std::forward<MockObjType>(mockObj), 403 getPropertiesS8(::testing::_, path, 404 "org.freedesktop.DBus.Properties", 405 "GetAll", interface)); 406 } 407 }; 408 409 template <> 410 struct Expect<std::string> 411 { 412 template <typename MockObjType> getPropertiesphosphor::dbus::monitoring::Expect413 static auto& getProperties(MockObjType&& mockObj, const std::string& path, 414 const std::string& interface) 415 { 416 return EXPECT_CALL( 417 std::forward<MockObjType>(mockObj), 418 getPropertiesString(::testing::_, path, 419 "org.freedesktop.DBus.Properties", "GetAll", 420 interface)); 421 } 422 }; 423 424 } // namespace monitoring 425 } // namespace dbus 426 } // namespace phosphor 427