| #pragma once |
| #include "data_types.hpp" |
| #include "sdbusplus/bus/match.hpp" |
| |
| #include <string> |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| namespace phosphor |
| { |
| namespace dbus |
| { |
| namespace monitoring |
| { |
| |
| /** @class CallMethodAndRead |
| * @brief GMock template member forwarding helper. |
| * |
| * The code under test calls callMethodAndRead, which is a templated, |
| * free function. Enable this under GMock by forwarding calls to it |
| * to functions that can be mocked. |
| * |
| * @tparam DBusInterfaceType - The mock object type. |
| * @tparam Ret - The return type of the method being called. |
| * @tparam Args - The argument types of the method being called. |
| * |
| * Specialize to implement new forwards. |
| */ |
| template <typename DBusInterfaceType, typename Ret, typename... Args> |
| struct CallMethodAndRead |
| { |
| static Ret op(DBusInterfaceType& dbus, const std::string& busName, |
| const std::string& path, const std::string& interface, |
| const std::string& method, Args&&... args) |
| { |
| static_assert(true, "Missing CallMethodAndRead definition."); |
| return Ret(); |
| } |
| }; |
| |
| /** @brief CallMethodAndRead specialization for |
| * xyz.openbmc_project.ObjectMapper.GetObject. */ |
| template <typename DBusInterfaceType> |
| struct CallMethodAndRead<DBusInterfaceType, GetObject, const MapperPath&, |
| const std::vector<std::string>&> |
| { |
| static GetObject op(DBusInterfaceType& dbus, const std::string& busName, |
| const std::string& path, const std::string& interface, |
| const std::string& method, const MapperPath& objectPath, |
| const std::vector<std::string>& interfaces) |
| { |
| return dbus.mapperGetObject(busName, path, interface, method, |
| objectPath, interfaces); |
| } |
| }; |
| |
| /** @brief CallMethodAndRead specialization for |
| * org.freedesktop.DBus.Properties.GetAll(uint64_t). */ |
| template <typename DBusInterfaceType> |
| struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<uint64_t>, |
| const std::string&> |
| { |
| static PropertiesChanged<uint64_t> |
| op(DBusInterfaceType& dbus, const std::string& busName, |
| const std::string& path, const std::string& interface, |
| const std::string& method, const std::string& propertiesInterface) |
| { |
| return dbus.getPropertiesU64(busName, path, interface, method, |
| propertiesInterface); |
| } |
| }; |
| |
| /** @brief CallMethodAndRead specialization for |
| * org.freedesktop.DBus.Properties.GetAll(uint32_t). */ |
| template <typename DBusInterfaceType> |
| struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<uint32_t>, |
| const std::string&> |
| { |
| static PropertiesChanged<uint32_t> |
| op(DBusInterfaceType& dbus, const std::string& busName, |
| const std::string& path, const std::string& interface, |
| const std::string& method, const std::string& propertiesInterface) |
| { |
| return dbus.getPropertiesU32(busName, path, interface, method, |
| propertiesInterface); |
| } |
| }; |
| |
| /** @brief CallMethodAndRead specialization for |
| * org.freedesktop.DBus.Properties.GetAll(uint16_t). */ |
| template <typename DBusInterfaceType> |
| struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<uint16_t>, |
| const std::string&> |
| { |
| static PropertiesChanged<uint16_t> |
| op(DBusInterfaceType& dbus, const std::string& busName, |
| const std::string& path, const std::string& interface, |
| const std::string& method, const std::string& propertiesInterface) |
| { |
| return dbus.getPropertiesU16(busName, path, interface, method, |
| propertiesInterface); |
| } |
| }; |
| |
| /** @brief CallMethodAndRead specialization for |
| * org.freedesktop.DBus.Properties.GetAll(uint8_t). */ |
| template <typename DBusInterfaceType> |
| struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<uint8_t>, |
| const std::string&> |
| { |
| static PropertiesChanged<uint8_t> |
| op(DBusInterfaceType& dbus, const std::string& busName, |
| const std::string& path, const std::string& interface, |
| const std::string& method, const std::string& propertiesInterface) |
| { |
| return dbus.getPropertiesU8(busName, path, interface, method, |
| propertiesInterface); |
| } |
| }; |
| |
| /** @brief CallMethodAndRead specialization for |
| * org.freedesktop.DBus.Properties.GetAll(int64_t). */ |
| template <typename DBusInterfaceType> |
| struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<int64_t>, |
| const std::string&> |
| { |
| static PropertiesChanged<int64_t> |
| op(DBusInterfaceType& dbus, const std::string& busName, |
| const std::string& path, const std::string& interface, |
| const std::string& method, const std::string& propertiesInterface) |
| { |
| return dbus.getPropertiesU64(busName, path, interface, method, |
| propertiesInterface); |
| } |
| }; |
| |
| /** @brief CallMethodAndRead specialization for |
| * org.freedesktop.DBus.Properties.GetAll(int32_t). */ |
| template <typename DBusInterfaceType> |
| struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<int32_t>, |
| const std::string&> |
| { |
| static PropertiesChanged<int32_t> |
| op(DBusInterfaceType& dbus, const std::string& busName, |
| const std::string& path, const std::string& interface, |
| const std::string& method, const std::string& propertiesInterface) |
| { |
| return dbus.getPropertiesU32(busName, path, interface, method, |
| propertiesInterface); |
| } |
| }; |
| |
| /** @brief CallMethodAndRead specialization for |
| * org.freedesktop.DBus.Properties.GetAll(int16_t). */ |
| template <typename DBusInterfaceType> |
| struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<int16_t>, |
| const std::string&> |
| { |
| static PropertiesChanged<int16_t> |
| op(DBusInterfaceType& dbus, const std::string& busName, |
| const std::string& path, const std::string& interface, |
| const std::string& method, const std::string& propertiesInterface) |
| { |
| return dbus.getPropertiesU16(busName, path, interface, method, |
| propertiesInterface); |
| } |
| }; |
| |
| /** @brief CallMethodAndRead specialization for |
| * org.freedesktop.DBus.Properties.GetAll(int8_t). */ |
| template <typename DBusInterfaceType> |
| struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<int8_t>, |
| const std::string&> |
| { |
| static PropertiesChanged<int8_t> |
| op(DBusInterfaceType& dbus, const std::string& busName, |
| const std::string& path, const std::string& interface, |
| const std::string& method, const std::string& propertiesInterface) |
| { |
| return dbus.getPropertiesU8(busName, path, interface, method, |
| propertiesInterface); |
| } |
| }; |
| |
| /** @brief CallMethodAndRead specialization for |
| * org.freedesktop.DBus.Properties.GetAll(std::string). */ |
| template <typename DBusInterfaceType> |
| struct CallMethodAndRead<DBusInterfaceType, PropertiesChanged<std::string>, |
| const std::string&> |
| { |
| static PropertiesChanged<std::string> |
| op(DBusInterfaceType& dbus, const std::string& busName, |
| const std::string& path, const std::string& interface, |
| const std::string& method, const std::string& propertiesInterface) |
| { |
| return dbus.getPropertiesString(busName, path, interface, method, |
| propertiesInterface); |
| } |
| }; |
| |
| /** @class MockDBusInterface |
| * @brief DBus access delegate implementation for the property watch test |
| * suite. |
| */ |
| struct MockDBusInterface |
| { |
| MOCK_METHOD6(mapperGetObject, |
| GetObject(const std::string&, const std::string&, |
| const std::string&, const std::string&, |
| const MapperPath&, const std::vector<std::string>&)); |
| |
| MOCK_METHOD5(getPropertiesU64, |
| PropertiesChanged<uint64_t>( |
| const std::string&, const std::string&, const std::string&, |
| const std::string&, const std::string&)); |
| |
| MOCK_METHOD5(getPropertiesU32, |
| PropertiesChanged<uint32_t>( |
| const std::string&, const std::string&, const std::string&, |
| const std::string&, const std::string&)); |
| |
| MOCK_METHOD5(getPropertiesU16, |
| PropertiesChanged<uint16_t>( |
| const std::string&, const std::string&, const std::string&, |
| const std::string&, const std::string&)); |
| |
| MOCK_METHOD5(getPropertiesU8, |
| PropertiesChanged<uint8_t>( |
| const std::string&, const std::string&, const std::string&, |
| const std::string&, const std::string&)); |
| |
| MOCK_METHOD5(getPropertiesS64, |
| PropertiesChanged<int64_t>( |
| const std::string&, const std::string&, const std::string&, |
| const std::string&, const std::string&)); |
| |
| MOCK_METHOD5(getPropertiesS32, |
| PropertiesChanged<int32_t>( |
| const std::string&, const std::string&, const std::string&, |
| const std::string&, const std::string&)); |
| |
| MOCK_METHOD5(getPropertiesS16, |
| PropertiesChanged<int16_t>( |
| const std::string&, const std::string&, const std::string&, |
| const std::string&, const std::string&)); |
| |
| MOCK_METHOD5(getPropertiesS8, |
| PropertiesChanged<int8_t>( |
| const std::string&, const std::string&, const std::string&, |
| const std::string&, const std::string&)); |
| |
| MOCK_METHOD5(getPropertiesString, |
| PropertiesChanged<std::string>( |
| const std::string&, const std::string&, const std::string&, |
| const std::string&, const std::string&)); |
| |
| MOCK_METHOD2(fwdAddMatch, |
| void(const std::string&, |
| const sdbusplus::bus::match::match::callback_t&)); |
| |
| static MockDBusInterface* ptr; |
| static MockDBusInterface& instance() |
| { |
| return *ptr; |
| } |
| static void instance(MockDBusInterface& p) |
| { |
| ptr = &p; |
| } |
| |
| /** @brief GMock member template/free function forward. */ |
| template <typename Ret, typename... Args> |
| static auto callMethodAndRead(const std::string& busName, |
| const std::string& path, |
| const std::string& interface, |
| const std::string& method, Args&&... args) |
| { |
| return CallMethodAndRead<MockDBusInterface, Ret, Args...>::op( |
| instance(), busName, path, interface, method, |
| std::forward<Args>(args)...); |
| } |
| |
| /** @brief GMock free function forward. */ |
| static auto |
| addMatch(const std::string& match, |
| const sdbusplus::bus::match::match::callback_t& callback) |
| { |
| instance().fwdAddMatch(match, callback); |
| } |
| }; |
| |
| /** @class Expect |
| * @brief Enable use of EXPECT_CALL from a C++ template. |
| */ |
| template <typename T> |
| struct Expect |
| { |
| }; |
| |
| template <> |
| struct Expect<uint64_t> |
| { |
| template <typename MockObjType> |
| static auto& getProperties(MockObjType&& mockObj, const std::string& path, |
| const std::string& interface) |
| { |
| return EXPECT_CALL(std::forward<MockObjType>(mockObj), |
| getPropertiesU64(::testing::_, path, |
| "org.freedesktop.DBus.Properties", |
| "GetAll", interface)); |
| } |
| }; |
| |
| template <> |
| struct Expect<uint32_t> |
| { |
| template <typename MockObjType> |
| static auto& getProperties(MockObjType&& mockObj, const std::string& path, |
| const std::string& interface) |
| { |
| return EXPECT_CALL(std::forward<MockObjType>(mockObj), |
| getPropertiesU32(::testing::_, path, |
| "org.freedesktop.DBus.Properties", |
| "GetAll", interface)); |
| } |
| }; |
| |
| template <> |
| struct Expect<uint16_t> |
| { |
| template <typename MockObjType> |
| static auto& getProperties(MockObjType&& mockObj, const std::string& path, |
| const std::string& interface) |
| { |
| return EXPECT_CALL(std::forward<MockObjType>(mockObj), |
| getPropertiesU16(::testing::_, path, |
| "org.freedesktop.DBus.Properties", |
| "GetAll", interface)); |
| } |
| }; |
| |
| template <> |
| struct Expect<uint8_t> |
| { |
| template <typename MockObjType> |
| static auto& getProperties(MockObjType&& mockObj, const std::string& path, |
| const std::string& interface) |
| { |
| return EXPECT_CALL(std::forward<MockObjType>(mockObj), |
| getPropertiesU8(::testing::_, path, |
| "org.freedesktop.DBus.Properties", |
| "GetAll", interface)); |
| } |
| }; |
| |
| template <> |
| struct Expect<int64_t> |
| { |
| template <typename MockObjType> |
| static auto& getProperties(MockObjType&& mockObj, const std::string& path, |
| const std::string& interface) |
| { |
| return EXPECT_CALL(std::forward<MockObjType>(mockObj), |
| getPropertiesS64(::testing::_, path, |
| "org.freedesktop.DBus.Properties", |
| "GetAll", interface)); |
| } |
| }; |
| |
| template <> |
| struct Expect<int32_t> |
| { |
| template <typename MockObjType> |
| static auto& getProperties(MockObjType&& mockObj, const std::string& path, |
| const std::string& interface) |
| { |
| return EXPECT_CALL(std::forward<MockObjType>(mockObj), |
| getPropertiesS32(::testing::_, path, |
| "org.freedesktop.DBus.Properties", |
| "GetAll", interface)); |
| } |
| }; |
| |
| template <> |
| struct Expect<int16_t> |
| { |
| template <typename MockObjType> |
| static auto& getProperties(MockObjType&& mockObj, const std::string& path, |
| const std::string& interface) |
| { |
| return EXPECT_CALL(std::forward<MockObjType>(mockObj), |
| getPropertiesS16(::testing::_, path, |
| "org.freedesktop.DBus.Properties", |
| "GetAll", interface)); |
| } |
| }; |
| |
| template <> |
| struct Expect<int8_t> |
| { |
| template <typename MockObjType> |
| static auto& getProperties(MockObjType&& mockObj, const std::string& path, |
| const std::string& interface) |
| { |
| return EXPECT_CALL(std::forward<MockObjType>(mockObj), |
| getPropertiesS8(::testing::_, path, |
| "org.freedesktop.DBus.Properties", |
| "GetAll", interface)); |
| } |
| }; |
| |
| template <> |
| struct Expect<std::string> |
| { |
| template <typename MockObjType> |
| static auto& getProperties(MockObjType&& mockObj, const std::string& path, |
| const std::string& interface) |
| { |
| return EXPECT_CALL( |
| std::forward<MockObjType>(mockObj), |
| getPropertiesString(::testing::_, path, |
| "org.freedesktop.DBus.Properties", "GetAll", |
| interface)); |
| } |
| }; |
| |
| } // namespace monitoring |
| } // namespace dbus |
| } // namespace phosphor |