regulators: Complete SensorMonitoring class

Complete the SensorMonitoring class.  This class implements the
"sensor_monitoring" object in the JSON config file.

Add calls to the startRail() and endRail() methods of the Sensors
service.

Add ErrorHistory data member so that errors are only logged once per
boot since sensor monitoring occurs repeatedly once per second.

Add error count data member to limit the number of error messages
written to the journal since monitoring occurs repeatedly.

Update all affected test cases.

Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
Change-Id: I0bd20d03ccea9e15cd0f97529f6ccdad2fa015c8
diff --git a/phosphor-regulators/test/rail_tests.cpp b/phosphor-regulators/test/rail_tests.cpp
index 4f52701..d852a06 100644
--- a/phosphor-regulators/test/rail_tests.cpp
+++ b/phosphor-regulators/test/rail_tests.cpp
@@ -20,9 +20,9 @@
 #include "i2c_interface.hpp"
 #include "mock_action.hpp"
 #include "mock_journal.hpp"
+#include "mock_sensors.hpp"
 #include "mock_services.hpp"
 #include "mocked_i2c_interface.hpp"
-#include "pmbus_read_sensor_action.hpp"
 #include "presence_detection.hpp"
 #include "rail.hpp"
 #include "rule.hpp"
@@ -222,22 +222,20 @@
 {
     // Test where SensorMonitoring was not specified in constructor
     {
-        // Create mock services.  No logging should occur.
+        // Create mock services.  No Sensors methods should be called.
         MockServices services{};
-        MockJournal& journal = services.getMockJournal();
-        EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
-        EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
-
-        // Create mock I2CInterface.  A two-byte read should NOT occur.
-        std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
-            std::make_unique<i2c::MockedI2CInterface>();
-        EXPECT_CALL(*i2cInterface, read(A<uint8_t>(), A<uint16_t&>())).Times(0);
+        MockSensors& sensors = services.getMockSensors();
+        EXPECT_CALL(sensors, startRail).Times(0);
+        EXPECT_CALL(sensors, setValue).Times(0);
+        EXPECT_CALL(sensors, endRail).Times(0);
 
         // Create Rail
         std::unique_ptr<Rail> rail = std::make_unique<Rail>("vdd0");
         Rail* railPtr = rail.get();
 
         // Create Device that contains Rail
+        std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
+            std::make_unique<i2c::MockedI2CInterface>();
         std::unique_ptr<PresenceDetection> presenceDetection{};
         std::unique_ptr<Configuration> deviceConfiguration{};
         std::vector<std::unique_ptr<Rail>> rails{};
@@ -262,36 +260,27 @@
         chassisVec.emplace_back(std::move(chassis));
         System system{std::move(rules), std::move(chassisVec)};
 
-        // Call monitorSensors().
+        // Call monitorSensors()
         railPtr->monitorSensors(services, system, *chassisPtr, *devicePtr);
     }
 
     // Test where SensorMonitoring was specified in constructor
     {
-        // Create mock services.  No logging should occur.
+        // Create mock services.  Set Sensors service expectations.
         MockServices services{};
-        MockJournal& journal = services.getMockJournal();
-        EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
-        EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
-
-        // Create PMBusReadSensorAction
-        SensorType type{SensorType::iout};
-        uint8_t command = 0x8C;
-        pmbus_utils::SensorDataFormat format{
-            pmbus_utils::SensorDataFormat::linear_11};
-        std::optional<int8_t> exponent{};
-        std::unique_ptr<PMBusReadSensorAction> action =
-            std::make_unique<PMBusReadSensorAction>(type, command, format,
-                                                    exponent);
-
-        // Create mock I2CInterface.  A two-byte read should occur.
-        std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
-            std::make_unique<i2c::MockedI2CInterface>();
-        EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
-        EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x8C), A<uint16_t&>()))
+        MockSensors& sensors = services.getMockSensors();
+        EXPECT_CALL(sensors,
+                    startRail("vddr1",
+                              "/xyz/openbmc_project/inventory/system/chassis/"
+                              "motherboard/reg1",
+                              chassisInvPath))
             .Times(1);
+        EXPECT_CALL(sensors, setValue).Times(0);
+        EXPECT_CALL(sensors, endRail(false)).Times(1);
 
         // Create SensorMonitoring
+        std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
+        EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
         std::vector<std::unique_ptr<Action>> actions{};
         actions.emplace_back(std::move(action));
         std::unique_ptr<SensorMonitoring> sensorMonitoring =
@@ -304,6 +293,8 @@
         Rail* railPtr = rail.get();
 
         // Create Device that contains Rail
+        std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
+            std::make_unique<i2c::MockedI2CInterface>();
         std::unique_ptr<PresenceDetection> presenceDetection{};
         std::unique_ptr<Configuration> deviceConfiguration{};
         std::vector<std::unique_ptr<Rail>> rails{};
@@ -328,7 +319,7 @@
         chassisVec.emplace_back(std::move(chassis));
         System system{std::move(rules), std::move(chassisVec)};
 
-        // Call monitorSensors().
+        // Call monitorSensors()
         railPtr->monitorSensors(services, system, *chassisPtr, *devicePtr);
     }
 }