Add testcases for property watches

Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
Change-Id: I9e9266901414c71a34d9686f2a45bc4764602d53
diff --git a/src/test/propertywatchtest.hpp b/src/test/propertywatchtest.hpp
new file mode 100644
index 0000000..f965096
--- /dev/null
+++ b/src/test/propertywatchtest.hpp
@@ -0,0 +1,628 @@
+#pragma once
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <string>
+
+#include "data_types.hpp"
+#include "sdbusplus/bus/match.hpp"
+
+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