13f1242f3SBrandon Wyman #include "../power_supply.hpp"
23f1242f3SBrandon Wyman #include "mock.hpp"
33f1242f3SBrandon Wyman 
43f1242f3SBrandon Wyman #include <xyz/openbmc_project/Common/Device/error.hpp>
53f1242f3SBrandon Wyman #include <xyz/openbmc_project/Common/error.hpp>
63f1242f3SBrandon Wyman 
73f1242f3SBrandon Wyman #include <gmock/gmock.h>
83f1242f3SBrandon Wyman #include <gtest/gtest.h>
93f1242f3SBrandon Wyman 
103f1242f3SBrandon Wyman using namespace phosphor::power::psu;
113f1242f3SBrandon Wyman using namespace phosphor::pmbus;
123f1242f3SBrandon Wyman 
133f1242f3SBrandon Wyman using ::testing::_;
1459a35793SBrandon Wyman using ::testing::Args;
153f1242f3SBrandon Wyman using ::testing::Assign;
163f1242f3SBrandon Wyman using ::testing::DoAll;
1759a35793SBrandon Wyman using ::testing::ElementsAre;
1859a35793SBrandon Wyman using ::testing::NotNull;
193f1242f3SBrandon Wyman using ::testing::Return;
203f1242f3SBrandon Wyman using ::testing::StrEq;
213f1242f3SBrandon Wyman 
223f1242f3SBrandon Wyman static auto PSUInventoryPath = "/xyz/bmc/inv/sys/chassis/board/powersupply0";
23681b2a36SB. J. Wyman static auto PSUGPIOLineName = "presence-ps0";
243f1242f3SBrandon Wyman 
25b654c619SBrandon Wyman struct PMBusExpectations
26b654c619SBrandon Wyman {
27b654c619SBrandon Wyman     uint16_t statusWordValue{0x0000};
28b654c619SBrandon Wyman     uint8_t statusInputValue{0x00};
29b654c619SBrandon Wyman     uint8_t statusMFRValue{0x00};
30b654c619SBrandon Wyman     uint8_t statusCMLValue{0x00};
31b654c619SBrandon Wyman     uint8_t statusVOUTValue{0x00};
32b10b3be0SBrandon Wyman     uint8_t statusIOUTValue{0x00};
337ee4d7e4SBrandon Wyman     uint8_t statusFans12Value{0x00};
3496893a46SBrandon Wyman     uint8_t statusTempValue{0x00};
35b654c619SBrandon Wyman };
36b654c619SBrandon Wyman 
378da35c51SBrandon Wyman // Helper function to setup expectations for various STATUS_* commands
38b654c619SBrandon Wyman void setPMBusExpectations(MockedPMBus& mockPMBus,
39b654c619SBrandon Wyman                           const PMBusExpectations& expectations)
408da35c51SBrandon Wyman {
418da35c51SBrandon Wyman     EXPECT_CALL(mockPMBus, read(STATUS_WORD, _))
428da35c51SBrandon Wyman         .Times(1)
43b654c619SBrandon Wyman         .WillOnce(Return(expectations.statusWordValue));
448da35c51SBrandon Wyman 
45b654c619SBrandon Wyman     if (expectations.statusWordValue != 0)
468da35c51SBrandon Wyman     {
478da35c51SBrandon Wyman         // If fault bits are on in STATUS_WORD, there will also be a read of
4896893a46SBrandon Wyman         // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT (page 0), and
4996893a46SBrandon Wyman         // STATUS_TEMPERATURE.
508da35c51SBrandon Wyman         EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _))
518da35c51SBrandon Wyman             .Times(1)
52b654c619SBrandon Wyman             .WillOnce(Return(expectations.statusInputValue));
538da35c51SBrandon Wyman         EXPECT_CALL(mockPMBus, read(STATUS_MFR, _))
548da35c51SBrandon Wyman             .Times(1)
55b654c619SBrandon Wyman             .WillOnce(Return(expectations.statusMFRValue));
568da35c51SBrandon Wyman         EXPECT_CALL(mockPMBus, read(STATUS_CML, _))
578da35c51SBrandon Wyman             .Times(1)
58b654c619SBrandon Wyman             .WillOnce(Return(expectations.statusCMLValue));
596710ba2cSBrandon Wyman         // Page will need to be set to 0 to read STATUS_VOUT.
606710ba2cSBrandon Wyman         EXPECT_CALL(mockPMBus, insertPageNum(STATUS_VOUT, 0))
616710ba2cSBrandon Wyman             .Times(1)
626710ba2cSBrandon Wyman             .WillOnce(Return("status0_vout"));
636710ba2cSBrandon Wyman         EXPECT_CALL(mockPMBus, read("status0_vout", _))
646710ba2cSBrandon Wyman             .Times(1)
65b654c619SBrandon Wyman             .WillOnce(Return(expectations.statusVOUTValue));
66b10b3be0SBrandon Wyman         EXPECT_CALL(mockPMBus, read(STATUS_IOUT, _))
67b10b3be0SBrandon Wyman             .Times(1)
68b10b3be0SBrandon Wyman             .WillOnce(Return(expectations.statusIOUTValue));
697ee4d7e4SBrandon Wyman         EXPECT_CALL(mockPMBus, read(STATUS_FANS_1_2, _))
707ee4d7e4SBrandon Wyman             .Times(1)
717ee4d7e4SBrandon Wyman             .WillOnce(Return(expectations.statusFans12Value));
7296893a46SBrandon Wyman         EXPECT_CALL(mockPMBus, read(STATUS_TEMPERATURE, _))
7396893a46SBrandon Wyman             .Times(1)
7496893a46SBrandon Wyman             .WillOnce(Return(expectations.statusTempValue));
758da35c51SBrandon Wyman     }
768da35c51SBrandon Wyman }
778da35c51SBrandon Wyman 
783f1242f3SBrandon Wyman class PowerSupplyTests : public ::testing::Test
793f1242f3SBrandon Wyman {
803f1242f3SBrandon Wyman   public:
813f1242f3SBrandon Wyman     PowerSupplyTests() :
823f1242f3SBrandon Wyman         mockedUtil(reinterpret_cast<const MockedUtil&>(getUtils()))
833f1242f3SBrandon Wyman     {
843f1242f3SBrandon Wyman         ON_CALL(mockedUtil, getPresence(_, _)).WillByDefault(Return(false));
853f1242f3SBrandon Wyman     }
863f1242f3SBrandon Wyman 
873f1242f3SBrandon Wyman     ~PowerSupplyTests() override
883f1242f3SBrandon Wyman     {
893f1242f3SBrandon Wyman         freeUtils();
903f1242f3SBrandon Wyman     }
913f1242f3SBrandon Wyman 
923f1242f3SBrandon Wyman     const MockedUtil& mockedUtil;
933f1242f3SBrandon Wyman };
943f1242f3SBrandon Wyman 
95391a0690SBrandon Wyman // Helper function for when a power supply goes from missing to present.
96391a0690SBrandon Wyman void setMissingToPresentExpects(MockedPMBus& pmbus, const MockedUtil& util)
97391a0690SBrandon Wyman {
98391a0690SBrandon Wyman     // Call to analyze() will update to present, that will trigger updating
99391a0690SBrandon Wyman     // to the correct/latest HWMON directory, in case it changes.
100391a0690SBrandon Wyman     EXPECT_CALL(pmbus, findHwmonDir());
101391a0690SBrandon Wyman     // Presence change from missing to present will trigger write to
102391a0690SBrandon Wyman     // ON_OFF_CONFIG.
103391a0690SBrandon Wyman     EXPECT_CALL(pmbus, writeBinary(ON_OFF_CONFIG, _, _));
104391a0690SBrandon Wyman     // Presence change from missing to present will trigger in1_input read
105391a0690SBrandon Wyman     // in an attempt to get CLEAR_FAULTS called.
106*82affd94SBrandon Wyman     // The voltage defaults to 0, the first call to analyze should update the
107*82affd94SBrandon Wyman     // voltage to the current reading, triggering another clearing of faults
108*82affd94SBrandon Wyman     // due to below minimum to within range voltage.
109*82affd94SBrandon Wyman     // This READ_VIN for CLEAR_FAULTS does not check the returned value.
110*82affd94SBrandon Wyman     EXPECT_CALL(pmbus, read(READ_VIN, _))
111*82affd94SBrandon Wyman         .Times(2)
112*82affd94SBrandon Wyman         .WillOnce(Return(1))
113*82affd94SBrandon Wyman         .WillOnce(Return(2));
114391a0690SBrandon Wyman     // Missing/present call will update Presence in inventory.
115391a0690SBrandon Wyman     EXPECT_CALL(util, setPresence(_, _, true, _));
116391a0690SBrandon Wyman }
117391a0690SBrandon Wyman 
1183f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Constructor)
1193f1242f3SBrandon Wyman {
1203f1242f3SBrandon Wyman     /**
1213f1242f3SBrandon Wyman      * @param[in] invpath - String for inventory path to use
1223f1242f3SBrandon Wyman      * @param[in] i2cbus - The bus number this power supply is on
1233f1242f3SBrandon Wyman      * @param[in] i2caddr - The 16-bit I2C address of the power supply
124681b2a36SB. J. Wyman      * @param[in] gpioLineName - The string for the gpio-line-name to read for
125681b2a36SB. J. Wyman      * presence.
126681b2a36SB. J. Wyman      * @param[in] bindDelay - Time in milliseconds to delay binding the device
127681b2a36SB. J. Wyman      * driver after seeing the presence line go active.
1283f1242f3SBrandon Wyman      */
1293f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
1301d7a7df8SBrandon Wyman 
1311d7a7df8SBrandon Wyman     // Try where inventory path is empty, constructor should fail.
1321d7a7df8SBrandon Wyman     try
1331d7a7df8SBrandon Wyman     {
134681b2a36SB. J. Wyman         auto psu =
135681b2a36SB. J. Wyman             std::make_unique<PowerSupply>(bus, "", 3, 0x68, PSUGPIOLineName);
1361d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have reached this line.";
1371d7a7df8SBrandon Wyman     }
1381d7a7df8SBrandon Wyman     catch (const std::invalid_argument& e)
1391d7a7df8SBrandon Wyman     {
1401d7a7df8SBrandon Wyman         EXPECT_STREQ(e.what(), "Invalid empty inventoryPath");
1411d7a7df8SBrandon Wyman     }
1421d7a7df8SBrandon Wyman     catch (...)
1431d7a7df8SBrandon Wyman     {
1441d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have caught exception.";
1451d7a7df8SBrandon Wyman     }
1461d7a7df8SBrandon Wyman 
147681b2a36SB. J. Wyman     // TODO: Try invalid i2c address?
148681b2a36SB. J. Wyman 
149681b2a36SB. J. Wyman     // Try where gpioLineName is empty.
1501d7a7df8SBrandon Wyman     try
1511d7a7df8SBrandon Wyman     {
1521d7a7df8SBrandon Wyman         auto psu =
153681b2a36SB. J. Wyman             std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, "");
154681b2a36SB. J. Wyman         ADD_FAILURE()
155681b2a36SB. J. Wyman             << "Should not have reached this line. Invalid gpioLineName.";
156681b2a36SB. J. Wyman     }
157681b2a36SB. J. Wyman     catch (const std::invalid_argument& e)
158681b2a36SB. J. Wyman     {
159681b2a36SB. J. Wyman         EXPECT_STREQ(e.what(), "Invalid empty gpioLineName");
160681b2a36SB. J. Wyman     }
161681b2a36SB. J. Wyman     catch (...)
162681b2a36SB. J. Wyman     {
163681b2a36SB. J. Wyman         ADD_FAILURE() << "Should not have caught exception.";
164681b2a36SB. J. Wyman     }
165681b2a36SB. J. Wyman 
166681b2a36SB. J. Wyman     // Test with valid arguments
167681b2a36SB. J. Wyman     // NOT using D-Bus inventory path for presence.
168681b2a36SB. J. Wyman     try
169681b2a36SB. J. Wyman     {
170681b2a36SB. J. Wyman         auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68,
171681b2a36SB. J. Wyman                                                  PSUGPIOLineName);
1723f1242f3SBrandon Wyman 
1733f1242f3SBrandon Wyman         EXPECT_EQ(psu->isPresent(), false);
1743f1242f3SBrandon Wyman         EXPECT_EQ(psu->isFaulted(), false);
1758da35c51SBrandon Wyman         EXPECT_EQ(psu->hasCommFault(), false);
1763f1242f3SBrandon Wyman         EXPECT_EQ(psu->hasInputFault(), false);
1773f1242f3SBrandon Wyman         EXPECT_EQ(psu->hasMFRFault(), false);
1783f1242f3SBrandon Wyman         EXPECT_EQ(psu->hasVINUVFault(), false);
1796710ba2cSBrandon Wyman         EXPECT_EQ(psu->hasVoutOVFault(), false);
180b10b3be0SBrandon Wyman         EXPECT_EQ(psu->hasIoutOCFault(), false);
1812cf46945SBrandon Wyman         EXPECT_EQ(psu->hasVoutUVFault(), false);
1827ee4d7e4SBrandon Wyman         EXPECT_EQ(psu->hasFanFault(), false);
18396893a46SBrandon Wyman         EXPECT_EQ(psu->hasTempFault(), false);
1842916ea52SBrandon Wyman         EXPECT_EQ(psu->hasPgoodFault(), false);
18539ea02bcSBrandon Wyman         EXPECT_EQ(psu->hasPSKillFault(), false);
18639ea02bcSBrandon Wyman         EXPECT_EQ(psu->hasPS12VcsFault(), false);
18739ea02bcSBrandon Wyman         EXPECT_EQ(psu->hasPSCS12VFault(), false);
1883f1242f3SBrandon Wyman     }
1891d7a7df8SBrandon Wyman     catch (...)
1901d7a7df8SBrandon Wyman     {
1911d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have caught exception.";
1921d7a7df8SBrandon Wyman     }
193681b2a36SB. J. Wyman 
194681b2a36SB. J. Wyman     // Test with valid arguments
195681b2a36SB. J. Wyman     // TODO: Using D-Bus inventory path for presence.
196681b2a36SB. J. Wyman     try
197681b2a36SB. J. Wyman     {
198681b2a36SB. J. Wyman         // FIXME: How do I get that presenceGPIO.read() in the startup to throw
199681b2a36SB. J. Wyman         // an exception?
200681b2a36SB. J. Wyman 
201681b2a36SB. J. Wyman         // EXPECT_CALL(mockedUtil, getPresence(_,
202681b2a36SB. J. Wyman         // StrEq(PSUInventoryPath)))
203681b2a36SB. J. Wyman         //    .Times(1);
204681b2a36SB. J. Wyman     }
205681b2a36SB. J. Wyman     catch (...)
206681b2a36SB. J. Wyman     {
207681b2a36SB. J. Wyman         ADD_FAILURE() << "Should not have caught exception.";
208681b2a36SB. J. Wyman     }
2091d7a7df8SBrandon Wyman }
2103f1242f3SBrandon Wyman 
2113f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Analyze)
2123f1242f3SBrandon Wyman {
2133f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
2143f1242f3SBrandon Wyman 
215b654c619SBrandon Wyman     {
216681b2a36SB. J. Wyman         // If I default to reading the GPIO, I will NOT expect a call to
217681b2a36SB. J. Wyman         // getPresence().
218681b2a36SB. J. Wyman 
219681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
2203ca062aeSAdriana Kobylak         MockedGPIOInterface* mockPresenceGPIO =
2213ca062aeSAdriana Kobylak             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
222681b2a36SB. J. Wyman         EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0));
223681b2a36SB. J. Wyman 
2243f1242f3SBrandon Wyman         psu.analyze();
2253f1242f3SBrandon Wyman         // By default, nothing should change.
2263f1242f3SBrandon Wyman         EXPECT_EQ(psu.isPresent(), false);
2273f1242f3SBrandon Wyman         EXPECT_EQ(psu.isFaulted(), false);
2283f1242f3SBrandon Wyman         EXPECT_EQ(psu.hasInputFault(), false);
2293f1242f3SBrandon Wyman         EXPECT_EQ(psu.hasMFRFault(), false);
2303f1242f3SBrandon Wyman         EXPECT_EQ(psu.hasVINUVFault(), false);
23185c7bf41SBrandon Wyman         EXPECT_EQ(psu.hasCommFault(), false);
2326710ba2cSBrandon Wyman         EXPECT_EQ(psu.hasVoutOVFault(), false);
233b10b3be0SBrandon Wyman         EXPECT_EQ(psu.hasIoutOCFault(), false);
2342cf46945SBrandon Wyman         EXPECT_EQ(psu.hasVoutUVFault(), false);
2357ee4d7e4SBrandon Wyman         EXPECT_EQ(psu.hasFanFault(), false);
23696893a46SBrandon Wyman         EXPECT_EQ(psu.hasTempFault(), false);
2372916ea52SBrandon Wyman         EXPECT_EQ(psu.hasPgoodFault(), false);
23839ea02bcSBrandon Wyman         EXPECT_EQ(psu.hasPSKillFault(), false);
23939ea02bcSBrandon Wyman         EXPECT_EQ(psu.hasPS12VcsFault(), false);
24039ea02bcSBrandon Wyman         EXPECT_EQ(psu.hasPSCS12VFault(), false);
241b654c619SBrandon Wyman     }
2423f1242f3SBrandon Wyman 
243681b2a36SB. J. Wyman     PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
244681b2a36SB. J. Wyman     // In order to get the various faults tested, the power supply needs to
245681b2a36SB. J. Wyman     // be present in order to read from the PMBus device(s).
2463ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO2 =
2473ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO());
24806ca4590SBrandon Wyman     // Always return 1 to indicate present.
24906ca4590SBrandon Wyman     // Each analyze() call will trigger a read of the presence GPIO.
25006ca4590SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO2, read()).WillRepeatedly(Return(1));
251681b2a36SB. J. Wyman     EXPECT_EQ(psu2.isPresent(), false);
2523f1242f3SBrandon Wyman 
2533f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus());
254391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
255b654c619SBrandon Wyman 
256b654c619SBrandon Wyman     // STATUS_WORD INPUT fault.
257b654c619SBrandon Wyman     {
258b654c619SBrandon Wyman         // Start with STATUS_WORD 0x0000. Powered on, no faults.
259b654c619SBrandon Wyman         // Set expectations for a no fault
260b654c619SBrandon Wyman         PMBusExpectations expectations;
261b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
262*82affd94SBrandon Wyman         // After reading STATUS_WORD, etc., there will be a READ_VIN check.
263*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
264*82affd94SBrandon Wyman             .Times(1)
265*82affd94SBrandon Wyman             .WillOnce(Return("206000"));
2663f1242f3SBrandon Wyman         psu2.analyze();
2673f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
2683f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), false);
2693f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
2703f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
2713f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
27285c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
2736710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
274b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
2752cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
2767ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
27796893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
2782916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
27939ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
28039ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
28139ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
2823f1242f3SBrandon Wyman 
283b654c619SBrandon Wyman         // Update expectations for STATUS_WORD input fault/warn
28496893a46SBrandon Wyman         // STATUS_INPUT fault bits ... on.
285b654c619SBrandon Wyman         expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
286b654c619SBrandon Wyman         expectations.statusInputValue = 0x38;
287b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
288*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
289*82affd94SBrandon Wyman             .Times(1)
290*82affd94SBrandon Wyman             .WillOnce(Return("207000"));
2913f1242f3SBrandon Wyman         psu2.analyze();
2923f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
2933f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
2943f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), true);
2953f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
2963f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
29785c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
2986710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
299b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
3002cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
3017ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
30296893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
3032916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
30439ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
30539ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
30639ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
307b654c619SBrandon Wyman     }
3083f1242f3SBrandon Wyman 
3093f1242f3SBrandon Wyman     // STATUS_WORD INPUT/UV fault.
310b654c619SBrandon Wyman     {
3113f1242f3SBrandon Wyman         // First need it to return good status, then the fault
312b654c619SBrandon Wyman         PMBusExpectations expectations;
313b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
314*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
315*82affd94SBrandon Wyman             .Times(1)
316*82affd94SBrandon Wyman             .WillOnce(Return("208000"));
3173f1242f3SBrandon Wyman         psu2.analyze();
3188da35c51SBrandon Wyman         // Now set fault bits in STATUS_WORD
319b654c619SBrandon Wyman         expectations.statusWordValue =
3208da35c51SBrandon Wyman             (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT);
3218da35c51SBrandon Wyman         // STATUS_INPUT fault bits ... on.
322b654c619SBrandon Wyman         expectations.statusInputValue = 0x38;
323b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
324*82affd94SBrandon Wyman         // Input/UV fault, so voltage should read back low.
325*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
326*82affd94SBrandon Wyman             .Times(1)
327*82affd94SBrandon Wyman             .WillOnce(Return("19123"));
3283f1242f3SBrandon Wyman         psu2.analyze();
3293f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
3303f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
331f07bc797SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), true);
3323f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
3333f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), true);
33485c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
3356710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
336b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
3372cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
3387ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
33996893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
3402916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
34139ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
34239ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
34339ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
344*82affd94SBrandon Wyman 
345*82affd94SBrandon Wyman         // Turning VIN_UV fault off causes clearing of faults, causing read of
346*82affd94SBrandon Wyman         // in1_input as an attempt to get CLEAR_FAULTS called.
347*82affd94SBrandon Wyman         expectations.statusWordValue = 0;
348*82affd94SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
349*82affd94SBrandon Wyman         // The call to read the voltage
350*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
351*82affd94SBrandon Wyman             .Times(1)
352*82affd94SBrandon Wyman             .WillOnce(Return("209000"));
353*82affd94SBrandon Wyman         // The call for CLEAR_FAULTS command
354*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(3));
355*82affd94SBrandon Wyman         psu2.analyze();
356*82affd94SBrandon Wyman         // Should remain present, no longer be faulted, no input fault, no
357*82affd94SBrandon Wyman         // VIN_UV fault. Nothing else should change.
358*82affd94SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
359*82affd94SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), false);
360*82affd94SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
361*82affd94SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
362b654c619SBrandon Wyman     }
3633f1242f3SBrandon Wyman 
3643f1242f3SBrandon Wyman     // STATUS_WORD MFR fault.
365b654c619SBrandon Wyman     {
366f07bc797SBrandon Wyman         // First need it to return good status, then the fault
367b654c619SBrandon Wyman         PMBusExpectations expectations;
368b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
369*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
370*82affd94SBrandon Wyman             .Times(1)
371*82affd94SBrandon Wyman             .WillOnce(Return("210000"));
3723f1242f3SBrandon Wyman         psu2.analyze();
3738da35c51SBrandon Wyman         // Now STATUS_WORD with MFR fault bit on.
374b654c619SBrandon Wyman         expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
3758da35c51SBrandon Wyman         // STATUS_MFR bits on.
376b654c619SBrandon Wyman         expectations.statusMFRValue = 0xFF;
377b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
378*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
379*82affd94SBrandon Wyman             .Times(1)
380*82affd94SBrandon Wyman             .WillOnce(Return("211000"));
3813f1242f3SBrandon Wyman         psu2.analyze();
3823f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
3833f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
3843f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
3853f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), true);
3863f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
38785c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
3886710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
389b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
3902cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
3917ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
39296893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
3932916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
39439ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), true);
39539ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), true);
39639ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), true);
397b654c619SBrandon Wyman     }
3983f1242f3SBrandon Wyman 
39996893a46SBrandon Wyman     // Temperature fault.
400b654c619SBrandon Wyman     {
401f07bc797SBrandon Wyman         // First STATUS_WORD with no bits set, then with temperature fault.
402b654c619SBrandon Wyman         PMBusExpectations expectations;
403b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
404*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
405*82affd94SBrandon Wyman             .Times(1)
406*82affd94SBrandon Wyman             .WillOnce(Return("212000"));
4073f1242f3SBrandon Wyman         psu2.analyze();
4088da35c51SBrandon Wyman         // STATUS_WORD with temperature fault bit on.
409b654c619SBrandon Wyman         expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
41096893a46SBrandon Wyman         // STATUS_TEMPERATURE with fault bit(s) on.
41196893a46SBrandon Wyman         expectations.statusTempValue = 0x10;
412b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
413*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
414*82affd94SBrandon Wyman             .Times(1)
415*82affd94SBrandon Wyman             .WillOnce(Return("213000"));
4163f1242f3SBrandon Wyman         psu2.analyze();
4173f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
41896893a46SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
4193f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
4203f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
4213f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
42285c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
4236710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
424b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
4252cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
4267ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
42796893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), true);
4282916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
42939ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
43039ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
43139ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
432b654c619SBrandon Wyman     }
43385c7bf41SBrandon Wyman 
43485c7bf41SBrandon Wyman     // CML fault
435b654c619SBrandon Wyman     {
43685c7bf41SBrandon Wyman         // First STATUS_WORD wit no bits set, then with CML fault.
437b654c619SBrandon Wyman         PMBusExpectations expectations;
438b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
439*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
440*82affd94SBrandon Wyman             .Times(1)
441*82affd94SBrandon Wyman             .WillOnce(Return("214000"));
44285c7bf41SBrandon Wyman         psu2.analyze();
4438da35c51SBrandon Wyman         // STATUS_WORD with CML fault bit on.
444b654c619SBrandon Wyman         expectations.statusWordValue = (status_word::CML_FAULT);
44585c7bf41SBrandon Wyman         // Turn on STATUS_CML fault bit(s)
446b654c619SBrandon Wyman         expectations.statusCMLValue = 0xFF;
447b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
448*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
449*82affd94SBrandon Wyman             .Times(1)
450*82affd94SBrandon Wyman             .WillOnce(Return("215000"));
45185c7bf41SBrandon Wyman         psu2.analyze();
45285c7bf41SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
45385c7bf41SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
45485c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
45585c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
45685c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
45785c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), true);
4586710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
459b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
4602cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
4617ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
46296893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
4632916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
46439ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
46539ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
46639ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
467b654c619SBrandon Wyman     }
4686710ba2cSBrandon Wyman 
4696710ba2cSBrandon Wyman     // VOUT_OV_FAULT fault
470b654c619SBrandon Wyman     {
4716710ba2cSBrandon Wyman         // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault.
472b654c619SBrandon Wyman         PMBusExpectations expectations;
473b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
474*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
475*82affd94SBrandon Wyman             .Times(1)
476*82affd94SBrandon Wyman             .WillOnce(Return("216000"));
4776710ba2cSBrandon Wyman         psu2.analyze();
4786710ba2cSBrandon Wyman         // STATUS_WORD with VOUT/VOUT_OV fault.
479b654c619SBrandon Wyman         expectations.statusWordValue =
4806710ba2cSBrandon Wyman             ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT));
4816710ba2cSBrandon Wyman         // Turn on STATUS_VOUT fault bit(s)
482b654c619SBrandon Wyman         expectations.statusVOUTValue = 0xA0;
48396893a46SBrandon Wyman         // STATUS_TEMPERATURE don't care (default)
484b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
485*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
486*82affd94SBrandon Wyman             .Times(1)
487*82affd94SBrandon Wyman             .WillOnce(Return("217000"));
4886710ba2cSBrandon Wyman         psu2.analyze();
4896710ba2cSBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
4906710ba2cSBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
4916710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
4926710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
4936710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
4946710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
4956710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), true);
4962cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
497b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
4987ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
499b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
500b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
50139ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
50239ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
50339ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
504b10b3be0SBrandon Wyman     }
505b10b3be0SBrandon Wyman 
506b10b3be0SBrandon Wyman     // IOUT_OC_FAULT fault
507b10b3be0SBrandon Wyman     {
508b10b3be0SBrandon Wyman         // First STATUS_WORD with no bits set, then with IOUT_OC fault.
509b10b3be0SBrandon Wyman         PMBusExpectations expectations;
510b10b3be0SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
511*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
512*82affd94SBrandon Wyman             .Times(1)
513*82affd94SBrandon Wyman             .WillOnce(Return("218000"));
514b10b3be0SBrandon Wyman         psu2.analyze();
515b10b3be0SBrandon Wyman         // STATUS_WORD with IOUT_OC fault.
516b10b3be0SBrandon Wyman         expectations.statusWordValue = status_word::IOUT_OC_FAULT;
517b10b3be0SBrandon Wyman         // Turn on STATUS_IOUT fault bit(s)
518b10b3be0SBrandon Wyman         expectations.statusIOUTValue = 0x88;
519b10b3be0SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
520*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
521*82affd94SBrandon Wyman             .Times(1)
522*82affd94SBrandon Wyman             .WillOnce(Return("219000"));
523b10b3be0SBrandon Wyman         psu2.analyze();
524b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
525b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
526b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
527b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
528b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
529b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
530b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
531b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), true);
5322cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
5337ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
5342cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
5352cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
53639ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
53739ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
53839ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
5392cf46945SBrandon Wyman     }
5402cf46945SBrandon Wyman 
5412cf46945SBrandon Wyman     // VOUT_UV_FAULT
5422cf46945SBrandon Wyman     {
5432cf46945SBrandon Wyman         // First STATUS_WORD with no bits set, then with VOUT fault.
5442cf46945SBrandon Wyman         PMBusExpectations expectations;
5452cf46945SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
546*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
547*82affd94SBrandon Wyman             .Times(1)
548*82affd94SBrandon Wyman             .WillOnce(Return("220000"));
5492cf46945SBrandon Wyman         psu2.analyze();
5502cf46945SBrandon Wyman         // Change STATUS_WORD to indicate VOUT fault.
5512cf46945SBrandon Wyman         expectations.statusWordValue = (status_word::VOUT_FAULT);
5522cf46945SBrandon Wyman         // Turn on STATUS_VOUT fault bit(s)
5532cf46945SBrandon Wyman         expectations.statusVOUTValue = 0x30;
5542cf46945SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
555*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
556*82affd94SBrandon Wyman             .Times(1)
557*82affd94SBrandon Wyman             .WillOnce(Return("221000"));
5582cf46945SBrandon Wyman         psu2.analyze();
5592cf46945SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
5602cf46945SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
5612cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
5622cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
5632cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
5642cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
5652cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
5662cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
5672cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), true);
5687ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
56996893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
5702916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
57139ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
57239ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
57339ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
574b654c619SBrandon Wyman     }
5753f1242f3SBrandon Wyman 
5767ee4d7e4SBrandon Wyman     // Fan fault
577b654c619SBrandon Wyman     {
578b654c619SBrandon Wyman         // First STATUS_WORD with no bits set, then with fan fault.
579b654c619SBrandon Wyman         PMBusExpectations expectations;
580b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
581*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
582*82affd94SBrandon Wyman             .Times(1)
583*82affd94SBrandon Wyman             .WillOnce(Return("222000"));
5843f1242f3SBrandon Wyman         psu2.analyze();
585b654c619SBrandon Wyman         expectations.statusWordValue = (status_word::FAN_FAULT);
5867ee4d7e4SBrandon Wyman         // STATUS_FANS_1_2 with fan 1 warning & fault bits on.
5877ee4d7e4SBrandon Wyman         expectations.statusFans12Value = 0xA0;
588b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
589*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
590*82affd94SBrandon Wyman             .Times(1)
591*82affd94SBrandon Wyman             .WillOnce(Return("223000"));
5923f1242f3SBrandon Wyman         psu2.analyze();
5933f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
5947ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
5953f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
5963f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
5973f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
59885c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
5996710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
600b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
6012cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
6027ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), true);
60396893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
6042916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
60539ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
60639ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
60739ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
608b654c619SBrandon Wyman     }
6092916ea52SBrandon Wyman 
61006ca4590SBrandon Wyman     // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT.
6112cf46945SBrandon Wyman     {
6122916ea52SBrandon Wyman         // First STATUS_WORD with no bits set.
6132916ea52SBrandon Wyman         PMBusExpectations expectations;
6142916ea52SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
615*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
616*82affd94SBrandon Wyman             .Times(1)
617*82affd94SBrandon Wyman             .WillOnce(Return("123000"));
6182916ea52SBrandon Wyman         psu2.analyze();
6192916ea52SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), false);
6202916ea52SBrandon Wyman         // POWER_GOOD# inactive, and OFF bit on.
6212916ea52SBrandon Wyman         expectations.statusWordValue =
6222916ea52SBrandon Wyman             ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF));
62306ca4590SBrandon Wyman         for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
62406ca4590SBrandon Wyman         {
6252916ea52SBrandon Wyman             // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and
6262916ea52SBrandon Wyman             // STATUS_TEMPERATURE: Don't care if bits set or not (defaults).
6272916ea52SBrandon Wyman             setPMBusExpectations(mockPMBus, expectations);
628*82affd94SBrandon Wyman             EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
629*82affd94SBrandon Wyman                 .Times(1)
630*82affd94SBrandon Wyman                 .WillOnce(Return("124000"));
6312916ea52SBrandon Wyman             psu2.analyze();
6322916ea52SBrandon Wyman             EXPECT_EQ(psu2.isPresent(), true);
63306ca4590SBrandon Wyman             if (x < DEGLITCH_LIMIT)
63406ca4590SBrandon Wyman             {
63506ca4590SBrandon Wyman                 EXPECT_EQ(psu2.isFaulted(), false);
63606ca4590SBrandon Wyman             }
63706ca4590SBrandon Wyman             else
63806ca4590SBrandon Wyman             {
6392916ea52SBrandon Wyman                 EXPECT_EQ(psu2.isFaulted(), true);
64006ca4590SBrandon Wyman             }
6412916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasInputFault(), false);
6422916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasMFRFault(), false);
6432916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasVINUVFault(), false);
6442916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasCommFault(), false);
6452916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasVoutOVFault(), false);
6462cf46945SBrandon Wyman             EXPECT_EQ(psu2.hasVoutUVFault(), false);
647b10b3be0SBrandon Wyman             EXPECT_EQ(psu2.hasIoutOCFault(), false);
6487ee4d7e4SBrandon Wyman             EXPECT_EQ(psu2.hasFanFault(), false);
6492916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasTempFault(), false);
65006ca4590SBrandon Wyman             if (x < DEGLITCH_LIMIT)
65106ca4590SBrandon Wyman             {
65206ca4590SBrandon Wyman                 EXPECT_EQ(psu2.hasPgoodFault(), false);
65306ca4590SBrandon Wyman             }
65406ca4590SBrandon Wyman             else
65506ca4590SBrandon Wyman             {
6562916ea52SBrandon Wyman                 EXPECT_EQ(psu2.hasPgoodFault(), true);
6572916ea52SBrandon Wyman             }
65806ca4590SBrandon Wyman         }
65906ca4590SBrandon Wyman     }
6602916ea52SBrandon Wyman 
6613f1242f3SBrandon Wyman     // TODO: ReadFailure
6623f1242f3SBrandon Wyman }
6633f1242f3SBrandon Wyman 
66459a35793SBrandon Wyman TEST_F(PowerSupplyTests, OnOffConfig)
66559a35793SBrandon Wyman {
66659a35793SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
66759a35793SBrandon Wyman     uint8_t data = 0x15;
66859a35793SBrandon Wyman 
66959a35793SBrandon Wyman     // Test where PSU is NOT present
67059a35793SBrandon Wyman     try
67159a35793SBrandon Wyman     {
672681b2a36SB. J. Wyman         // Assume GPIO presence, not inventory presence?
673681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
674681b2a36SB. J. Wyman 
6753ca062aeSAdriana Kobylak         MockedGPIOInterface* mockPresenceGPIO =
6763ca062aeSAdriana Kobylak             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
677681b2a36SB. J. Wyman         ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0));
67859a35793SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
679681b2a36SB. J. Wyman         // Constructor should set initial presence, default read returns 0.
68059a35793SBrandon Wyman         // If it is not present, I should not be trying to write to it.
68159a35793SBrandon Wyman         EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0);
68259a35793SBrandon Wyman         psu.onOffConfig(data);
68359a35793SBrandon Wyman     }
68459a35793SBrandon Wyman     catch (...)
6850c9a33d6SAdriana Kobylak     {}
68659a35793SBrandon Wyman 
68759a35793SBrandon Wyman     // Test where PSU is present
68859a35793SBrandon Wyman     try
68959a35793SBrandon Wyman     {
690681b2a36SB. J. Wyman         // Assume GPIO presence, not inventory presence?
691681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
6923ca062aeSAdriana Kobylak         MockedGPIOInterface* mockPresenceGPIO =
6933ca062aeSAdriana Kobylak             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
694391a0690SBrandon Wyman         // There will potentially be multiple calls, we want it to continue
695391a0690SBrandon Wyman         // returning 1 for the GPIO read to keep the power supply present.
696391a0690SBrandon Wyman         EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
69759a35793SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
698391a0690SBrandon Wyman         setMissingToPresentExpects(mockPMBus, mockedUtil);
699391a0690SBrandon Wyman         // If I am calling analyze(), I should probably give it good data.
700391a0690SBrandon Wyman         // STATUS_WORD 0x0000 is powered on, no faults.
701391a0690SBrandon Wyman         PMBusExpectations expectations;
702391a0690SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
703*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
704*82affd94SBrandon Wyman             .Times(1)
705*82affd94SBrandon Wyman             .WillOnce(Return("205000"));
706681b2a36SB. J. Wyman         psu.analyze();
707391a0690SBrandon Wyman         // I definitely should be writting ON_OFF_CONFIG if I call the function
708391a0690SBrandon Wyman         EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, ElementsAre(0x15),
709391a0690SBrandon Wyman                                            Type::HwmonDeviceDebug))
71059a35793SBrandon Wyman             .Times(1);
71159a35793SBrandon Wyman         psu.onOffConfig(data);
71259a35793SBrandon Wyman     }
71359a35793SBrandon Wyman     catch (...)
7140c9a33d6SAdriana Kobylak     {}
71559a35793SBrandon Wyman }
71659a35793SBrandon Wyman 
7173f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, ClearFaults)
7183f1242f3SBrandon Wyman {
7193f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
720681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, PSUGPIOLineName};
7213ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
7223ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
72306ca4590SBrandon Wyman     // Always return 1 to indicate present.
72406ca4590SBrandon Wyman     // Each analyze() call will trigger a read of the presence GPIO.
72506ca4590SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
726681b2a36SB. J. Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
727391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
7288da35c51SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
729b654c619SBrandon Wyman     PMBusExpectations expectations;
730b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
731*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
732*82affd94SBrandon Wyman         .Times(1)
733*82affd94SBrandon Wyman         .WillOnce(Return("207000"));
734681b2a36SB. J. Wyman     psu.analyze();
7353f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), true);
7363f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), false);
7373f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
7383f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
7393f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
74085c7bf41SBrandon Wyman     EXPECT_EQ(psu.hasCommFault(), false);
7416710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), false);
742b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), false);
7432cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
7447ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), false);
74596893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), false);
7462916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
74739ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
74839ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
74939ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
750b654c619SBrandon Wyman 
751f07bc797SBrandon Wyman     // STATUS_WORD with fault bits galore!
752b654c619SBrandon Wyman     expectations.statusWordValue = 0xFFFF;
753f07bc797SBrandon Wyman     // STATUS_INPUT with fault bits on.
754b654c619SBrandon Wyman     expectations.statusInputValue = 0xFF;
755f07bc797SBrandon Wyman     // STATUS_MFR_SPEFIC with bits on.
756b654c619SBrandon Wyman     expectations.statusMFRValue = 0xFF;
75785c7bf41SBrandon Wyman     // STATUS_CML with bits on.
758b654c619SBrandon Wyman     expectations.statusCMLValue = 0xFF;
7596710ba2cSBrandon Wyman     // STATUS_VOUT with bits on.
760b654c619SBrandon Wyman     expectations.statusVOUTValue = 0xFF;
761b10b3be0SBrandon Wyman     // STATUS_IOUT with bits on.
762b10b3be0SBrandon Wyman     expectations.statusIOUTValue = 0xFF;
7637ee4d7e4SBrandon Wyman     // STATUS_FANS_1_2 with bits on.
7647ee4d7e4SBrandon Wyman     expectations.statusFans12Value = 0xFF;
76596893a46SBrandon Wyman     // STATUS_TEMPERATURE with bits on.
76696893a46SBrandon Wyman     expectations.statusTempValue = 0xFF;
767b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
768*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
769*82affd94SBrandon Wyman         .Times(1)
770*82affd94SBrandon Wyman         .WillOnce(Return("0"));
7713f1242f3SBrandon Wyman     psu.analyze();
7723f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), true);
7733f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), true);
7743f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), true);
7753f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), true);
7763f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), true);
77785c7bf41SBrandon Wyman     EXPECT_EQ(psu.hasCommFault(), true);
7786710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), true);
779b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), true);
7802cf46945SBrandon Wyman     // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
7812cf46945SBrandon Wyman     // Rely on HasVoutUVFault() to verify this sets and clears.
7822cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
7837ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), true);
78496893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), true);
78506ca4590SBrandon Wyman     // pgoodFault is deglitched up to DEGLITCH_LIMIT
78606ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
78706ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
788*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
789*82affd94SBrandon Wyman         .Times(1)
790*82affd94SBrandon Wyman         .WillOnce(Return("0"));
79106ca4590SBrandon Wyman     psu.analyze();
79206ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
79306ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
794*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
795*82affd94SBrandon Wyman         .Times(1)
796*82affd94SBrandon Wyman         .WillOnce(Return("0"));
79706ca4590SBrandon Wyman     psu.analyze();
79806ca4590SBrandon Wyman     // DEGLITCH_LIMIT reached for pgoodFault
7992916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), true);
80039ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), true);
80139ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), true);
80239ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), true);
803*82affd94SBrandon Wyman     // This is the CLEAR_FAULTS read that does not check the return value.
804*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(3));
8053f1242f3SBrandon Wyman     psu.clearFaults();
8063f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), true);
8073f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), false);
8083f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
8093f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
8103f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
81185c7bf41SBrandon Wyman     EXPECT_EQ(psu.hasCommFault(), false);
8126710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), false);
813b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), false);
8142cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
8157ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), false);
81696893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), false);
8172916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
81839ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
81939ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
82039ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
821681b2a36SB. J. Wyman 
822*82affd94SBrandon Wyman     // Faults clear on READ_VIN 0 -> !0
823*82affd94SBrandon Wyman     // STATUS_WORD with fault bits galore!
824*82affd94SBrandon Wyman     expectations.statusWordValue = 0xFFFF;
825*82affd94SBrandon Wyman     // STATUS_INPUT with fault bits on.
826*82affd94SBrandon Wyman     expectations.statusInputValue = 0xFF;
827*82affd94SBrandon Wyman     // STATUS_MFR_SPEFIC with bits on.
828*82affd94SBrandon Wyman     expectations.statusMFRValue = 0xFF;
829*82affd94SBrandon Wyman     // STATUS_CML with bits on.
830*82affd94SBrandon Wyman     expectations.statusCMLValue = 0xFF;
831*82affd94SBrandon Wyman     // STATUS_VOUT with bits on.
832*82affd94SBrandon Wyman     expectations.statusVOUTValue = 0xFF;
833*82affd94SBrandon Wyman     // STATUS_IOUT with bits on.
834*82affd94SBrandon Wyman     expectations.statusIOUTValue = 0xFF;
835*82affd94SBrandon Wyman     // STATUS_FANS_1_2 with bits on.
836*82affd94SBrandon Wyman     expectations.statusFans12Value = 0xFF;
837*82affd94SBrandon Wyman     // STATUS_TEMPERATURE with bits on.
838*82affd94SBrandon Wyman     expectations.statusTempValue = 0xFF;
839*82affd94SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
840*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(0));
841*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
842*82affd94SBrandon Wyman         .Times(1)
843*82affd94SBrandon Wyman         .WillOnce(Return("0"));
844*82affd94SBrandon Wyman     psu.analyze();
845*82affd94SBrandon Wyman     EXPECT_EQ(psu.isPresent(), true);
846*82affd94SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), true);
847*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), true);
848*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), true);
849*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), true);
850*82affd94SBrandon Wyman     // True due to CML fault bits on
851*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasCommFault(), true);
852*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), true);
853*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), true);
854*82affd94SBrandon Wyman     // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
855*82affd94SBrandon Wyman     // Rely on HasVoutUVFault() to verify this sets and clears.
856*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
857*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), true);
858*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), true);
859*82affd94SBrandon Wyman     // PGOOD fault is deglitched before hasPgoodFault() returns true.
860*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
861*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), true);
862*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), true);
863*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), true);
864*82affd94SBrandon Wyman     // STATUS_WORD with INPUT/VIN_UV fault bits off.
865*82affd94SBrandon Wyman     expectations.statusWordValue = 0xDFF7;
866*82affd94SBrandon Wyman     // STATUS_INPUT with VIN_UV_WARNING, VIN_UV_FAULT, and Unit Off For
867*82affd94SBrandon Wyman     // Insufficient Input Voltage bits off.
868*82affd94SBrandon Wyman     expectations.statusInputValue = 0xC7;
869*82affd94SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
870*82affd94SBrandon Wyman     // READ_VIN back in range.
871*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
872*82affd94SBrandon Wyman         .Times(1)
873*82affd94SBrandon Wyman         .WillOnce(Return("206000"));
874*82affd94SBrandon Wyman     psu.analyze();
875*82affd94SBrandon Wyman     EXPECT_EQ(psu.isPresent(), true);
876*82affd94SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), false);
877*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
878*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
879*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
880*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasCommFault(), false);
881*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), false);
882*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), false);
883*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
884*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), false);
885*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), false);
886*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
887*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
888*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
889*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
890*82affd94SBrandon Wyman 
891681b2a36SB. J. Wyman     // TODO: Faults clear on missing/present?
8923f1242f3SBrandon Wyman }
8933f1242f3SBrandon Wyman 
8943f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory)
8953f1242f3SBrandon Wyman {
8963f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
8971d7a7df8SBrandon Wyman 
8981d7a7df8SBrandon Wyman     try
8991d7a7df8SBrandon Wyman     {
900681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
9011d7a7df8SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
9021d7a7df8SBrandon Wyman         // If it is not present, I should not be trying to read a string
9031d7a7df8SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(_, _)).Times(0);
9041d7a7df8SBrandon Wyman         psu.updateInventory();
9051d7a7df8SBrandon Wyman     }
9061d7a7df8SBrandon Wyman     catch (...)
9071d7a7df8SBrandon Wyman     {
9081d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have caught exception.";
9091d7a7df8SBrandon Wyman     }
9101d7a7df8SBrandon Wyman 
9111d7a7df8SBrandon Wyman     try
9121d7a7df8SBrandon Wyman     {
913681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, PSUGPIOLineName};
9143ca062aeSAdriana Kobylak         MockedGPIOInterface* mockPresenceGPIO =
9153ca062aeSAdriana Kobylak             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
916681b2a36SB. J. Wyman         // GPIO read return 1 to indicate present.
917681b2a36SB. J. Wyman         EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
9181d7a7df8SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
919391a0690SBrandon Wyman         setMissingToPresentExpects(mockPMBus, mockedUtil);
920391a0690SBrandon Wyman         // STATUS_WORD 0x0000 is powered on, no faults.
921391a0690SBrandon Wyman         PMBusExpectations expectations;
922391a0690SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
923*82affd94SBrandon Wyman         // Call to analyze will read voltage, trigger clear faults for 0 to
924*82affd94SBrandon Wyman         // within range.
925*82affd94SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
926*82affd94SBrandon Wyman             .Times(1)
927*82affd94SBrandon Wyman             .WillOnce(Return("123456"));
928391a0690SBrandon Wyman         psu.analyze();
9291d7a7df8SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return(""));
9303f1242f3SBrandon Wyman         psu.updateInventory();
9311d7a7df8SBrandon Wyman 
9323c530fbdSBrandon Wyman #if IBM_VPD
9331d7a7df8SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(_, _))
9341d7a7df8SBrandon Wyman             .WillOnce(Return("CCIN"))
9351d7a7df8SBrandon Wyman             .WillOnce(Return("PN3456"))
9361d7a7df8SBrandon Wyman             .WillOnce(Return("FN3456"))
9371d7a7df8SBrandon Wyman             .WillOnce(Return("HEADER"))
9381d7a7df8SBrandon Wyman             .WillOnce(Return("SN3456"))
9391d7a7df8SBrandon Wyman             .WillOnce(Return("FW3456"));
9403c530fbdSBrandon Wyman #endif
9411d7a7df8SBrandon Wyman         psu.updateInventory();
9421d7a7df8SBrandon Wyman         // TODO: D-Bus mocking to verify values stored on D-Bus (???)
9431d7a7df8SBrandon Wyman     }
9441d7a7df8SBrandon Wyman     catch (...)
9451d7a7df8SBrandon Wyman     {
9461d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have caught exception.";
9471d7a7df8SBrandon Wyman     }
9483f1242f3SBrandon Wyman }
9493f1242f3SBrandon Wyman 
9503f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent)
9513f1242f3SBrandon Wyman {
9523f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
953681b2a36SB. J. Wyman 
954681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
9553ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
9563ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
9573f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), false);
9583f1242f3SBrandon Wyman 
959681b2a36SB. J. Wyman     // Change GPIO read to return 1 to indicate present.
960681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
961391a0690SBrandon Wyman     // Call to analyze() will update to present, that will trigger updating
962391a0690SBrandon Wyman     // to the correct/latest HWMON directory, in case it changes.
963391a0690SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
964391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
965391a0690SBrandon Wyman     // Call to analyze things will trigger read of STATUS_WORD and READ_VIN.
966391a0690SBrandon Wyman     // Default expectations will be on, no faults.
967391a0690SBrandon Wyman     PMBusExpectations expectations;
968391a0690SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
969*82affd94SBrandon Wyman     // Give it an input voltage in the 100-volt range.
970*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
971*82affd94SBrandon Wyman         .Times(1)
972*82affd94SBrandon Wyman         .WillOnce(Return("123456"));
973681b2a36SB. J. Wyman     psu.analyze();
974681b2a36SB. J. Wyman     EXPECT_EQ(psu.isPresent(), true);
9753f1242f3SBrandon Wyman }
9763f1242f3SBrandon Wyman 
9773f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted)
9783f1242f3SBrandon Wyman {
9793f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
980681b2a36SB. J. Wyman 
981681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, PSUGPIOLineName};
9823ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
9833ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
984681b2a36SB. J. Wyman     // Always return 1 to indicate present.
985681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
986391a0690SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
987391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
988391a0690SBrandon Wyman     // Call to analyze things will trigger read of STATUS_WORD and READ_VIN.
989391a0690SBrandon Wyman     // Default expectations will be on, no faults.
990391a0690SBrandon Wyman     PMBusExpectations expectations;
991391a0690SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
992*82affd94SBrandon Wyman     // Give it an input voltage in the 100-volt range.
993*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
994*82affd94SBrandon Wyman         .Times(1)
995*82affd94SBrandon Wyman         .WillOnce(Return("124680"));
996681b2a36SB. J. Wyman     psu.analyze();
9973f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), false);
998f07bc797SBrandon Wyman     // STATUS_WORD with fault bits on.
999b654c619SBrandon Wyman     expectations.statusWordValue = 0xFFFF;
1000f07bc797SBrandon Wyman     // STATUS_INPUT with fault bits on.
1001b654c619SBrandon Wyman     expectations.statusInputValue = 0xFF;
1002f07bc797SBrandon Wyman     // STATUS_MFR_SPECIFIC with faults bits on.
1003b654c619SBrandon Wyman     expectations.statusMFRValue = 0xFF;
100485c7bf41SBrandon Wyman     // STATUS_CML with faults bits on.
1005b654c619SBrandon Wyman     expectations.statusCMLValue = 0xFF;
10066710ba2cSBrandon Wyman     // STATUS_VOUT with fault bits on.
1007b654c619SBrandon Wyman     expectations.statusVOUTValue = 0xFF;
1008b10b3be0SBrandon Wyman     // STATUS_IOUT with fault bits on.
1009b10b3be0SBrandon Wyman     expectations.statusIOUTValue = 0xFF;
10107ee4d7e4SBrandon Wyman     // STATUS_FANS_1_2 with bits on.
10117ee4d7e4SBrandon Wyman     expectations.statusFans12Value = 0xFF;
101296893a46SBrandon Wyman     // STATUS_TEMPERATURE with fault bits on.
101396893a46SBrandon Wyman     expectations.statusTempValue = 0xFF;
1014b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1015*82affd94SBrandon Wyman     // Also get another read of READ_VIN.
1016*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1017*82affd94SBrandon Wyman         .Times(1)
1018*82affd94SBrandon Wyman         .WillOnce(Return("125790"));
10193f1242f3SBrandon Wyman     psu.analyze();
10203f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), true);
10213f1242f3SBrandon Wyman }
10223f1242f3SBrandon Wyman 
10233f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasInputFault)
10243f1242f3SBrandon Wyman {
10253f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
1026681b2a36SB. J. Wyman 
1027681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
10283ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
10293ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1030681b2a36SB. J. Wyman     // Always return 1 to indicate present.
1031681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
10323f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1033391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
10348da35c51SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
1035b654c619SBrandon Wyman     PMBusExpectations expectations;
1036b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1037*82affd94SBrandon Wyman     // Analyze call will also need good READ_VIN value to check.
1038*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1039*82affd94SBrandon Wyman         .Times(1)
1040*82affd94SBrandon Wyman         .WillOnce(Return("201100"));
10413f1242f3SBrandon Wyman     psu.analyze();
10423f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
1043f07bc797SBrandon Wyman     // STATUS_WORD with input fault/warn on.
1044b654c619SBrandon Wyman     expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
1045f07bc797SBrandon Wyman     // STATUS_INPUT with an input fault bit on.
1046b654c619SBrandon Wyman     expectations.statusInputValue = 0x80;
1047b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1048*82affd94SBrandon Wyman     // Analyze call will also need good READ_VIN value to check.
1049*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1050*82affd94SBrandon Wyman         .Times(1)
1051*82affd94SBrandon Wyman         .WillOnce(Return("201200"));
10523f1242f3SBrandon Wyman     psu.analyze();
10533f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), true);
1054f07bc797SBrandon Wyman     // STATUS_WORD with no bits on.
1055b654c619SBrandon Wyman     expectations.statusWordValue = 0;
1056b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1057*82affd94SBrandon Wyman     // Analyze call will also need good READ_VIN value to check.
1058*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1059*82affd94SBrandon Wyman         .Times(1)
1060*82affd94SBrandon Wyman         .WillOnce(Return("201300"));
10613f1242f3SBrandon Wyman     psu.analyze();
10623f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
10633f1242f3SBrandon Wyman }
10643f1242f3SBrandon Wyman 
10653f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault)
10663f1242f3SBrandon Wyman {
10673f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
1068681b2a36SB. J. Wyman 
1069681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
10703ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
10713ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1072681b2a36SB. J. Wyman     // Always return 1 to indicate present.
1073681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
10743f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1075391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
1076f07bc797SBrandon Wyman     // First return STATUS_WORD with no bits on.
10778da35c51SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
1078b654c619SBrandon Wyman     PMBusExpectations expectations;
1079b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1080*82affd94SBrandon Wyman     // Analyze call will also need good READ_VIN value to check.
1081*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1082*82affd94SBrandon Wyman         .Times(1)
1083*82affd94SBrandon Wyman         .WillOnce(Return("202100"));
10843f1242f3SBrandon Wyman     psu.analyze();
10853f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
1086f07bc797SBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
1087b654c619SBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1088f07bc797SBrandon Wyman     // STATUS_MFR_SPEFIC with bit(s) on.
1089b654c619SBrandon Wyman     expectations.statusMFRValue = 0xFF;
1090b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1091*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1092*82affd94SBrandon Wyman         .Times(1)
1093*82affd94SBrandon Wyman         .WillOnce(Return("202200"));
10943f1242f3SBrandon Wyman     psu.analyze();
10953f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), true);
1096f07bc797SBrandon Wyman     // Back to no bits on in STATUS_WORD
1097b654c619SBrandon Wyman     expectations.statusWordValue = 0;
1098b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1099*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1100*82affd94SBrandon Wyman         .Times(1)
1101*82affd94SBrandon Wyman         .WillOnce(Return("202300"));
11023f1242f3SBrandon Wyman     psu.analyze();
11033f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
11043f1242f3SBrandon Wyman }
11053f1242f3SBrandon Wyman 
11063f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault)
11073f1242f3SBrandon Wyman {
11083f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
1109681b2a36SB. J. Wyman 
1110681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
11113ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
11123ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1113681b2a36SB. J. Wyman     // Always return 1 to indicate present.
1114681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
11153f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1116391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
1117*82affd94SBrandon Wyman 
1118*82affd94SBrandon Wyman     // Presence change from missing to present will trigger in1_input read in
1119*82affd94SBrandon Wyman     // an attempt to get CLEAR_FAULTS called. Return value ignored.
1120*82affd94SBrandon Wyman     // Zero to non-zero voltage, for missing/present change, triggers clear
1121*82affd94SBrandon Wyman     // faults call again. Return value ignored.
1122*82affd94SBrandon Wyman     // Fault (low voltage) to not faulted (voltage in range) triggers clear
1123*82affd94SBrandon Wyman     // faults call a third time.
1124*82affd94SBrandon Wyman 
11258da35c51SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
1126b654c619SBrandon Wyman     PMBusExpectations expectations;
1127b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1128*82affd94SBrandon Wyman     // Analyze call will also need good READ_VIN value to check.
1129*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1130*82affd94SBrandon Wyman         .Times(1)
1131*82affd94SBrandon Wyman         .WillOnce(Return("201100"));
11323f1242f3SBrandon Wyman     psu.analyze();
11333f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
1134f07bc797SBrandon Wyman     // Turn fault on.
1135b654c619SBrandon Wyman     expectations.statusWordValue = (status_word::VIN_UV_FAULT);
113685c7bf41SBrandon Wyman     // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by
113785c7bf41SBrandon Wyman     // Figure 16, and assume bits on in STATUS_INPUT.
1138b654c619SBrandon Wyman     expectations.statusInputValue = 0x18;
1139b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1140*82affd94SBrandon Wyman     // If there is a VIN_UV fault, fake reading voltage of less than 20V
1141*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1142*82affd94SBrandon Wyman         .Times(1)
1143*82affd94SBrandon Wyman         .WillOnce(Return("19876"));
11443f1242f3SBrandon Wyman     psu.analyze();
11453f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), true);
1146f07bc797SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
1147b654c619SBrandon Wyman     expectations.statusWordValue = 0;
1148b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1149*82affd94SBrandon Wyman     // Updates now result in clearing faults if read voltage goes from below the
1150*82affd94SBrandon Wyman     // minimum, to within a valid range.
1151*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1152*82affd94SBrandon Wyman         .Times(1)
1153*82affd94SBrandon Wyman         .WillOnce(Return("201300"));
1154*82affd94SBrandon Wyman     // Went from below minimum to within range, expect CLEAR_FAULTS.
1155*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(3));
11563f1242f3SBrandon Wyman     psu.analyze();
11573f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
11583f1242f3SBrandon Wyman }
11596710ba2cSBrandon Wyman 
11606710ba2cSBrandon Wyman TEST_F(PowerSupplyTests, HasVoutOVFault)
11616710ba2cSBrandon Wyman {
11626710ba2cSBrandon Wyman     auto bus = sdbusplus::bus::new_default();
11636710ba2cSBrandon Wyman 
11646710ba2cSBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x69, PSUGPIOLineName};
11656710ba2cSBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
11666710ba2cSBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
11676710ba2cSBrandon Wyman     // Always return 1 to indicate present.
11686710ba2cSBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
11696710ba2cSBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1170391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
11716710ba2cSBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
1172b654c619SBrandon Wyman     PMBusExpectations expectations;
1173b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1174*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1175*82affd94SBrandon Wyman     // Initial value would be 0, so this read updates it to non-zero.
1176*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1177*82affd94SBrandon Wyman         .Times(1)
1178*82affd94SBrandon Wyman         .WillOnce(Return("202100"));
11796710ba2cSBrandon Wyman     psu.analyze();
11806710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), false);
11816710ba2cSBrandon Wyman     // Turn fault on.
1182b654c619SBrandon Wyman     expectations.statusWordValue = (status_word::VOUT_OV_FAULT);
11836710ba2cSBrandon Wyman     // STATUS_VOUT fault bit(s)
1184b654c619SBrandon Wyman     expectations.statusVOUTValue = 0x80;
118596893a46SBrandon Wyman     // STATUS_TEMPERATURE default.
1186b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1187*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1188*82affd94SBrandon Wyman         .Times(1)
1189*82affd94SBrandon Wyman         .WillOnce(Return("202200"));
11906710ba2cSBrandon Wyman     psu.analyze();
11916710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), true);
11926710ba2cSBrandon Wyman     // Back to no fault bits on in STATUS_WORD
1193b654c619SBrandon Wyman     expectations.statusWordValue = 0;
1194b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1195*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1196*82affd94SBrandon Wyman         .Times(1)
1197*82affd94SBrandon Wyman         .WillOnce(Return("202300"));
11986710ba2cSBrandon Wyman     psu.analyze();
11996710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), false);
12006710ba2cSBrandon Wyman }
120196893a46SBrandon Wyman 
1202b10b3be0SBrandon Wyman TEST_F(PowerSupplyTests, HasIoutOCFault)
1203b10b3be0SBrandon Wyman {
1204b10b3be0SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
1205b10b3be0SBrandon Wyman 
1206b10b3be0SBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName};
1207b10b3be0SBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
1208b10b3be0SBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1209b10b3be0SBrandon Wyman     // Always return 1 to indicate present.
1210b10b3be0SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1211b10b3be0SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1212391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
1213b10b3be0SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
1214b10b3be0SBrandon Wyman     PMBusExpectations expectations;
1215b10b3be0SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1216*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1217*82affd94SBrandon Wyman     // Initial value would be 0, so this read updates it to non-zero.
1218*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1219*82affd94SBrandon Wyman         .Times(1)
1220*82affd94SBrandon Wyman         .WillOnce(Return("203100"));
1221b10b3be0SBrandon Wyman     psu.analyze();
1222b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), false);
1223b10b3be0SBrandon Wyman     // Turn fault on.
1224b10b3be0SBrandon Wyman     expectations.statusWordValue = status_word::IOUT_OC_FAULT;
1225b10b3be0SBrandon Wyman     // STATUS_IOUT fault bit(s)
1226b10b3be0SBrandon Wyman     expectations.statusIOUTValue = 0x88;
1227b10b3be0SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1228*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1229*82affd94SBrandon Wyman         .Times(1)
1230*82affd94SBrandon Wyman         .WillOnce(Return("203200"));
1231b10b3be0SBrandon Wyman     psu.analyze();
1232b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), true);
1233b10b3be0SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
1234b10b3be0SBrandon Wyman     expectations.statusWordValue = 0;
1235b10b3be0SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1236*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1237*82affd94SBrandon Wyman         .Times(1)
1238*82affd94SBrandon Wyman         .WillOnce(Return("203300"));
1239b10b3be0SBrandon Wyman     psu.analyze();
1240b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), false);
1241b10b3be0SBrandon Wyman }
1242b10b3be0SBrandon Wyman 
12432cf46945SBrandon Wyman TEST_F(PowerSupplyTests, HasVoutUVFault)
12442cf46945SBrandon Wyman {
12452cf46945SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
12462cf46945SBrandon Wyman 
12472cf46945SBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName};
12482cf46945SBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
12492cf46945SBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
12502cf46945SBrandon Wyman     // Always return 1 to indicate present.
12512cf46945SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
12522cf46945SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1253391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
1254391a0690SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
12552cf46945SBrandon Wyman     PMBusExpectations expectations;
12562cf46945SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1257*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1258*82affd94SBrandon Wyman     // Initial value would be 0, so this read updates it to non-zero.
1259*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1260*82affd94SBrandon Wyman         .Times(1)
1261*82affd94SBrandon Wyman         .WillOnce(Return("204100"));
12622cf46945SBrandon Wyman     psu.analyze();
12632cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
12642cf46945SBrandon Wyman     // Turn fault on.
12652cf46945SBrandon Wyman     expectations.statusWordValue = (status_word::VOUT_FAULT);
12662cf46945SBrandon Wyman     // STATUS_VOUT fault bit(s)
12672cf46945SBrandon Wyman     expectations.statusVOUTValue = 0x30;
12682cf46945SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1269*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1270*82affd94SBrandon Wyman         .Times(1)
1271*82affd94SBrandon Wyman         .WillOnce(Return("204200"));
12722cf46945SBrandon Wyman     psu.analyze();
12732cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), true);
12742cf46945SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
12752cf46945SBrandon Wyman     expectations.statusWordValue = 0;
12762cf46945SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1277*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1278*82affd94SBrandon Wyman         .Times(1)
1279*82affd94SBrandon Wyman         .WillOnce(Return("204300"));
12802cf46945SBrandon Wyman     psu.analyze();
12812cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
12822cf46945SBrandon Wyman }
12832cf46945SBrandon Wyman 
12847ee4d7e4SBrandon Wyman TEST_F(PowerSupplyTests, HasFanFault)
12857ee4d7e4SBrandon Wyman {
12867ee4d7e4SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
12877ee4d7e4SBrandon Wyman 
12887ee4d7e4SBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName};
12897ee4d7e4SBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
12907ee4d7e4SBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
12917ee4d7e4SBrandon Wyman     // Always return 1 to indicate present.
12927ee4d7e4SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
12937ee4d7e4SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1294391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
12957ee4d7e4SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
12967ee4d7e4SBrandon Wyman     PMBusExpectations expectations;
12977ee4d7e4SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1298*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1299*82affd94SBrandon Wyman     // Initial value would be 0, so this read updates it to non-zero.
1300*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1301*82affd94SBrandon Wyman         .Times(1)
1302*82affd94SBrandon Wyman         .WillOnce(Return("205100"));
13037ee4d7e4SBrandon Wyman     psu.analyze();
13047ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), false);
13057ee4d7e4SBrandon Wyman     // Turn fault on.
13067ee4d7e4SBrandon Wyman     expectations.statusWordValue = (status_word::FAN_FAULT);
13077ee4d7e4SBrandon Wyman     // STATUS_FANS_1_2 fault bit on (Fan 1 Fault)
13087ee4d7e4SBrandon Wyman     expectations.statusFans12Value = 0x80;
13097ee4d7e4SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1310*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1311*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1312*82affd94SBrandon Wyman         .Times(1)
1313*82affd94SBrandon Wyman         .WillOnce(Return("205200"));
13147ee4d7e4SBrandon Wyman     psu.analyze();
13157ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), true);
13167ee4d7e4SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
13177ee4d7e4SBrandon Wyman     expectations.statusWordValue = 0;
13187ee4d7e4SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1319*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1320*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1321*82affd94SBrandon Wyman         .Times(1)
1322*82affd94SBrandon Wyman         .WillOnce(Return("205300"));
13237ee4d7e4SBrandon Wyman     psu.analyze();
13247ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), false);
13257ee4d7e4SBrandon Wyman }
13267ee4d7e4SBrandon Wyman 
132796893a46SBrandon Wyman TEST_F(PowerSupplyTests, HasTempFault)
132896893a46SBrandon Wyman {
132996893a46SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
133096893a46SBrandon Wyman 
133196893a46SBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName};
133296893a46SBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
133396893a46SBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
133496893a46SBrandon Wyman     // Always return 1 to indicate present.
133596893a46SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
133696893a46SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1337391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
133896893a46SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
133996893a46SBrandon Wyman     PMBusExpectations expectations;
134096893a46SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1341*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1342*82affd94SBrandon Wyman     // Initial value would be 0, so this read updates it to non-zero.
1343*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1344*82affd94SBrandon Wyman         .Times(1)
1345*82affd94SBrandon Wyman         .WillOnce(Return("206100"));
134696893a46SBrandon Wyman     psu.analyze();
134796893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), false);
134896893a46SBrandon Wyman     // Turn fault on.
134996893a46SBrandon Wyman     expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
135096893a46SBrandon Wyman     // STATUS_TEMPERATURE fault bit on (OT Fault)
135196893a46SBrandon Wyman     expectations.statusTempValue = 0x80;
135296893a46SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1353*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1354*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1355*82affd94SBrandon Wyman         .Times(1)
1356*82affd94SBrandon Wyman         .WillOnce(Return("206200"));
135796893a46SBrandon Wyman     psu.analyze();
135896893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), true);
135996893a46SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
136096893a46SBrandon Wyman     expectations.statusWordValue = 0;
136196893a46SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1362*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1363*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1364*82affd94SBrandon Wyman         .Times(1)
1365*82affd94SBrandon Wyman         .WillOnce(Return("206300"));
136696893a46SBrandon Wyman     psu.analyze();
136796893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), false);
136896893a46SBrandon Wyman }
13692916ea52SBrandon Wyman 
13702916ea52SBrandon Wyman TEST_F(PowerSupplyTests, HasPgoodFault)
13712916ea52SBrandon Wyman {
13722916ea52SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
13732916ea52SBrandon Wyman 
13742916ea52SBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6b, PSUGPIOLineName};
13752916ea52SBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
13762916ea52SBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
13772916ea52SBrandon Wyman     // Always return 1 to indicate present.
13782916ea52SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
13792916ea52SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1380391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
13812916ea52SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
13822916ea52SBrandon Wyman     PMBusExpectations expectations;
13832916ea52SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1384*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1385*82affd94SBrandon Wyman     // Initial value would be 0, so this read updates it to non-zero.
1386*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1387*82affd94SBrandon Wyman         .Times(1)
1388*82affd94SBrandon Wyman         .WillOnce(Return("207100"));
13892916ea52SBrandon Wyman     psu.analyze();
13902916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
1391391a0690SBrandon Wyman     // Setup another expectation of no faults.
1392391a0690SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1393*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1394*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1395*82affd94SBrandon Wyman         .Times(1)
1396*82affd94SBrandon Wyman         .WillOnce(Return("207200"));
1397*82affd94SBrandon Wyman     psu.analyze();
1398*82affd94SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
1399*82affd94SBrandon Wyman     // Setup another expectation of no faults.
1400*82affd94SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1401*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1402*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1403*82affd94SBrandon Wyman         .Times(1)
1404*82affd94SBrandon Wyman         .WillOnce(Return("207300"));
1405391a0690SBrandon Wyman     psu.analyze();
1406391a0690SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
14072916ea52SBrandon Wyman     // Turn PGOOD# off (fault on).
14082916ea52SBrandon Wyman     expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED);
14092916ea52SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1410*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1411*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1412*82affd94SBrandon Wyman         .Times(1)
1413*82affd94SBrandon Wyman         .WillOnce(Return("207400"));
14142916ea52SBrandon Wyman     psu.analyze();
141506ca4590SBrandon Wyman     // Expect false until reaches DEGLITCH_LIMIT
141606ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
141706ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1418*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1419*82affd94SBrandon Wyman         .Times(1)
1420*82affd94SBrandon Wyman         .WillOnce(Return("207500"));
142106ca4590SBrandon Wyman     psu.analyze();
142206ca4590SBrandon Wyman     // Expect false until reaches DEGLITCH_LIMIT
142306ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
142406ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1425*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1426*82affd94SBrandon Wyman         .Times(1)
1427*82affd94SBrandon Wyman         .WillOnce(Return("207600"));
142806ca4590SBrandon Wyman     psu.analyze();
142906ca4590SBrandon Wyman     // DEGLITCH_LIMIT reached, expect true.
14302916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), true);
14312916ea52SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
14322916ea52SBrandon Wyman     expectations.statusWordValue = 0;
14332916ea52SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1434*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1435*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1436*82affd94SBrandon Wyman         .Times(1)
1437*82affd94SBrandon Wyman         .WillOnce(Return("207700"));
14382916ea52SBrandon Wyman     psu.analyze();
14392916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
1440*82affd94SBrandon Wyman 
14412916ea52SBrandon Wyman     // Turn OFF bit on
14422916ea52SBrandon Wyman     expectations.statusWordValue = (status_word::UNIT_IS_OFF);
14432916ea52SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1444*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1445*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1446*82affd94SBrandon Wyman         .Times(1)
1447*82affd94SBrandon Wyman         .WillOnce(Return("208100"));
14482916ea52SBrandon Wyman     psu.analyze();
144906ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
145006ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1451*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1452*82affd94SBrandon Wyman         .Times(1)
1453*82affd94SBrandon Wyman         .WillOnce(Return("208200"));
145406ca4590SBrandon Wyman     psu.analyze();
145506ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
145606ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1457*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1458*82affd94SBrandon Wyman         .Times(1)
1459*82affd94SBrandon Wyman         .WillOnce(Return("208300"));
146006ca4590SBrandon Wyman     psu.analyze();
14612916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), true);
14622916ea52SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
14632916ea52SBrandon Wyman     expectations.statusWordValue = 0;
14642916ea52SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1465*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1466*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1467*82affd94SBrandon Wyman         .Times(1)
1468*82affd94SBrandon Wyman         .WillOnce(Return("208400"));
14692916ea52SBrandon Wyman     psu.analyze();
14702916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
14712916ea52SBrandon Wyman }
147239ea02bcSBrandon Wyman 
147339ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSKillFault)
147439ea02bcSBrandon Wyman {
147539ea02bcSBrandon Wyman     auto bus = sdbusplus::bus::new_default();
147639ea02bcSBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 4, 0x6d, PSUGPIOLineName};
147739ea02bcSBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
147839ea02bcSBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
147939ea02bcSBrandon Wyman     // Always return 1 to indicate present.
148039ea02bcSBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
148139ea02bcSBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1482*82affd94SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
148339ea02bcSBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
148439ea02bcSBrandon Wyman     PMBusExpectations expectations;
148539ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1486*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1487*82affd94SBrandon Wyman     // Initial value would be 0, so this read updates it to non-zero.
1488*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1489*82affd94SBrandon Wyman         .Times(1)
1490*82affd94SBrandon Wyman         .WillOnce(Return("208100"));
149139ea02bcSBrandon Wyman     psu.analyze();
149239ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
149339ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
149439ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
149539ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit(s) on.
149639ea02bcSBrandon Wyman     expectations.statusMFRValue = 0xFF;
149739ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1498*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1499*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1500*82affd94SBrandon Wyman         .Times(1)
1501*82affd94SBrandon Wyman         .WillOnce(Return("208200"));
150239ea02bcSBrandon Wyman     psu.analyze();
150339ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), true);
150439ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
150539ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
150639ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1507*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1508*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1509*82affd94SBrandon Wyman         .Times(1)
1510*82affd94SBrandon Wyman         .WillOnce(Return("208300"));
151139ea02bcSBrandon Wyman     psu.analyze();
151239ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
151339ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
151439ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
151539ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit 4 on.
151639ea02bcSBrandon Wyman     expectations.statusMFRValue = 0x10;
151739ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1518*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1519*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1520*82affd94SBrandon Wyman         .Times(1)
1521*82affd94SBrandon Wyman         .WillOnce(Return("208400"));
152239ea02bcSBrandon Wyman     psu.analyze();
152339ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), true);
152439ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
152539ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
152639ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1527*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1528*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1529*82affd94SBrandon Wyman         .Times(1)
1530*82affd94SBrandon Wyman         .WillOnce(Return("208500"));
153139ea02bcSBrandon Wyman     psu.analyze();
153239ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
153339ea02bcSBrandon Wyman }
153439ea02bcSBrandon Wyman 
153539ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPS12VcsFault)
153639ea02bcSBrandon Wyman {
153739ea02bcSBrandon Wyman     auto bus = sdbusplus::bus::new_default();
153839ea02bcSBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 5, 0x6e, PSUGPIOLineName};
153939ea02bcSBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
154039ea02bcSBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
154139ea02bcSBrandon Wyman     // Always return 1 to indicate present.
154239ea02bcSBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
154339ea02bcSBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1544*82affd94SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
154539ea02bcSBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
154639ea02bcSBrandon Wyman     PMBusExpectations expectations;
154739ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1548*82affd94SBrandon Wyman     // Call to analyze will trigger read of "in1_input" to check voltage.
1549*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1550*82affd94SBrandon Wyman         .Times(1)
1551*82affd94SBrandon Wyman         .WillOnce(Return("209100"));
155239ea02bcSBrandon Wyman     psu.analyze();
155339ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
155439ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
155539ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
155639ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit(s) on.
155739ea02bcSBrandon Wyman     expectations.statusMFRValue = 0xFF;
155839ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1559*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1560*82affd94SBrandon Wyman         .Times(1)
1561*82affd94SBrandon Wyman         .WillOnce(Return("209200"));
156239ea02bcSBrandon Wyman     psu.analyze();
156339ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), true);
156439ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
156539ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
156639ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1567*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1568*82affd94SBrandon Wyman         .Times(1)
1569*82affd94SBrandon Wyman         .WillOnce(Return("209300"));
157039ea02bcSBrandon Wyman     psu.analyze();
157139ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
157239ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
157339ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
157439ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit 6 on.
157539ea02bcSBrandon Wyman     expectations.statusMFRValue = 0x40;
157639ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1577*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1578*82affd94SBrandon Wyman         .Times(1)
1579*82affd94SBrandon Wyman         .WillOnce(Return("209400"));
158039ea02bcSBrandon Wyman     psu.analyze();
158139ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), true);
158239ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
158339ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
158439ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1585*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1586*82affd94SBrandon Wyman         .Times(1)
1587*82affd94SBrandon Wyman         .WillOnce(Return("209500"));
158839ea02bcSBrandon Wyman     psu.analyze();
158939ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
159039ea02bcSBrandon Wyman }
159139ea02bcSBrandon Wyman 
159239ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSCS12VFault)
159339ea02bcSBrandon Wyman {
159439ea02bcSBrandon Wyman     auto bus = sdbusplus::bus::new_default();
159539ea02bcSBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f, PSUGPIOLineName};
159639ea02bcSBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
159739ea02bcSBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
159839ea02bcSBrandon Wyman     // Always return 1 to indicate present.
159939ea02bcSBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
160039ea02bcSBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1601*82affd94SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
160239ea02bcSBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
160339ea02bcSBrandon Wyman     PMBusExpectations expectations;
160439ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1605*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1606*82affd94SBrandon Wyman         .Times(1)
1607*82affd94SBrandon Wyman         .WillOnce(Return("209100"));
160839ea02bcSBrandon Wyman     psu.analyze();
160939ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
161039ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
161139ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
161239ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit(s) on.
161339ea02bcSBrandon Wyman     expectations.statusMFRValue = 0xFF;
161439ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1615*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1616*82affd94SBrandon Wyman         .Times(1)
1617*82affd94SBrandon Wyman         .WillOnce(Return("209200"));
161839ea02bcSBrandon Wyman     psu.analyze();
161939ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), true);
162039ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
162139ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
162239ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1623*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1624*82affd94SBrandon Wyman         .Times(1)
1625*82affd94SBrandon Wyman         .WillOnce(Return("209300"));
162639ea02bcSBrandon Wyman     psu.analyze();
162739ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
162839ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
162939ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
163039ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit 7 on.
163139ea02bcSBrandon Wyman     expectations.statusMFRValue = 0x80;
163239ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1633*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1634*82affd94SBrandon Wyman         .Times(1)
1635*82affd94SBrandon Wyman         .WillOnce(Return("209400"));
163639ea02bcSBrandon Wyman     psu.analyze();
163739ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), true);
163839ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
163939ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
164039ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1641*82affd94SBrandon Wyman     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1642*82affd94SBrandon Wyman         .Times(1)
1643*82affd94SBrandon Wyman         .WillOnce(Return("209500"));
164439ea02bcSBrandon Wyman     psu.analyze();
164539ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
164639ea02bcSBrandon Wyman }
1647