pldm: Move the updateDbusProperty method to the common utils

The updateDbusProperty method defined in libpldmresponder/bios_parse.cpp
and need to moved pldm/utils.hpp.
Add the updateDbusProperty method to Mock test class and remove the
setDbusProperty method in Mock test class.

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: Ib1c339af41df7f625d6976c192a3b72ce06b04a2
diff --git a/libpldmresponder/bios.cpp b/libpldmresponder/bios.cpp
index a246bb7..f9f3a55 100644
--- a/libpldmresponder/bios.cpp
+++ b/libpldmresponder/bios.cpp
@@ -21,6 +21,7 @@
 namespace fs = std::filesystem;
 using namespace pldm::responder::bios;
 using namespace bios_parser;
+using namespace pldm::utils;
 
 constexpr auto stringTableFile = "stringTable";
 constexpr auto attrTableFile = "attributeTable";
@@ -208,11 +209,12 @@
     uint64_t timeUsec = std::chrono::duration_cast<std::chrono::microseconds>(
                             std::chrono::seconds(timeSec))
                             .count();
-    std::variant<uint64_t> value{timeUsec};
+    PropertyValue value{timeUsec};
     try
     {
-        pldm::utils::DBusHandler().setDbusProperty(setTimePath, timeSetPro,
-                                                   setTimeInterface, value);
+        DBusMapping dbusMapping{setTimePath, setTimeInterface, timeSetPro,
+                                "uint64_t"};
+        pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
     }
     catch (std::exception& e)
     {
diff --git a/libpldmresponder/bios_parser.cpp b/libpldmresponder/bios_parser.cpp
index 2dc2e57..0b74059 100644
--- a/libpldmresponder/bios_parser.cpp
+++ b/libpldmresponder/bios_parser.cpp
@@ -17,6 +17,7 @@
 namespace bios_parser
 {
 
+using namespace pldm::utils;
 using Json = nlohmann::json;
 namespace fs = std::filesystem;
 using namespace pldm::responder::bios;
@@ -24,21 +25,11 @@
 const std::vector<Json> emptyJsonList{};
 const Json emptyJson{};
 
-struct DBusMapping
-{
-    std::string objectPath;   //!< D-Bus object path
-    std::string interface;    //!< D-Bus interface
-    std::string propertyName; //!< D-Bus property name
-    std::string propertyType; //!< D-Bus property type
-};
-
 using AttrType = uint8_t;
 using Table = std::vector<uint8_t>;
 using BIOSJsonName = std::string;
 using AttrLookup = std::map<AttrName, std::optional<DBusMapping>>;
-using PropertyValue =
-    std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t,
-                 uint64_t, double, std::string>;
+
 const std::set<std::string> SupportedDbusPropertyTypes = {
     "bool",     "uint8_t", "int16_t",  "uint16_t", "int32_t",
     "uint32_t", "int64_t", "uint64_t", "double",   "string"};
@@ -173,66 +164,6 @@
 
     return valueMap;
 }
-
-void updateDbusProperty(const DBusMapping& dBusMap, const PropertyValue& value)
-{
-    auto setDbusProperty = [&dBusMap](const auto& variant) {
-        pldm::utils::DBusHandler().setDbusProperty(
-            dBusMap.objectPath.c_str(), dBusMap.propertyName.c_str(),
-            dBusMap.interface.c_str(), variant);
-    };
-
-    if (dBusMap.propertyType == "uint8_t")
-    {
-        std::variant<uint8_t> v = std::get<uint8_t>(value);
-        setDbusProperty(v);
-    }
-    else if (dBusMap.propertyType == "int16_t")
-    {
-        std::variant<int16_t> v = std::get<int16_t>(value);
-        setDbusProperty(v);
-    }
-    else if (dBusMap.propertyType == "uint16_t")
-    {
-        std::variant<uint16_t> v = std::get<uint16_t>(value);
-        setDbusProperty(v);
-    }
-    else if (dBusMap.propertyType == "int32_t")
-    {
-        std::variant<int32_t> v = std::get<int32_t>(value);
-        setDbusProperty(v);
-    }
-    else if (dBusMap.propertyType == "uint32_t")
-    {
-        std::variant<uint32_t> v = std::get<uint32_t>(value);
-        setDbusProperty(v);
-    }
-    else if (dBusMap.propertyType == "int64_t")
-    {
-        std::variant<int64_t> v = std::get<int64_t>(value);
-        setDbusProperty(v);
-    }
-    else if (dBusMap.propertyType == "uint64_t")
-    {
-        std::variant<uint64_t> v = std::get<uint64_t>(value);
-        setDbusProperty(v);
-    }
-    else if (dBusMap.propertyType == "double")
-    {
-        std::variant<double> v = std::get<double>(value);
-        setDbusProperty(v);
-    }
-    else if (dBusMap.propertyType == "string")
-    {
-        std::variant<std::string> v = std::get<std::string>(value);
-        setDbusProperty(v);
-    }
-    else
-    {
-        assert(false && "UnSpported Dbus Type");
-    }
-}
-
 } // namespace internal
 
 int setupBIOSStrings(const Json& entry, Strings& strings)
@@ -352,7 +283,7 @@
         return PLDM_ERROR;
     }
 
-    internal::updateDbusProperty(dBusMap.value(), it->first);
+    pldm::utils::DBusHandler().setDbusProperty(dBusMap.value(), it->first);
 
     return PLDM_SUCCESS;
 }
@@ -503,12 +434,9 @@
     std::vector<uint8_t> data(currentString.ptr,
                               currentString.ptr + currentString.length);
 
-    std::variant<std::string> value =
+    PropertyValue value =
         stringToUtf8(static_cast<BIOSStringEncoding>(stringType), data);
-
-    pldm::utils::DBusHandler().setDbusProperty(
-        dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
-        dBusMap->interface.c_str(), value);
+    pldm::utils::DBusHandler().setDbusProperty(dBusMap.value(), value);
 
     return PLDM_SUCCESS;
 }
@@ -556,55 +484,6 @@
     return 0;
 }
 
-void updateDbusProperty(const DBusMapping& dBusMap, uint64_t value)
-{
-    auto setDbusProperty = [&dBusMap](const auto& variant) {
-        pldm::utils::DBusHandler().setDbusProperty(
-            dBusMap.objectPath.c_str(), dBusMap.propertyName.c_str(),
-            dBusMap.interface.c_str(), variant);
-    };
-
-    if (dBusMap.propertyType == "uint8_t")
-    {
-        std::variant<uint8_t> v = value;
-        setDbusProperty(v);
-    }
-    else if (dBusMap.propertyType == "int16_t")
-    {
-        std::variant<int16_t> v = value;
-        setDbusProperty(v);
-    }
-    else if (dBusMap.propertyType == "uint16_t")
-    {
-        std::variant<uint16_t> v = value;
-        setDbusProperty(v);
-    }
-    else if (dBusMap.propertyType == "int32_t")
-    {
-        std::variant<int32_t> v = value;
-        setDbusProperty(v);
-    }
-    else if (dBusMap.propertyType == "uint32_t")
-    {
-        std::variant<uint32_t> v = value;
-        setDbusProperty(v);
-    }
-    else if (dBusMap.propertyType == "int64_t")
-    {
-        std::variant<int64_t> v = value;
-        setDbusProperty(v);
-    }
-    else if (dBusMap.propertyType == "uint64_t")
-    {
-        std::variant<uint64_t> v = value;
-        setDbusProperty(v);
-    }
-    else
-    {
-        assert(false && "Unsupported Dbus Type");
-    }
-}
-
 const AttrValuesMap& getValues()
 {
     return valueMap;
@@ -639,7 +518,8 @@
     uint64_t currentValue =
         pldm_bios_table_attr_value_entry_integer_decode_cv(attrValueEntry);
 
-    updateDbusProperty(dBusMap.value(), currentValue);
+    PropertyValue value = static_cast<uint64_t>(currentValue);
+    pldm::utils::DBusHandler().setDbusProperty(dBusMap.value(), value);
 
     return PLDM_SUCCESS;
 }
diff --git a/libpldmresponder/platform.hpp b/libpldmresponder/platform.hpp
index 8bcc596..8c9e45c 100644
--- a/libpldmresponder/platform.hpp
+++ b/libpldmresponder/platform.hpp
@@ -102,6 +102,7 @@
         const std::vector<set_effecter_state_field>& stateField)
     {
         using namespace pldm::responder::pdr;
+        using namespace pldm::utils;
         using namespace std::string_literals;
         using DBusProperty = std::variant<std::string, bool>;
         using StateSetId = uint16_t;
@@ -181,23 +182,23 @@
                                    << "\n";
                          return PLDM_ERROR_INVALID_DATA;
                      }
-                     auto dbusProp = "OperatingSystemState";
-                     std::variant<std::string> value{
-                         std::get<std::string>(iter->second)};
-                     auto dbusInterface =
-                         "xyz.openbmc_project.State.OperatingSystem.Status";
+                     PropertyValue value{std::get<std::string>(iter->second)};
+                     DBusMapping dbusMapping{
+                         objPath,
+                         "xyz.openbmc_project.State.OperatingSystem.Status",
+                         "OperatingSystemState", "string"};
                      try
                      {
-                         dBusIntf.setDbusProperty(objPath.c_str(), dbusProp,
-                                                  dbusInterface, value);
+                         dBusIntf.setDbusProperty(dbusMapping, value);
                      }
                      catch (const std::exception& e)
                      {
                          std::cerr
                              << "Error setting property, ERROR=" << e.what()
-                             << " PROPERTY=" << dbusProp
-                             << " INTERFACE=" << dbusInterface
-                             << " PATH=" << objPath.c_str() << "\n";
+                             << " PROPERTY=" << dbusMapping.propertyName
+                             << " INTERFACE="
+                             << dbusMapping.interface << " PATH="
+                             << dbusMapping.objectPath << "\n";
                          return PLDM_ERROR;
                      }
                      return PLDM_SUCCESS;
@@ -226,22 +227,22 @@
                                    << "\n";
                          return PLDM_ERROR_INVALID_DATA;
                      }
-                     auto dbusProp = "RequestedPowerTransition";
-                     std::variant<std::string> value{
-                         std::get<std::string>(iter->second)};
-                     auto dbusInterface = "xyz.openbmc_project.State.Chassis";
+                     PropertyValue value{std::get<std::string>(iter->second)};
+                     DBusMapping dbusMapping{
+                         objPath, "xyz.openbmc_project.State.Chassis",
+                         "RequestedPowerTransition", "string"};
                      try
                      {
-                         dBusIntf.setDbusProperty(objPath.c_str(), dbusProp,
-                                                  dbusInterface, value);
+                         dBusIntf.setDbusProperty(dbusMapping, value);
                      }
                      catch (const std::exception& e)
                      {
                          std::cerr
                              << "Error setting property, ERROR=" << e.what()
-                             << " PROPERTY=" << dbusProp
-                             << " INTERFACE=" << dbusInterface
-                             << " PATH=" << objPath.c_str() << "\n";
+                             << " PROPERTY=" << dbusMapping.propertyName
+                             << " INTERFACE="
+                             << dbusMapping.interface << " PATH="
+                             << dbusMapping.objectPath << "\n";
                          return PLDM_ERROR;
                      }
                      return PLDM_SUCCESS;
diff --git a/test/libpldmresponder_platform_test.cpp b/test/libpldmresponder_platform_test.cpp
index d1241c2..2e99f5a 100644
--- a/test/libpldmresponder_platform_test.cpp
+++ b/test/libpldmresponder_platform_test.cpp
@@ -1,13 +1,12 @@
 #include "libpldmresponder/pdr.hpp"
 #include "libpldmresponder/pdr_utils.hpp"
 #include "libpldmresponder/platform.hpp"
+#include "mocked_utils.hpp"
+#include "utils.hpp"
 
 #include <iostream>
 
-#include <gmock/gmock-matchers.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
+using namespace pldm::utils;
 using namespace pldm::responder;
 using namespace pldm::responder::platform;
 using namespace pldm::responder::pdr;
@@ -175,26 +174,6 @@
     pldm_pdr_destroy(pdrRepo);
 }
 
-namespace pldm
-{
-
-namespace responder
-{
-
-class MockdBusHandler
-{
-  public:
-    MOCK_CONST_METHOD4(setDbusProperty,
-                       int(const std::string&, const std::string&,
-                           const std::string&,
-                           const std::variant<std::string>&));
-};
-} // namespace responder
-} // namespace pldm
-
-using ::testing::_;
-using ::testing::Return;
-
 TEST(setStateEffecterStatesHandler, testGoodRequest)
 {
     auto inPDRRepo = pldm_pdr_init();
@@ -213,16 +192,16 @@
     std::vector<set_effecter_state_field> stateField;
     stateField.push_back({PLDM_REQUEST_SET, 1});
     stateField.push_back({PLDM_REQUEST_SET, 1});
-
-    auto bootProgressInf = "xyz.openbmc_project.State.OperatingSystem.Status";
-    auto bootProgressProp = "OperatingSystemState";
-    std::string objPath = "/foo/bar";
-    std::variant<std::string> value{"xyz.openbmc_project.State.OperatingSystem."
-                                    "Status.OSStatus.Standby"};
+    std::string value = "xyz.openbmc_project.State.OperatingSystem."
+                        "Status.OSStatus.Standby";
+    PropertyValue propertyValue = value;
 
     MockdBusHandler handlerObj;
-    EXPECT_CALL(handlerObj, setDbusProperty(objPath, bootProgressProp,
-                                            bootProgressInf, value))
+    DBusMapping dbusMapping{"/foo/bar",
+                            "xyz.openbmc_project.State.OperatingSystem.Status",
+                            "OperatingSystemState", "string"};
+
+    EXPECT_CALL(handlerObj, setDbusProperty(dbusMapping, propertyValue))
         .Times(2);
     auto rc = handler.setStateEffecterStatesHandler<MockdBusHandler>(
         handlerObj, 0x1, stateField);
diff --git a/test/mocked_utils.hpp b/test/mocked_utils.hpp
new file mode 100644
index 0000000..39ac8bb
--- /dev/null
+++ b/test/mocked_utils.hpp
@@ -0,0 +1,35 @@
+#pragma once
+
+#include "utils.hpp"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace pldm
+{
+namespace utils
+{
+
+/** @brief helper function for parameter matching
+ *  @param[in] lhs - left-hand side value
+ *  @param[in] rhs - right-hand side value
+ *  @return true if it matches
+ */
+inline bool operator==(const DBusMapping& lhs, const DBusMapping& rhs)
+{
+    return lhs.objectPath == rhs.objectPath && lhs.interface == rhs.interface &&
+           lhs.propertyName == rhs.propertyName &&
+           lhs.propertyType == rhs.propertyType;
+}
+
+} // namespace utils
+} // namespace pldm
+
+using namespace pldm::utils;
+
+class MockdBusHandler : public DBusHandler
+{
+  public:
+    MOCK_METHOD(void, setDbusProperty,
+                (const DBusMapping&, const PropertyValue&), (const override));
+};
diff --git a/utils.cpp b/utils.cpp
index 846297a..836591b 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -116,5 +116,70 @@
     }
 }
 
+void DBusHandler::setDbusProperty(const DBusMapping& dBusMap,
+                                  const PropertyValue& value) const
+{
+    auto setDbusValue = [&dBusMap, this](const auto& variant) {
+        auto& bus = getBus();
+        auto service =
+            getService(dBusMap.objectPath.c_str(), dBusMap.interface.c_str());
+        auto method = bus.new_method_call(
+            service.c_str(), dBusMap.objectPath.c_str(), dbusProperties, "Set");
+        method.append(dBusMap.interface.c_str(), dBusMap.propertyName.c_str(),
+                      variant);
+        bus.call_noreply(method);
+    };
+
+    if (dBusMap.propertyType == "uint8_t")
+    {
+        std::variant<uint8_t> v = std::get<uint8_t>(value);
+        setDbusValue(v);
+    }
+    else if (dBusMap.propertyType == "int16_t")
+    {
+        std::variant<int16_t> v = std::get<int16_t>(value);
+        setDbusValue(v);
+    }
+    else if (dBusMap.propertyType == "uint16_t")
+    {
+        std::variant<uint16_t> v = std::get<uint16_t>(value);
+        setDbusValue(v);
+    }
+    else if (dBusMap.propertyType == "int32_t")
+    {
+        std::variant<int32_t> v = std::get<int32_t>(value);
+        setDbusValue(v);
+    }
+    else if (dBusMap.propertyType == "uint32_t")
+    {
+        std::variant<uint32_t> v = std::get<uint32_t>(value);
+        setDbusValue(v);
+    }
+    else if (dBusMap.propertyType == "int64_t")
+    {
+        std::variant<int64_t> v = std::get<int64_t>(value);
+        setDbusValue(v);
+    }
+    else if (dBusMap.propertyType == "uint64_t")
+    {
+        std::variant<uint64_t> v = std::get<uint64_t>(value);
+        setDbusValue(v);
+    }
+    else if (dBusMap.propertyType == "double")
+    {
+        std::variant<double> v = std::get<double>(value);
+        setDbusValue(v);
+    }
+    else if (dBusMap.propertyType == "string")
+    {
+        std::variant<std::string> v = std::get<std::string>(value);
+        setDbusValue(v);
+    }
+    else
+    {
+        throw std::invalid_argument("UnSpported Dbus Type");
+    }
+}
+
 } // namespace utils
 } // namespace pldm
diff --git a/utils.hpp b/utils.hpp
index db49f51..bfbfb5d 100644
--- a/utils.hpp
+++ b/utils.hpp
@@ -117,6 +117,30 @@
 
 constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
 
+struct DBusMapping
+{
+    std::string objectPath;   //!< D-Bus object path
+    std::string interface;    //!< D-Bus interface
+    std::string propertyName; //!< D-Bus property name
+    std::string propertyType; //!< D-Bus property type
+};
+
+using PropertyValue =
+    std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t,
+                 uint64_t, double, std::string>;
+
+/**
+ * @brief The interface for DBusHandler
+ */
+class DBusHandlerInterface
+{
+  public:
+    virtual ~DBusHandlerInterface() = default;
+
+    virtual void setDbusProperty(const DBusMapping& dBusMap,
+                                 const PropertyValue& value) const = 0;
+};
+
 /**
  *  @class DBusHandler
  *
@@ -126,7 +150,7 @@
  *  to cater the request from pldm requester.
  *  A class is created to mock the apis in the test cases
  */
-class DBusHandler
+class DBusHandler : public DBusHandlerInterface
 {
   public:
     /** @brief Get the bus connection. */
@@ -144,27 +168,6 @@
      */
     std::string getService(const char* path, const char* interface) const;
 
-    /** @brief API to set a D-Bus property
-     *
-     *  @param[in] objPath - Object path for the D-Bus object
-     *  @param[in] dbusProp - The D-Bus property
-     *  @param[in] dbusInterface - The D-Bus interface
-     *  @param[in] value - The value to be set
-     * failure
-     */
-    template <typename T>
-    void setDbusProperty(const char* objPath, const char* dbusProp,
-                         const char* dbusInterface,
-                         const std::variant<T>& value) const
-    {
-        auto& bus = DBusHandler::getBus();
-        auto service = getService(objPath, dbusInterface);
-        auto method = bus.new_method_call(service.c_str(), objPath,
-                                          dbusProperties, "Set");
-        method.append(dbusInterface, dbusProp, value);
-        bus.call_noreply(method);
-    }
-
     template <typename Variant>
     auto getDbusPropertyVariant(const char* objPath, const char* dbusProp,
                                 const char* dbusInterface)
@@ -189,6 +192,15 @@
             objPath, dbusProp, dbusInterface);
         return std::get<Property>(VariantValue);
     }
+
+    /** @brief Set Dbus property
+     *
+     *  @param[in] dBusMap - Object path, property name, interface and property
+     *                       type for the D-Bus object
+     *  @param[in] value - The value to be set
+     */
+    void setDbusProperty(const DBusMapping& dBusMap,
+                         const PropertyValue& value) const override;
 };
 
 } // namespace utils