Create PMBusBase class to allow for mocking

Derive the PMBus class from a new PMBusBase class to allow for the use
of Google Mock for unit testing. Create an interface to PMBusBase in the
phosphor-power-supply code.

Signed-off-by: Brandon Wyman <bjwyman@gmail.com>
Change-Id: I6dd8d8a64bdece0d82478450ec83f1aefcae4c75
diff --git a/phosphor-power-supply/power_supply.hpp b/phosphor-power-supply/power_supply.hpp
index 419e1a7..c3ff051 100644
--- a/phosphor-power-supply/power_supply.hpp
+++ b/phosphor-power-supply/power_supply.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include "pmbus.hpp"
 #include "types.hpp"
 
 #include <sdbusplus/bus/match.hpp>
@@ -28,7 +29,8 @@
     PowerSupply(sdbusplus::bus::bus& bus, const std::string& invpath,
                 std::uint8_t i2cbus, const std::string& i2caddr) :
         bus(bus),
-        inventoryPath(invpath), i2cbus(i2cbus), i2caddr(i2caddr)
+        inventoryPath(invpath),
+        pmbusIntf(phosphor::pmbus::createPMBus(i2cbus, i2caddr))
     {
         // Setup the functions to call when the D-Bus inventory path for the
         // Present property changes.
@@ -108,19 +110,6 @@
      **/
     std::string inventoryPath;
 
-    /**
-     * @brief I2C bus that this power supply is on.
-     */
-    std::uint8_t i2cbus;
-
-    /**
-     * @brief I2C address of this power supply.
-     *
-     * The PMBus device driver will put this in a path with 16-bit address,
-     * represented as a file path string.
-     */
-    std::string i2caddr;
-
     /** @brief True if the power supply is present. */
     bool present = false;
 
@@ -135,6 +124,13 @@
     std::unique_ptr<sdbusplus::bus::match_t> presentAddedMatch;
 
     /**
+     * @brief Pointer to the PMBus interface
+     *
+     * Used to read or write to/from PMBus power supply devices.
+     */
+    std::unique_ptr<phosphor::pmbus::PMBusBase> pmbusIntf;
+
+    /**
      *  @brief Updates the presence status by querying D-Bus
      *
      * The D-Bus inventory properties for this power supply will be read to
diff --git a/pmbus.cpp b/pmbus.cpp
index 5c16624..d8b1804 100644
--- a/pmbus.cpp
+++ b/pmbus.cpp
@@ -336,5 +336,21 @@
     }
 }
 
+std::unique_ptr<PMBusBase> PMBus::createPMBus(std::uint8_t bus,
+                                              const std::string& address)
+{
+    const std::string physpath = {"/sys/bus/i2c/devices/" +
+                                  std::to_string(bus) + "-" + address};
+    auto interface = std::make_unique<PMBus>(physpath);
+
+    return interface;
+}
+
+std::unique_ptr<PMBusBase> createPMBus(std::uint8_t bus,
+                                       const std::string& address)
+{
+    return PMBus::createPMBus(bus, address);
+}
+
 } // namespace pmbus
 } // namespace phosphor
diff --git a/pmbus.hpp b/pmbus.hpp
index 4635915..89c3118 100644
--- a/pmbus.hpp
+++ b/pmbus.hpp
@@ -110,6 +110,28 @@
 };
 
 /**
+ * @class PMBusBase
+ *
+ * This is a base class for PMBus to assist with unit testing via mocking.
+ */
+class PMBusBase
+{
+  public:
+    virtual ~PMBusBase() = default;
+};
+
+/**
+ * Wrapper function for PMBus
+ *
+ * @param[in] bus - I2C bus
+ * @param[in] address - I2C address (as a 2-byte string, e.g. 0069)
+ *
+ * @return PMBusBase pointer
+ */
+std::unique_ptr<PMBusBase> createPMBus(std::uint8_t bus,
+                                       const std::string& address);
+
+/**
  * @class PMBus
  *
  * This class is an interface to communicating with PMBus devices
@@ -119,11 +141,11 @@
  * in the base device directory (the one passed into the constructor),
  * or in the hwmon directory for the device.
  */
-class PMBus
+class PMBus : public PMBusBase
 {
   public:
     PMBus() = delete;
-    ~PMBus() = default;
+    virtual ~PMBus() = default;
     PMBus(const PMBus&) = default;
     PMBus& operator=(const PMBus&) = default;
     PMBus(PMBus&&) = default;
@@ -158,6 +180,17 @@
     }
 
     /**
+     * Wrapper function for PMBus
+     *
+     * @param[in] bus - I2C bus
+     * @param[in] address - I2C address (as a 2-byte string, e.g. 0069)
+     *
+     * @return PMBusBase pointer
+     */
+    static std::unique_ptr<PMBusBase> createPMBus(std::uint8_t bus,
+                                                  const std::string& address);
+
+    /**
      * Reads a file in sysfs that represents a single bit,
      * therefore doing a PMBus read.
      *