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 < 30 typename DBusInterfaceType, 31 typename Ret, 32 typename ...Args > 33 struct CallMethodAndRead 34 { 35 static Ret op( 36 DBusInterfaceType& dbus, 37 const std::string& busName, 38 const std::string& path, 39 const std::string& interface, 40 const std::string& method, 41 Args&& ... args) 42 { 43 static_assert(true, "Missing CallMethodAndRead definition."); 44 return Ret(); 45 } 46 }; 47 48 /** @brief CallMethodAndRead specialization for 49 * xyz.openbmc_project.ObjectMapper.GetObject. */ 50 template <typename DBusInterfaceType> 51 struct CallMethodAndRead < 52 DBusInterfaceType, 53 GetObject, 54 const MapperPath&, 55 const std::vector<std::string>& > 56 { 57 static GetObject op( 58 DBusInterfaceType& dbus, 59 const std::string& busName, 60 const std::string& path, 61 const std::string& interface, 62 const std::string& method, 63 const MapperPath& objectPath, 64 const std::vector<std::string>& interfaces) 65 { 66 return dbus.mapperGetObject( 67 busName, 68 path, 69 interface, 70 method, 71 objectPath, 72 interfaces); 73 } 74 }; 75 76 /** @brief CallMethodAndRead specialization for 77 * org.freedesktop.DBus.Properties.GetAll(uint64_t). */ 78 template <typename DBusInterfaceType> 79 struct CallMethodAndRead < 80 DBusInterfaceType, 81 PropertiesChanged<uint64_t>, 82 const std::string& > 83 { 84 static PropertiesChanged<uint64_t> op( 85 DBusInterfaceType& dbus, 86 const std::string& busName, 87 const std::string& path, 88 const std::string& interface, 89 const std::string& method, 90 const std::string& propertiesInterface) 91 { 92 return dbus.getPropertiesU64( 93 busName, 94 path, 95 interface, 96 method, 97 propertiesInterface); 98 } 99 }; 100 101 /** @brief CallMethodAndRead specialization for 102 * org.freedesktop.DBus.Properties.GetAll(uint32_t). */ 103 template <typename DBusInterfaceType> 104 struct CallMethodAndRead < 105 DBusInterfaceType, 106 PropertiesChanged<uint32_t>, 107 const std::string& > 108 { 109 static PropertiesChanged<uint32_t> op( 110 DBusInterfaceType& dbus, 111 const std::string& busName, 112 const std::string& path, 113 const std::string& interface, 114 const std::string& method, 115 const std::string& propertiesInterface) 116 { 117 return dbus.getPropertiesU32( 118 busName, 119 path, 120 interface, 121 method, 122 propertiesInterface); 123 } 124 }; 125 126 /** @brief CallMethodAndRead specialization for 127 * org.freedesktop.DBus.Properties.GetAll(uint16_t). */ 128 template <typename DBusInterfaceType> 129 struct CallMethodAndRead < 130 DBusInterfaceType, 131 PropertiesChanged<uint16_t>, 132 const std::string& > 133 { 134 static PropertiesChanged<uint16_t> op( 135 DBusInterfaceType& dbus, 136 const std::string& busName, 137 const std::string& path, 138 const std::string& interface, 139 const std::string& method, 140 const std::string& propertiesInterface) 141 { 142 return dbus.getPropertiesU16( 143 busName, 144 path, 145 interface, 146 method, 147 propertiesInterface); 148 } 149 }; 150 151 /** @brief CallMethodAndRead specialization for 152 * org.freedesktop.DBus.Properties.GetAll(uint8_t). */ 153 template <typename DBusInterfaceType> 154 struct CallMethodAndRead < 155 DBusInterfaceType, 156 PropertiesChanged<uint8_t>, 157 const std::string& > 158 { 159 static PropertiesChanged<uint8_t> op( 160 DBusInterfaceType& dbus, 161 const std::string& busName, 162 const std::string& path, 163 const std::string& interface, 164 const std::string& method, 165 const std::string& propertiesInterface) 166 { 167 return dbus.getPropertiesU8( 168 busName, 169 path, 170 interface, 171 method, 172 propertiesInterface); 173 } 174 }; 175 176 /** @brief CallMethodAndRead specialization for 177 * org.freedesktop.DBus.Properties.GetAll(int64_t). */ 178 template <typename DBusInterfaceType> 179 struct CallMethodAndRead < 180 DBusInterfaceType, 181 PropertiesChanged<int64_t>, 182 const std::string& > 183 { 184 static PropertiesChanged<int64_t> op( 185 DBusInterfaceType& dbus, 186 const std::string& busName, 187 const std::string& path, 188 const std::string& interface, 189 const std::string& method, 190 const std::string& propertiesInterface) 191 { 192 return dbus.getPropertiesU64( 193 busName, 194 path, 195 interface, 196 method, 197 propertiesInterface); 198 } 199 }; 200 201 /** @brief CallMethodAndRead specialization for 202 * org.freedesktop.DBus.Properties.GetAll(int32_t). */ 203 template <typename DBusInterfaceType> 204 struct CallMethodAndRead < 205 DBusInterfaceType, 206 PropertiesChanged<int32_t>, 207 const std::string& > 208 { 209 static PropertiesChanged<int32_t> op( 210 DBusInterfaceType& dbus, 211 const std::string& busName, 212 const std::string& path, 213 const std::string& interface, 214 const std::string& method, 215 const std::string& propertiesInterface) 216 { 217 return dbus.getPropertiesU32( 218 busName, 219 path, 220 interface, 221 method, 222 propertiesInterface); 223 } 224 }; 225 226 /** @brief CallMethodAndRead specialization for 227 * org.freedesktop.DBus.Properties.GetAll(int16_t). */ 228 template <typename DBusInterfaceType> 229 struct CallMethodAndRead < 230 DBusInterfaceType, 231 PropertiesChanged<int16_t>, 232 const std::string& > 233 { 234 static PropertiesChanged<int16_t> op( 235 DBusInterfaceType& dbus, 236 const std::string& busName, 237 const std::string& path, 238 const std::string& interface, 239 const std::string& method, 240 const std::string& propertiesInterface) 241 { 242 return dbus.getPropertiesU16( 243 busName, 244 path, 245 interface, 246 method, 247 propertiesInterface); 248 } 249 }; 250 251 /** @brief CallMethodAndRead specialization for 252 * org.freedesktop.DBus.Properties.GetAll(int8_t). */ 253 template <typename DBusInterfaceType> 254 struct CallMethodAndRead < 255 DBusInterfaceType, 256 PropertiesChanged<int8_t>, 257 const std::string& > 258 { 259 static PropertiesChanged<int8_t> op( 260 DBusInterfaceType& dbus, 261 const std::string& busName, 262 const std::string& path, 263 const std::string& interface, 264 const std::string& method, 265 const std::string& propertiesInterface) 266 { 267 return dbus.getPropertiesU8( 268 busName, 269 path, 270 interface, 271 method, 272 propertiesInterface); 273 } 274 }; 275 276 /** @brief CallMethodAndRead specialization for 277 * org.freedesktop.DBus.Properties.GetAll(std::string). */ 278 template <typename DBusInterfaceType> 279 struct CallMethodAndRead < 280 DBusInterfaceType, 281 PropertiesChanged<std::string>, 282 const std::string& > 283 { 284 static PropertiesChanged<std::string> op( 285 DBusInterfaceType& dbus, 286 const std::string& busName, 287 const std::string& path, 288 const std::string& interface, 289 const std::string& method, 290 const std::string& propertiesInterface) 291 { 292 return dbus.getPropertiesString( 293 busName, 294 path, 295 interface, 296 method, 297 propertiesInterface); 298 } 299 }; 300 301 /** @class MockDBusInterface 302 * @brief DBus access delegate implementation for the property watch test 303 * suite. 304 */ 305 struct MockDBusInterface 306 { 307 MOCK_METHOD6( 308 mapperGetObject, 309 GetObject( 310 const std::string&, 311 const std::string&, 312 const std::string&, 313 const std::string&, 314 const MapperPath&, 315 const std::vector<std::string>&)); 316 317 MOCK_METHOD5( 318 getPropertiesU64, 319 PropertiesChanged<uint64_t>( 320 const std::string&, 321 const std::string&, 322 const std::string&, 323 const std::string&, 324 const std::string&)); 325 326 MOCK_METHOD5( 327 getPropertiesU32, 328 PropertiesChanged<uint32_t>( 329 const std::string&, 330 const std::string&, 331 const std::string&, 332 const std::string&, 333 const std::string&)); 334 335 MOCK_METHOD5( 336 getPropertiesU16, 337 PropertiesChanged<uint16_t>( 338 const std::string&, 339 const std::string&, 340 const std::string&, 341 const std::string&, 342 const std::string&)); 343 344 MOCK_METHOD5( 345 getPropertiesU8, 346 PropertiesChanged<uint8_t>( 347 const std::string&, 348 const std::string&, 349 const std::string&, 350 const std::string&, 351 const std::string&)); 352 353 MOCK_METHOD5( 354 getPropertiesS64, 355 PropertiesChanged<int64_t>( 356 const std::string&, 357 const std::string&, 358 const std::string&, 359 const std::string&, 360 const std::string&)); 361 362 MOCK_METHOD5( 363 getPropertiesS32, 364 PropertiesChanged<int32_t>( 365 const std::string&, 366 const std::string&, 367 const std::string&, 368 const std::string&, 369 const std::string&)); 370 371 MOCK_METHOD5( 372 getPropertiesS16, 373 PropertiesChanged<int16_t>( 374 const std::string&, 375 const std::string&, 376 const std::string&, 377 const std::string&, 378 const std::string&)); 379 380 MOCK_METHOD5( 381 getPropertiesS8, 382 PropertiesChanged<int8_t>( 383 const std::string&, 384 const std::string&, 385 const std::string&, 386 const std::string&, 387 const std::string&)); 388 389 MOCK_METHOD5( 390 getPropertiesString, 391 PropertiesChanged<std::string>( 392 const std::string&, 393 const std::string&, 394 const std::string&, 395 const std::string&, 396 const std::string&)); 397 398 MOCK_METHOD2( 399 fwdAddMatch, 400 void( 401 const std::string&, 402 const sdbusplus::bus::match::match::callback_t&)); 403 404 static MockDBusInterface* ptr; 405 static MockDBusInterface& instance() 406 { 407 return *ptr; 408 } 409 static void instance(MockDBusInterface& p) 410 { 411 ptr = &p; 412 } 413 414 /** @brief GMock member template/free function forward. */ 415 template <typename Ret, typename ...Args> 416 static auto callMethodAndRead( 417 const std::string& busName, 418 const std::string& path, 419 const std::string& interface, 420 const std::string& method, 421 Args&& ... args) 422 { 423 return CallMethodAndRead <MockDBusInterface, Ret, Args... >::op( 424 instance(), 425 busName, 426 path, 427 interface, 428 method, 429 std::forward<Args>(args)...); 430 } 431 432 /** @brief GMock free function forward. */ 433 static auto addMatch( 434 const std::string& match, 435 const sdbusplus::bus::match::match::callback_t& callback) 436 { 437 instance().fwdAddMatch(match, callback); 438 } 439 }; 440 441 /** @class Expect 442 * @brief Enable use of EXPECT_CALL from a C++ template. 443 */ 444 template <typename T> struct Expect {}; 445 446 template <> 447 struct Expect<uint64_t> 448 { 449 template <typename MockObjType> 450 static auto& getProperties( 451 MockObjType&& mockObj, 452 const std::string& path, 453 const std::string& interface) 454 { 455 return EXPECT_CALL( 456 std::forward<MockObjType>(mockObj), 457 getPropertiesU64( 458 ::testing::_, 459 path, 460 "org.freedesktop.DBus.Properties", 461 "GetAll", 462 interface)); 463 } 464 }; 465 466 template <> 467 struct Expect<uint32_t> 468 { 469 template <typename MockObjType> 470 static auto& getProperties( 471 MockObjType&& mockObj, 472 const std::string& path, 473 const std::string& interface) 474 { 475 return EXPECT_CALL( 476 std::forward<MockObjType>(mockObj), 477 getPropertiesU32( 478 ::testing::_, 479 path, 480 "org.freedesktop.DBus.Properties", 481 "GetAll", 482 interface)); 483 } 484 }; 485 486 template <> 487 struct Expect<uint16_t> 488 { 489 template <typename MockObjType> 490 static auto& getProperties( 491 MockObjType&& mockObj, 492 const std::string& path, 493 const std::string& interface) 494 { 495 return EXPECT_CALL( 496 std::forward<MockObjType>(mockObj), 497 getPropertiesU16( 498 ::testing::_, 499 path, 500 "org.freedesktop.DBus.Properties", 501 "GetAll", 502 interface)); 503 } 504 }; 505 506 template <> 507 struct Expect<uint8_t> 508 { 509 template <typename MockObjType> 510 static auto& getProperties( 511 MockObjType&& mockObj, 512 const std::string& path, 513 const std::string& interface) 514 { 515 return EXPECT_CALL( 516 std::forward<MockObjType>(mockObj), 517 getPropertiesU8( 518 ::testing::_, 519 path, 520 "org.freedesktop.DBus.Properties", 521 "GetAll", 522 interface)); 523 } 524 }; 525 526 template <> 527 struct Expect<int64_t> 528 { 529 template <typename MockObjType> 530 static auto& getProperties( 531 MockObjType&& mockObj, 532 const std::string& path, 533 const std::string& interface) 534 { 535 return EXPECT_CALL( 536 std::forward<MockObjType>(mockObj), 537 getPropertiesS64( 538 ::testing::_, 539 path, 540 "org.freedesktop.DBus.Properties", 541 "GetAll", 542 interface)); 543 } 544 }; 545 546 template <> 547 struct Expect<int32_t> 548 { 549 template <typename MockObjType> 550 static auto& getProperties( 551 MockObjType&& mockObj, 552 const std::string& path, 553 const std::string& interface) 554 { 555 return EXPECT_CALL( 556 std::forward<MockObjType>(mockObj), 557 getPropertiesS32( 558 ::testing::_, 559 path, 560 "org.freedesktop.DBus.Properties", 561 "GetAll", 562 interface)); 563 } 564 }; 565 566 template <> 567 struct Expect<int16_t> 568 { 569 template <typename MockObjType> 570 static auto& getProperties( 571 MockObjType&& mockObj, 572 const std::string& path, 573 const std::string& interface) 574 { 575 return EXPECT_CALL( 576 std::forward<MockObjType>(mockObj), 577 getPropertiesS16( 578 ::testing::_, 579 path, 580 "org.freedesktop.DBus.Properties", 581 "GetAll", 582 interface)); 583 } 584 }; 585 586 template <> 587 struct Expect<int8_t> 588 { 589 template <typename MockObjType> 590 static auto& getProperties( 591 MockObjType&& mockObj, 592 const std::string& path, 593 const std::string& interface) 594 { 595 return EXPECT_CALL( 596 std::forward<MockObjType>(mockObj), 597 getPropertiesS8( 598 ::testing::_, 599 path, 600 "org.freedesktop.DBus.Properties", 601 "GetAll", 602 interface)); 603 } 604 }; 605 606 template <> 607 struct Expect<std::string> 608 { 609 template <typename MockObjType> 610 static auto& getProperties( 611 MockObjType&& mockObj, 612 const std::string& path, 613 const std::string& interface) 614 { 615 return EXPECT_CALL( 616 std::forward<MockObjType>(mockObj), 617 getPropertiesString( 618 ::testing::_, 619 path, 620 "org.freedesktop.DBus.Properties", 621 "GetAll", 622 interface)); 623 } 624 }; 625 626 } // namespace monitoring 627 } // namespace dbus 628 } // namespace phosphor 629