regulators: Add configure support to Chassis class

Implemented the configure() method in the Chassis class.  This method
configures all the regulator devices within the chassis.

Also made very minor fixes to two testcases.

Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
Change-Id: Ib29fdfa36e59f6b79d9467cdc52c3c6fc9c6886d
diff --git a/phosphor-regulators/src/chassis.cpp b/phosphor-regulators/src/chassis.cpp
index 3787365..3390ec5 100644
--- a/phosphor-regulators/src/chassis.cpp
+++ b/phosphor-regulators/src/chassis.cpp
@@ -16,6 +16,9 @@
 
 #include "chassis.hpp"
 
+#include "journal.hpp"
+#include "system.hpp"
+
 namespace phosphor::power::regulators
 {
 
@@ -28,4 +31,16 @@
     }
 }
 
+void Chassis::configure(System& system)
+{
+    // Log info message in journal; important for verifying success of boot
+    journal::logInfo("Configuring chassis " + std::to_string(number));
+
+    // Configure devices
+    for (std::unique_ptr<Device>& device : devices)
+    {
+        device->configure(system, *this);
+    }
+}
+
 } // namespace phosphor::power::regulators
diff --git a/phosphor-regulators/src/chassis.hpp b/phosphor-regulators/src/chassis.hpp
index 1fe74cb..354da30 100644
--- a/phosphor-regulators/src/chassis.hpp
+++ b/phosphor-regulators/src/chassis.hpp
@@ -27,6 +27,9 @@
 namespace phosphor::power::regulators
 {
 
+// Forward declarations to avoid circular dependencies
+class System;
+
 /**
  * @class Chassis
  *
@@ -82,6 +85,16 @@
     void addToIDMap(IDMap& idMap);
 
     /**
+     * Configure the devices within this chassis, if any.
+     *
+     * This method should be called during the boot before regulators are
+     * enabled.
+     *
+     * @param system system that contains this chassis
+     */
+    void configure(System& system);
+
+    /**
      * Returns the devices within this chassis, if any.
      *
      * The vector contains regulator devices and any related devices
diff --git a/phosphor-regulators/test/chassis_tests.cpp b/phosphor-regulators/test/chassis_tests.cpp
index 0f66d24..25722ae 100644
--- a/phosphor-regulators/test/chassis_tests.cpp
+++ b/phosphor-regulators/test/chassis_tests.cpp
@@ -13,14 +13,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include "action.hpp"
 #include "chassis.hpp"
+#include "configuration.hpp"
 #include "device.hpp"
 #include "i2c_interface.hpp"
 #include "id_map.hpp"
+#include "journal.hpp"
+#include "mock_journal.hpp"
+#include "presence_detection.hpp"
+#include "rail.hpp"
+#include "rule.hpp"
+#include "system.hpp"
 #include "test_utils.hpp"
 
 #include <memory>
 #include <stdexcept>
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -95,6 +104,93 @@
     EXPECT_THROW(idMap.getRail("rail3"), std::invalid_argument);
 }
 
+TEST(ChassisTests, Configure)
+{
+    // Test where no devices were specified in constructor
+    {
+        // Create Chassis
+        std::unique_ptr<Chassis> chassis = std::make_unique<Chassis>(1);
+        Chassis* chassisPtr = chassis.get();
+
+        // Create System that contains Chassis
+        std::vector<std::unique_ptr<Rule>> rules{};
+        std::vector<std::unique_ptr<Chassis>> chassisVec{};
+        chassisVec.emplace_back(std::move(chassis));
+        System system{std::move(rules), std::move(chassisVec)};
+
+        // Call configure()
+        journal::clear();
+        chassisPtr->configure(system);
+        EXPECT_EQ(journal::getDebugMessages().size(), 0);
+        EXPECT_EQ(journal::getErrMessages().size(), 0);
+        std::vector<std::string> expectedInfoMessages{"Configuring chassis 1"};
+        EXPECT_EQ(journal::getInfoMessages(), expectedInfoMessages);
+    }
+
+    // Test where devices were specified in constructor
+    {
+        std::vector<std::unique_ptr<Device>> devices{};
+
+        // Create Device vdd0_reg
+        {
+            // Create Configuration
+            std::vector<std::unique_ptr<Action>> actions{};
+            std::unique_ptr<Configuration> configuration =
+                std::make_unique<Configuration>(1.3, std::move(actions));
+
+            // Create Device
+            std::unique_ptr<i2c::I2CInterface> i2cInterface =
+                createI2CInterface();
+            std::unique_ptr<PresenceDetection> presenceDetection{};
+            std::unique_ptr<Device> device = std::make_unique<Device>(
+                "vdd0_reg", true, "/system/chassis/motherboard/vdd0_reg",
+                std::move(i2cInterface), std::move(presenceDetection),
+                std::move(configuration));
+            devices.emplace_back(std::move(device));
+        }
+
+        // Create Device vdd1_reg
+        {
+            // Create Configuration
+            std::vector<std::unique_ptr<Action>> actions{};
+            std::unique_ptr<Configuration> configuration =
+                std::make_unique<Configuration>(1.2, std::move(actions));
+
+            // Create Device
+            std::unique_ptr<i2c::I2CInterface> i2cInterface =
+                createI2CInterface();
+            std::unique_ptr<PresenceDetection> presenceDetection{};
+            std::unique_ptr<Device> device = std::make_unique<Device>(
+                "vdd1_reg", true, "/system/chassis/motherboard/vdd1_reg",
+                std::move(i2cInterface), std::move(presenceDetection),
+                std::move(configuration));
+            devices.emplace_back(std::move(device));
+        }
+
+        // Create Chassis
+        std::unique_ptr<Chassis> chassis =
+            std::make_unique<Chassis>(2, std::move(devices));
+        Chassis* chassisPtr = chassis.get();
+
+        // Create System that contains Chassis
+        std::vector<std::unique_ptr<Rule>> rules{};
+        std::vector<std::unique_ptr<Chassis>> chassisVec{};
+        chassisVec.emplace_back(std::move(chassis));
+        System system{std::move(rules), std::move(chassisVec)};
+
+        // Call configure()
+        journal::clear();
+        chassisPtr->configure(system);
+        std::vector<std::string> expectedDebugMessages{
+            "Configuring vdd0_reg: volts=1.300000",
+            "Configuring vdd1_reg: volts=1.200000"};
+        EXPECT_EQ(journal::getDebugMessages(), expectedDebugMessages);
+        EXPECT_EQ(journal::getErrMessages().size(), 0);
+        std::vector<std::string> expectedInfoMessages{"Configuring chassis 2"};
+        EXPECT_EQ(journal::getInfoMessages(), expectedInfoMessages);
+    }
+}
+
 TEST(ChassisTests, GetDevices)
 {
     // Test where no devices were specified in constructor
diff --git a/phosphor-regulators/test/device_tests.cpp b/phosphor-regulators/test/device_tests.cpp
index 1ce065c..901f1cf 100644
--- a/phosphor-regulators/test/device_tests.cpp
+++ b/phosphor-regulators/test/device_tests.cpp
@@ -25,12 +25,12 @@
 #include "presence_detection.hpp"
 #include "rail.hpp"
 #include "rule.hpp"
-#include "sensor_monitoring.hpp"
 #include "system.hpp"
 #include "test_utils.hpp"
 
 #include <memory>
 #include <optional>
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -243,10 +243,8 @@
         journal::clear();
         devicePtr->configure(system, *chassisPtr);
         std::vector<std::string> expectedDebugMessages{
-            "Configuring reg1",
-            "Configuring vdd0: volts=1.300000",
-            "Configuring vio0: volts=3.200000",
-        };
+            "Configuring reg1", "Configuring vdd0: volts=1.300000",
+            "Configuring vio0: volts=3.200000"};
         EXPECT_EQ(journal::getDebugMessages(), expectedDebugMessages);
         EXPECT_EQ(journal::getErrMessages().size(), 0);
     }
diff --git a/phosphor-regulators/test/validate-regulators-config_tests.cpp b/phosphor-regulators/test/validate-regulators-config_tests.cpp
index 987a492..139b3ca 100644
--- a/phosphor-regulators/test/validate-regulators-config_tests.cpp
+++ b/phosphor-regulators/test/validate-regulators-config_tests.cpp
@@ -221,7 +221,7 @@
 
 void expectCommandLineSyntax(const std::string& expectedErrorMessage,
                              const std::string& expectedOutputMessage,
-                             std::string command, int status)
+                             const std::string& command, int status)
 {
     std::string errorMessage;
     std::string outputMessage;