psu-ng: Add Availability support to power supplies

Add support for determining if a power supply is considered 'available'
or not, and set the Available D-Bus property on the
xyz.openbmc_project.State.Decorator.Availability interface with the
result.

A power supply is considered unavailable if any of the following are
true:
 - it isn't present
 - there is a input fault active
 - there is a Vin UV fault active
 - there is a PS KILL fault active
 - there is a Iout OC fault active

The latter four faults are the faults where it can't provide good
output power, hence the PS is unavailable.  These faults also don't
call out the power supply directly, so the Functional property won't
get set to false, unlike other faults.

The Available D-Bus property is then able to be used in Redfish
responses for the heath and state properties in the power supply
schema.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I349eddb8c052cf238276c832af0dde9e49f6d3f0
diff --git a/phosphor-power-supply/test/power_supply_tests.cpp b/phosphor-power-supply/test/power_supply_tests.cpp
index c556f82..8bcbf16 100644
--- a/phosphor-power-supply/test/power_supply_tests.cpp
+++ b/phosphor-power-supply/test/power_supply_tests.cpp
@@ -703,6 +703,7 @@
     try
     {
         // Assume GPIO presence, not inventory presence?
+        EXPECT_CALL(mockedUtil, setAvailable(_, _, _)).Times(0);
         PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
 
         MockedGPIOInterface* mockPresenceGPIO =
@@ -721,6 +722,7 @@
     try
     {
         // Assume GPIO presence, not inventory presence?
+        EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
         PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
         MockedGPIOInterface* mockPresenceGPIO =
             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
@@ -804,6 +806,10 @@
         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
             .Times(1)
             .WillOnce(Return("0"));
+        if (x == DEGLITCH_LIMIT)
+        {
+            EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
+        }
         psu.analyze();
         EXPECT_EQ(psu.isPresent(), true);
         // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
@@ -828,6 +834,7 @@
     EXPECT_CALL(mockPMBus, read(READ_VIN, _, _))
         .Times(1)
         .WillOnce(Return(207000));
+    EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
     psu.clearFaults();
     EXPECT_EQ(psu.isPresent(), true);
     EXPECT_EQ(psu.isFaulted(), false);
@@ -870,6 +877,10 @@
         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
             .Times(1)
             .WillOnce(Return("0"));
+        if (x == DEGLITCH_LIMIT)
+        {
+            EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
+        }
         psu.analyze();
     }
 
@@ -902,6 +913,7 @@
         .Times(1)
         .WillOnce(Return("206000"));
     EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(0));
+    EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
     psu.analyze();
     EXPECT_EQ(psu.isPresent(), true);
     EXPECT_EQ(psu.isFaulted(), false);
@@ -1001,6 +1013,7 @@
     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
         .Times(1)
         .WillOnce(Return("123456"));
+    EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
     psu.analyze();
     EXPECT_EQ(psu.isPresent(), true);
 }
@@ -1049,6 +1062,10 @@
         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
             .Times(1)
             .WillOnce(Return("125790"));
+        if (x == DEGLITCH_LIMIT)
+        {
+            EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
+        }
         psu.analyze();
         EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT);
     }
@@ -1085,6 +1102,10 @@
         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
             .Times(1)
             .WillOnce(Return("201200"));
+        if (x == DEGLITCH_LIMIT)
+        {
+            EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
+        }
         psu.analyze();
         EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT);
     }
@@ -1095,6 +1116,7 @@
     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
         .Times(1)
         .WillOnce(Return("201300"));
+    EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
     psu.analyze();
     EXPECT_EQ(psu.hasInputFault(), false);
 }
@@ -1183,6 +1205,10 @@
         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
             .Times(1)
             .WillOnce(Return("19876"));
+        if (x == DEGLITCH_LIMIT)
+        {
+            EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
+        }
         psu.analyze();
         EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT);
     }
@@ -1196,6 +1222,7 @@
         .WillOnce(Return("201300"));
     // Went from below minimum to within range, expect CLEAR_FAULTS.
     EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(3));
+    EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
     psu.analyze();
     EXPECT_EQ(psu.hasVINUVFault(), false);
 }
@@ -1275,6 +1302,10 @@
         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
             .Times(1)
             .WillOnce(Return("203200"));
+        if (x == DEGLITCH_LIMIT)
+        {
+            EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
+        }
         psu.analyze();
         EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT);
     }
@@ -1284,6 +1315,7 @@
     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
         .Times(1)
         .WillOnce(Return("203300"));
+    EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
     psu.analyze();
     EXPECT_EQ(psu.hasIoutOCFault(), false);
 }
@@ -1336,6 +1368,9 @@
 {
     auto bus = sdbusplus::bus::new_default();
 
+    EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1);
+    EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0);
+
     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName};
     MockedGPIOInterface* mockPresenceGPIO =
         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
@@ -1382,6 +1417,9 @@
 {
     auto bus = sdbusplus::bus::new_default();
 
+    EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1);
+    EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0);
+
     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName};
     MockedGPIOInterface* mockPresenceGPIO =
         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
@@ -1560,6 +1598,10 @@
         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
             .Times(1)
             .WillOnce(Return("208200"));
+        if (x == DEGLITCH_LIMIT)
+        {
+            EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
+        }
         psu.analyze();
         EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT);
     }
@@ -1571,6 +1613,7 @@
     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
         .Times(1)
         .WillOnce(Return("208300"));
+    EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
     psu.analyze();
     EXPECT_EQ(psu.hasPSKillFault(), false);
     // Next return STATUS_WORD with MFR fault bit on.
@@ -1585,6 +1628,10 @@
         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
             .Times(1)
             .WillOnce(Return("208400"));
+        if (x == DEGLITCH_LIMIT)
+        {
+            EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
+        }
         psu.analyze();
         EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT);
     }
@@ -1596,6 +1643,7 @@
     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
         .Times(1)
         .WillOnce(Return("208500"));
+    EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
     psu.analyze();
     EXPECT_EQ(psu.hasPSKillFault(), false);
 }