regulators: Complete PMBusReadSensorAction class

Complete implementation of the PMBusReadSensorAction class.  Publish the
sensor value on D-Bus using the Sensors service.

Update gtests for this class to expect calls to the Sensors service.
Fix some constructor parameter combinations that did not make sense,
such as linear_16 format for non-voltage sensors.

Also refactor the TestSDBusError exception class into a separate file.
This allows it to be shared by multiple test cases.  This class is a
concrete implementation of the abstract sdbusplus::exception_t class
used for D-Bus errors.

Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
Change-Id: I5a77616b2ae5b17224c296aeee88019512649589
diff --git a/phosphor-regulators/src/actions/pmbus_read_sensor_action.cpp b/phosphor-regulators/src/actions/pmbus_read_sensor_action.cpp
index 7ad0cad..896830c 100644
--- a/phosphor-regulators/src/actions/pmbus_read_sensor_action.cpp
+++ b/phosphor-regulators/src/actions/pmbus_read_sensor_action.cpp
@@ -19,6 +19,8 @@
 #include "action_error.hpp"
 #include "pmbus_error.hpp"
 
+#include <sdbusplus/exception.hpp>
+
 #include <exception>
 #include <ios>
 #include <sstream>
@@ -33,37 +35,39 @@
         // Get I2C interface to current device
         i2c::I2CInterface& interface = getI2CInterface(environment);
 
-        // Read value of the PMBus command code
-        uint16_t value;
+        // Read two byte value of PMBus command code.  I2CInterface method reads
+        // low byte first as required by PMBus.
+        uint16_t value{0x00};
         interface.read(command, value);
 
-        // Convert PMBus 2-byte value to a double
-        // TODO: Store result of conversion in a double.  Not doing it yet
-        // because it results in an unused variable compile error during CI.
+        // Convert two byte PMBus value into a decimal sensor value
+        double sensorValue{0.0};
         switch (format)
         {
             case pmbus_utils::SensorDataFormat::linear_11:
-                // Convert linear_11 format to a normal decimal number
-                pmbus_utils::convertFromLinear(value);
+                sensorValue = pmbus_utils::convertFromLinear(value);
                 break;
             case pmbus_utils::SensorDataFormat::linear_16:
-                // Get exponent value for converting linear format to volts
                 int8_t exponentValue = getExponentValue(environment, interface);
-
-                // Convert linear_16 format to a normal decimal number
-                pmbus_utils::convertFromVoutLinear(value, exponentValue);
+                sensorValue =
+                    pmbus_utils::convertFromVoutLinear(value, exponentValue);
                 break;
         }
 
-        // TODO: Publish sensor value using Sensors service
+        // Publish sensor value using the Sensors service
+        environment.getServices().getSensors().setValue(type, sensorValue);
     }
     // Nest the following exception types within an ActionError so the caller
     // will have both the low level error information and the action information
-    catch (const i2c::I2CException& i2cError)
+    catch (const i2c::I2CException& e)
     {
         std::throw_with_nested(ActionError(*this));
     }
-    catch (const PMBusError& pmbusError)
+    catch (const PMBusError& e)
+    {
+        std::throw_with_nested(ActionError(*this));
+    }
+    catch (const sdbusplus::exception_t& e)
     {
         std::throw_with_nested(ActionError(*this));
     }
diff --git a/phosphor-regulators/test/actions/pmbus_read_sensor_action_tests.cpp b/phosphor-regulators/test/actions/pmbus_read_sensor_action_tests.cpp
index f0ad7c2..2e57ac2 100644
--- a/phosphor-regulators/test/actions/pmbus_read_sensor_action_tests.cpp
+++ b/phosphor-regulators/test/actions/pmbus_read_sensor_action_tests.cpp
@@ -16,7 +16,6 @@
 #include "action_environment.hpp"
 #include "action_error.hpp"
 #include "device.hpp"
-#include "i2c_action.hpp"
 #include "i2c_interface.hpp"
 #include "id_map.hpp"
 #include "mock_services.hpp"
@@ -25,8 +24,10 @@
 #include "pmbus_read_sensor_action.hpp"
 #include "pmbus_utils.hpp"
 #include "sensors.hpp"
+#include "test_sdbus_error.hpp"
 
 #include <cstdint>
+#include <exception>
 #include <memory>
 #include <optional>
 #include <stdexcept>
@@ -37,6 +38,7 @@
 #include <gtest/gtest.h>
 
 using namespace phosphor::power::regulators;
+using namespace phosphor::power::regulators::pmbus_utils;
 
 using ::testing::A;
 using ::testing::Return;
@@ -47,56 +49,47 @@
 TEST(PMBusReadSensorActionTests, Constructor)
 {
     // Test where works: exponent value is specified
-    try
     {
-        SensorType type{SensorType::iout};
-        uint8_t command = 0x8C;
-        pmbus_utils::SensorDataFormat format{
-            pmbus_utils::SensorDataFormat::linear_16};
+        SensorType type{SensorType::vout};
+        uint8_t command{0x8B};
+        SensorDataFormat format{SensorDataFormat::linear_16};
         std::optional<int8_t> exponent{-8};
         PMBusReadSensorAction action{type, command, format, exponent};
-        EXPECT_EQ(action.getType(), SensorType::iout);
-        EXPECT_EQ(action.getCommand(), 0x8C);
-        EXPECT_EQ(action.getFormat(), pmbus_utils::SensorDataFormat::linear_16);
+        EXPECT_EQ(action.getType(), SensorType::vout);
+        EXPECT_EQ(action.getCommand(), 0x8B);
+        EXPECT_EQ(action.getFormat(), SensorDataFormat::linear_16);
         EXPECT_EQ(action.getExponent().has_value(), true);
         EXPECT_EQ(action.getExponent().value(), -8);
     }
-    catch (...)
-    {
-        ADD_FAILURE() << "Should not have caught exception.";
-    }
 
     // Test where works: exponent value is not specified
-    try
     {
         SensorType type{SensorType::iout};
-        uint8_t command = 0x8C;
-        pmbus_utils::SensorDataFormat format{
-            pmbus_utils::SensorDataFormat::linear_11};
+        uint8_t command{0x8C};
+        SensorDataFormat format{SensorDataFormat::linear_11};
         std::optional<int8_t> exponent{};
         PMBusReadSensorAction action{type, command, format, exponent};
         EXPECT_EQ(action.getType(), SensorType::iout);
         EXPECT_EQ(action.getCommand(), 0x8C);
-        EXPECT_EQ(action.getFormat(), pmbus_utils::SensorDataFormat::linear_11);
+        EXPECT_EQ(action.getFormat(), SensorDataFormat::linear_11);
         EXPECT_EQ(action.getExponent().has_value(), false);
     }
-    catch (...)
-    {
-        ADD_FAILURE() << "Should not have caught exception.";
-    }
 }
 
 TEST(PMBusReadSensorActionTests, Execute)
 {
-    // Test where works: linear_11 defined in action
+    // Test where works: linear_11 format
     try
     {
-        // Create mock I2CInterface.
+        // Determine READ_IOUT linear data value and decimal value
+        // * 5 bit exponent: -6 = 11010
+        // * 11 bit mantissa: 736 = 010 1110 0000
+        // * linear data format = 1101 0010 1110 0000 = 0xD2E0
+        // * Decimal value: 736 * 2^(-6) = 11.5
+
+        // Create mock I2CInterface.  Expect action to do the following:
         // * will read 0xD2E0 from READ_IOUT (command/register 0x8C)
         // * will not read from VOUT_MODE (command/register 0x20)
-        // assume output current is 11.5 amps,
-        // exponent = -6 = 11010, mantissa = 736 = 010 1110 0000
-        // linear data format = 1101 0010 1110 0000 = 0xD2E0
         std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
             std::make_unique<i2c::MockedI2CInterface>();
         EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
@@ -105,130 +98,124 @@
             .WillOnce(SetArgReferee<1>(0xD2E0));
         EXPECT_CALL(*i2cInterface, read(A<uint8_t>(), A<uint8_t&>())).Times(0);
 
-        // Create Device, IDMap, MockServices, and ActionEnvironment
+        // Create MockServices.  Expect the sensor value to be set.
+        MockServices services{};
+        MockSensors& sensors = services.getMockSensors();
+        EXPECT_CALL(sensors, setValue(SensorType::iout, 11.5)).Times(1);
+
+        // Create Device, IDMap, and ActionEnvironment
         Device device{
             "reg1", true,
             "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
             std::move(i2cInterface)};
         IDMap idMap{};
         idMap.addDevice(device);
-        MockServices services{};
         ActionEnvironment env{idMap, "reg1", services};
 
         // Create and execute action
         SensorType type{SensorType::iout};
-        uint8_t command = 0x8C;
-        pmbus_utils::SensorDataFormat format{
-            pmbus_utils::SensorDataFormat::linear_11};
+        uint8_t command{0x8C};
+        SensorDataFormat format{SensorDataFormat::linear_11};
         std::optional<int8_t> exponent{};
         PMBusReadSensorAction action{type, command, format, exponent};
         EXPECT_EQ(action.execute(env), true);
-        /**
-         * TODO: Replace with EXPECT calls using MockSensors
-         *
-         *  EXPECT_EQ(env.getSensorReadings().size(), 1);
-         *  EXPECT_EQ(env.getSensorReadings()[0].type,
-         *            SensorType::iout);
-         *  EXPECT_DOUBLE_EQ(env.getSensorReadings()[0].value, 11.5);
-         */
     }
     catch (...)
     {
         ADD_FAILURE() << "Should not have caught exception.";
     }
 
-    // Test where works: linear_16 with exponent defined in action
+    // Test where works: linear_16 format: exponent specified in constructor
     try
     {
-        // Create mock I2CInterface.
-        // * will read 0x0002 from READ_VOUT (command/register 0x8B)
+        // Determine READ_VOUT linear data value and decimal value
+        // * Exponent: -8
+        // * 16 bit mantissa: 816 = 0000 0011 0011 0000
+        // * linear data format = 0000 0011 0011 0000 = 0x0330
+        // * Decimal value: 816 * 2^(-8) = 3.1875
+
+        // Create mock I2CInterface.  Expect action to do the following:
+        // * will read 0x0330 from READ_VOUT (command/register 0x8B)
         // * will not read from VOUT_MODE (command/register 0x20)
-        // assume output voltage is 16 volts,
-        // exponent = 3
-        // linear data format = 0000 0000 0000 0010 = 0x0002 = 2
         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>(0x8B), A<uint16_t&>()))
             .Times(1)
-            .WillOnce(SetArgReferee<1>(0x0002));
+            .WillOnce(SetArgReferee<1>(0x0330));
         EXPECT_CALL(*i2cInterface, read(A<uint8_t>(), A<uint8_t&>())).Times(0);
 
-        // Create Device, IDMap, MockServices, and ActionEnvironment
+        // Create MockServices.  Expect the sensor value to be set.
+        MockServices services{};
+        MockSensors& sensors = services.getMockSensors();
+        EXPECT_CALL(sensors, setValue(SensorType::vout, 3.1875)).Times(1);
+
+        // Create Device, IDMap, and ActionEnvironment
         Device device{
             "reg1", true,
             "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
             std::move(i2cInterface)};
         IDMap idMap{};
         idMap.addDevice(device);
-        MockServices services{};
         ActionEnvironment env{idMap, "reg1", services};
 
         // Create and execute action
         SensorType type{SensorType::vout};
-        uint8_t command = 0x8B;
-        pmbus_utils::SensorDataFormat format{
-            pmbus_utils::SensorDataFormat::linear_16};
-        std::optional<int8_t> exponent{3};
+        uint8_t command{0x8B};
+        SensorDataFormat format{SensorDataFormat::linear_16};
+        std::optional<int8_t> exponent{-8};
         PMBusReadSensorAction action{type, command, format, exponent};
         EXPECT_EQ(action.execute(env), true);
-        /**
-         * TODO: Replace with EXPECT calls using MockSensors
-         *
-         * EXPECT_EQ(env.getSensorReadings().size(), 1);
-         * EXPECT_EQ(env.getSensorReadings()[0].type,
-         *           SensorType::vout);
-         * EXPECT_DOUBLE_EQ(env.getSensorReadings()[0].value, 16);
-         */
     }
     catch (...)
     {
         ADD_FAILURE() << "Should not have caught exception.";
     }
 
-    // Test where works: linear_16 with no exponent defined in action
+    // Test where works: linear_16 format: exponent not specified in constructor
     try
     {
-        // Create mock I2CInterface.
-        // * will read 0xB877 from vout_peak (command/register 0xC6)
-        // * will read 0b0001'0111 (linear format, -9 exponent) from VOUT_MODE
-        // assume output voltage is 0.232421875 volts,
-        // linear data format = 0000 0000 0111 0111 = 0x0077
+        // Determine READ_VOUT linear data value and decimal value
+        // * Exponent: -8
+        // * 16 bit mantissa: 816 = 0000 0011 0011 0000
+        // * linear data format = 0000 0011 0011 0000 = 0x0330
+        // * Decimal value: 816 * 2^(-8) = 3.1875
+
+        // Create mock I2CInterface.  Expect action to do the following:
+        // * will read 0x0330 from READ_VOUT (command/register 0x8B)
+        // * will read 0b0001'1000 (linear format, -8 exponent) from VOUT_MODE
+        //   (command/register 0x20)
         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>(0xC6), A<uint16_t&>()))
+        EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x8B), A<uint16_t&>()))
             .Times(1)
-            .WillOnce(SetArgReferee<1>(0x0077));
+            .WillOnce(SetArgReferee<1>(0x0330));
         EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x20), A<uint8_t&>()))
             .Times(1)
-            .WillOnce(SetArgReferee<1>(0b0001'0111));
-        // Create Device, IDMap, MockServices, and ActionEnvironment
+            .WillOnce(SetArgReferee<1>(0b0001'1000));
+
+        // Create MockServices.  Expect the sensor value to be set.
+        MockServices services{};
+        MockSensors& sensors = services.getMockSensors();
+        EXPECT_CALL(sensors, setValue(SensorType::vout, 3.1875)).Times(1);
+
+        // Create Device, IDMap, and ActionEnvironment
         Device device{
             "reg1", true,
             "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
             std::move(i2cInterface)};
         IDMap idMap{};
         idMap.addDevice(device);
-        MockServices services{};
         ActionEnvironment env{idMap, "reg1", services};
 
         // Create and execute action
-        SensorType type{SensorType::vout_peak};
-        uint8_t command = 0xC6;
-        pmbus_utils::SensorDataFormat format{
-            pmbus_utils::SensorDataFormat::linear_16};
+        SensorType type{SensorType::vout};
+        uint8_t command{0x8B};
+        SensorDataFormat format{SensorDataFormat::linear_16};
         std::optional<int8_t> exponent{};
         PMBusReadSensorAction action{type, command, format, exponent};
         EXPECT_EQ(action.execute(env), true);
-        /**
-         * TODO: Replace with EXPECT calls using MockSensors
-         *
-         * EXPECT_EQ(env.getSensorReadings().size(), 1);
-         * EXPECT_EQ(env.getSensorReadings()[0].type,
-         *           SensorType::vout_peak);
-         * EXPECT_DOUBLE_EQ(env.getSensorReadings()[0].value, 0.232421875);
-         */
     }
     catch (...)
     {
@@ -245,9 +232,8 @@
 
         // Create and execute action
         SensorType type{SensorType::pout};
-        uint8_t command = 0x96;
-        pmbus_utils::SensorDataFormat format{
-            pmbus_utils::SensorDataFormat::linear_11};
+        uint8_t command{0x96};
+        SensorDataFormat format{SensorDataFormat::linear_11};
         std::optional<int8_t> exponent{};
         PMBusReadSensorAction action{type, command, format, exponent};
         action.execute(env);
@@ -266,7 +252,8 @@
     try
     {
         // Create mock I2CInterface.  Expect action to do the following:
-        // * will read 0b0010'0000 (vid data format) from VOUT_MODE
+        // * will read READ_VOUT (command/register 0x8B)
+        // * will read 0b0010'0000 (VID data format) from VOUT_MODE
         std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
             std::make_unique<i2c::MockedI2CInterface>();
         EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
@@ -288,9 +275,8 @@
 
         // Create and execute action
         SensorType type{SensorType::vout};
-        uint8_t command = 0x8B;
-        pmbus_utils::SensorDataFormat format{
-            pmbus_utils::SensorDataFormat::linear_16};
+        uint8_t command{0x8B};
+        SensorDataFormat format{SensorDataFormat::linear_16};
         std::optional<int8_t> exponent{};
         PMBusReadSensorAction action{type, command, format, exponent};
         action.execute(env);
@@ -329,6 +315,7 @@
     try
     {
         // Create mock I2CInterface.  Expect action to do the following:
+        // * will read command/register 0xC6
         // * will try to read VOUT_MODE; exception will be thrown
         std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
             std::make_unique<i2c::MockedI2CInterface>();
@@ -352,9 +339,8 @@
 
         // Create and execute action
         SensorType type{SensorType::vout_peak};
-        uint8_t command = 0xC6;
-        pmbus_utils::SensorDataFormat format{
-            pmbus_utils::SensorDataFormat::linear_16};
+        uint8_t command{0xC6};
+        SensorDataFormat format{SensorDataFormat::linear_16};
         std::optional<int8_t> exponent{};
         PMBusReadSensorAction action{type, command, format, exponent};
         action.execute(env);
@@ -391,14 +377,14 @@
     try
     {
         // Create mock I2CInterface.  Expect action to do the following:
-        // * will try to read PMBus command(0x96); exception will be thrown
+        // * will try to read command/register 0x96; exception will be thrown
         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>(0x96), A<uint16_t&>()))
             .Times(1)
-            .WillOnce(Throw(
-                i2c::I2CException{"Failed to read word", "/dev/i2c-1", 0x70}));
+            .WillOnce(Throw(i2c::I2CException{"Failed to read word data",
+                                              "/dev/i2c-1", 0x70}));
 
         // Create Device, IDMap, MockServices, and ActionEnvironment
         Device device{
@@ -412,9 +398,8 @@
 
         // Create and execute action
         SensorType type{SensorType::pout};
-        uint8_t command = 0x96;
-        pmbus_utils::SensorDataFormat format{
-            pmbus_utils::SensorDataFormat::linear_11};
+        uint8_t command{0x96};
+        SensorDataFormat format{SensorDataFormat::linear_11};
         std::optional<int8_t> exponent{};
         PMBusReadSensorAction action{type, command, format, exponent};
         action.execute(env);
@@ -432,9 +417,78 @@
         }
         catch (const i2c::I2CException& ie)
         {
-            EXPECT_STREQ(
-                ie.what(),
-                "I2CException: Failed to read word: bus /dev/i2c-1, addr 0x70");
+            EXPECT_STREQ(ie.what(), "I2CException: Failed to read word data: "
+                                    "bus /dev/i2c-1, addr 0x70");
+        }
+        catch (...)
+        {
+            ADD_FAILURE() << "Should not have caught exception.";
+        }
+    }
+    catch (...)
+    {
+        ADD_FAILURE() << "Should not have caught exception.";
+    }
+
+    // Test where fails: Unable to publish sensor value due to D-Bus exception
+    try
+    {
+        // Determine READ_IOUT linear data value and decimal value
+        // * 5 bit exponent: -6 = 11010
+        // * 11 bit mantissa: 736 = 010 1110 0000
+        // * linear data format = 1101 0010 1110 0000 = 0xD2E0
+        // * Decimal value: 736 * 2^(-6) = 11.5
+
+        // Create mock I2CInterface.  Expect action to do the following:
+        // * will read 0xD2E0 from READ_IOUT (command/register 0x8C)
+        // * will not read from VOUT_MODE (command/register 0x20)
+        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&>()))
+            .Times(1)
+            .WillOnce(SetArgReferee<1>(0xD2E0));
+        EXPECT_CALL(*i2cInterface, read(A<uint8_t>(), A<uint8_t&>())).Times(0);
+
+        // Create MockServices.  Will throw D-Bus exception when trying to set
+        // sensor value.
+        MockServices services{};
+        MockSensors& sensors = services.getMockSensors();
+        EXPECT_CALL(sensors, setValue(SensorType::iout, 11.5))
+            .Times(1)
+            .WillOnce(Throw(TestSDBusError{"D-Bus error: Invalid property"}));
+
+        // Create Device, IDMap, and ActionEnvironment
+        Device device{
+            "reg1", true,
+            "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
+            std::move(i2cInterface)};
+        IDMap idMap{};
+        idMap.addDevice(device);
+        ActionEnvironment env{idMap, "reg1", services};
+
+        // Create and execute action
+        SensorType type{SensorType::iout};
+        uint8_t command{0x8C};
+        SensorDataFormat format{SensorDataFormat::linear_11};
+        std::optional<int8_t> exponent{};
+        PMBusReadSensorAction action{type, command, format, exponent};
+        action.execute(env);
+        ADD_FAILURE() << "Should not have reached this line.";
+    }
+    catch (const ActionError& e)
+    {
+        EXPECT_STREQ(e.what(), "ActionError: pmbus_read_sensor: { type: iout, "
+                               "command: 0x8C, format: linear_11 }");
+        try
+        {
+            // Re-throw inner D-Bus exception
+            std::rethrow_if_nested(e);
+            ADD_FAILURE() << "Should not have reached this line.";
+        }
+        catch (const sdbusplus::exception_t& de)
+        {
+            EXPECT_STREQ(de.what(), "D-Bus error: Invalid property");
         }
         catch (...)
         {
@@ -450,20 +504,18 @@
 TEST(PMBusReadSensorActionTests, GetCommand)
 {
     SensorType type{SensorType::iout};
-    uint8_t command = 0x8C;
-    pmbus_utils::SensorDataFormat format{
-        pmbus_utils::SensorDataFormat::linear_16};
-    std::optional<int8_t> exponent{-8};
+    uint8_t command{0x8C};
+    SensorDataFormat format{SensorDataFormat::linear_11};
+    std::optional<int8_t> exponent{};
     PMBusReadSensorAction action{type, command, format, exponent};
     EXPECT_EQ(action.getCommand(), 0x8C);
 }
 
 TEST(PMBusReadSensorActionTests, GetExponent)
 {
-    SensorType type{SensorType::iout};
-    uint8_t command = 0x8C;
-    pmbus_utils::SensorDataFormat format{
-        pmbus_utils::SensorDataFormat::linear_16};
+    SensorType type{SensorType::vout};
+    uint8_t command{0x8B};
+    SensorDataFormat format{SensorDataFormat::linear_16};
 
     // Exponent value is specified
     {
@@ -484,21 +536,19 @@
 TEST(PMBusReadSensorActionTests, GetFormat)
 {
     SensorType type{SensorType::iout};
-    uint8_t command = 0x8C;
-    pmbus_utils::SensorDataFormat format{
-        pmbus_utils::SensorDataFormat::linear_16};
-    std::optional<int8_t> exponent{-8};
+    uint8_t command{0x8C};
+    SensorDataFormat format{SensorDataFormat::linear_11};
+    std::optional<int8_t> exponent{};
     PMBusReadSensorAction action{type, command, format, exponent};
-    EXPECT_EQ(action.getFormat(), pmbus_utils::SensorDataFormat::linear_16);
+    EXPECT_EQ(action.getFormat(), SensorDataFormat::linear_11);
 }
 
 TEST(PMBusReadSensorActionTests, GetType)
 {
     SensorType type{SensorType::pout};
-    uint8_t command = 0x8C;
-    pmbus_utils::SensorDataFormat format{
-        pmbus_utils::SensorDataFormat::linear_16};
-    std::optional<int8_t> exponent{-8};
+    uint8_t command{0x96};
+    SensorDataFormat format{SensorDataFormat::linear_11};
+    std::optional<int8_t> exponent{};
     PMBusReadSensorAction action{type, command, format, exponent};
     EXPECT_EQ(action.getType(), SensorType::pout);
 }
@@ -507,26 +557,24 @@
 {
     // Test where exponent value is specified
     {
-        SensorType type{SensorType::vout};
-        uint8_t command = 0x8B;
-        pmbus_utils::SensorDataFormat format{
-            pmbus_utils::SensorDataFormat::linear_16};
+        SensorType type{SensorType::vout_peak};
+        uint8_t command{0xC6};
+        SensorDataFormat format{SensorDataFormat::linear_16};
         std::optional<int8_t> exponent{-8};
         PMBusReadSensorAction action{type, command, format, exponent};
         EXPECT_EQ(action.toString(), "pmbus_read_sensor: { type: "
-                                     "vout, command: 0x8B, format: "
+                                     "vout_peak, command: 0xC6, format: "
                                      "linear_16, exponent: -8 }");
     }
 
     // Test where exponent value is not specified
     {
-        SensorType type{SensorType::iout};
-        uint8_t command = 0x8C;
-        pmbus_utils::SensorDataFormat format{
-            pmbus_utils::SensorDataFormat::linear_11};
+        SensorType type{SensorType::iout_valley};
+        uint8_t command{0xCB};
+        SensorDataFormat format{SensorDataFormat::linear_11};
         std::optional<int8_t> exponent{};
         PMBusReadSensorAction action{type, command, format, exponent};
-        EXPECT_EQ(action.toString(), "pmbus_read_sensor: { type: iout, "
-                                     "command: 0x8C, format: linear_11 }");
+        EXPECT_EQ(action.toString(), "pmbus_read_sensor: { type: iout_valley, "
+                                     "command: 0xCB, format: linear_11 }");
     }
 }
diff --git a/phosphor-regulators/test/presence_detection_tests.cpp b/phosphor-regulators/test/presence_detection_tests.cpp
index c63f403..0de5919 100644
--- a/phosphor-regulators/test/presence_detection_tests.cpp
+++ b/phosphor-regulators/test/presence_detection_tests.cpp
@@ -27,6 +27,7 @@
 #include "presence_detection.hpp"
 #include "rule.hpp"
 #include "system.hpp"
+#include "test_sdbus_error.hpp"
 
 #include <sdbusplus/exception.hpp>
 
@@ -47,35 +48,6 @@
 using ::testing::Throw;
 
 /**
- * Concrete subclass of sdbusplus::exception_t abstract base class.
- */
-class TestSDBusError : public sdbusplus::exception_t
-{
-  public:
-    TestSDBusError(const std::string& error) : error{error}
-    {
-    }
-
-    const char* what() const noexcept override
-    {
-        return error.c_str();
-    }
-
-    const char* name() const noexcept override
-    {
-        return "";
-    }
-
-    const char* description() const noexcept override
-    {
-        return "";
-    }
-
-  private:
-    const std::string error{};
-};
-
-/**
  * Creates the parent objects that normally contain a PresenceDetection object.
  *
  * A PresenceDetection object is normally contained within a hierarchy of
diff --git a/phosphor-regulators/test/test_sdbus_error.hpp b/phosphor-regulators/test/test_sdbus_error.hpp
new file mode 100644
index 0000000..a4ac9ee
--- /dev/null
+++ b/phosphor-regulators/test/test_sdbus_error.hpp
@@ -0,0 +1,54 @@
+/**
+ * Copyright © 2021 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <sdbusplus/exception.hpp>
+
+#include <string>
+
+namespace phosphor::power::regulators
+{
+
+/**
+ * Concrete subclass of sdbusplus::exception_t abstract base class.
+ */
+class TestSDBusError : public sdbusplus::exception_t
+{
+  public:
+    TestSDBusError(const std::string& error) : error{error}
+    {
+    }
+
+    const char* what() const noexcept override
+    {
+        return error.c_str();
+    }
+
+    const char* name() const noexcept override
+    {
+        return "";
+    }
+
+    const char* description() const noexcept override
+    {
+        return "";
+    }
+
+  private:
+    const std::string error{};
+};
+
+} // namespace phosphor::power::regulators