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 
953f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Constructor)
963f1242f3SBrandon Wyman {
973f1242f3SBrandon Wyman     /**
983f1242f3SBrandon Wyman      * @param[in] invpath - String for inventory path to use
993f1242f3SBrandon Wyman      * @param[in] i2cbus - The bus number this power supply is on
1003f1242f3SBrandon Wyman      * @param[in] i2caddr - The 16-bit I2C address of the power supply
101681b2a36SB. J. Wyman      * @param[in] gpioLineName - The string for the gpio-line-name to read for
102681b2a36SB. J. Wyman      * presence.
103681b2a36SB. J. Wyman      * @param[in] bindDelay - Time in milliseconds to delay binding the device
104681b2a36SB. J. Wyman      * driver after seeing the presence line go active.
1053f1242f3SBrandon Wyman      */
1063f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
1071d7a7df8SBrandon Wyman 
1081d7a7df8SBrandon Wyman     // Try where inventory path is empty, constructor should fail.
1091d7a7df8SBrandon Wyman     try
1101d7a7df8SBrandon Wyman     {
111681b2a36SB. J. Wyman         auto psu =
112681b2a36SB. J. Wyman             std::make_unique<PowerSupply>(bus, "", 3, 0x68, PSUGPIOLineName);
1131d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have reached this line.";
1141d7a7df8SBrandon Wyman     }
1151d7a7df8SBrandon Wyman     catch (const std::invalid_argument& e)
1161d7a7df8SBrandon Wyman     {
1171d7a7df8SBrandon Wyman         EXPECT_STREQ(e.what(), "Invalid empty inventoryPath");
1181d7a7df8SBrandon Wyman     }
1191d7a7df8SBrandon Wyman     catch (...)
1201d7a7df8SBrandon Wyman     {
1211d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have caught exception.";
1221d7a7df8SBrandon Wyman     }
1231d7a7df8SBrandon Wyman 
124681b2a36SB. J. Wyman     // TODO: Try invalid i2c address?
125681b2a36SB. J. Wyman 
126681b2a36SB. J. Wyman     // Try where gpioLineName is empty.
1271d7a7df8SBrandon Wyman     try
1281d7a7df8SBrandon Wyman     {
1291d7a7df8SBrandon Wyman         auto psu =
130681b2a36SB. J. Wyman             std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, "");
131681b2a36SB. J. Wyman         ADD_FAILURE()
132681b2a36SB. J. Wyman             << "Should not have reached this line. Invalid gpioLineName.";
133681b2a36SB. J. Wyman     }
134681b2a36SB. J. Wyman     catch (const std::invalid_argument& e)
135681b2a36SB. J. Wyman     {
136681b2a36SB. J. Wyman         EXPECT_STREQ(e.what(), "Invalid empty gpioLineName");
137681b2a36SB. J. Wyman     }
138681b2a36SB. J. Wyman     catch (...)
139681b2a36SB. J. Wyman     {
140681b2a36SB. J. Wyman         ADD_FAILURE() << "Should not have caught exception.";
141681b2a36SB. J. Wyman     }
142681b2a36SB. J. Wyman 
143681b2a36SB. J. Wyman     // Test with valid arguments
144681b2a36SB. J. Wyman     // NOT using D-Bus inventory path for presence.
145681b2a36SB. J. Wyman     try
146681b2a36SB. J. Wyman     {
147681b2a36SB. J. Wyman         auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68,
148681b2a36SB. J. Wyman                                                  PSUGPIOLineName);
1493f1242f3SBrandon Wyman 
1503f1242f3SBrandon Wyman         EXPECT_EQ(psu->isPresent(), false);
1513f1242f3SBrandon Wyman         EXPECT_EQ(psu->isFaulted(), false);
1528da35c51SBrandon Wyman         EXPECT_EQ(psu->hasCommFault(), false);
1533f1242f3SBrandon Wyman         EXPECT_EQ(psu->hasInputFault(), false);
1543f1242f3SBrandon Wyman         EXPECT_EQ(psu->hasMFRFault(), false);
1553f1242f3SBrandon Wyman         EXPECT_EQ(psu->hasVINUVFault(), false);
1566710ba2cSBrandon Wyman         EXPECT_EQ(psu->hasVoutOVFault(), false);
157b10b3be0SBrandon Wyman         EXPECT_EQ(psu->hasIoutOCFault(), false);
1582cf46945SBrandon Wyman         EXPECT_EQ(psu->hasVoutUVFault(), false);
1597ee4d7e4SBrandon Wyman         EXPECT_EQ(psu->hasFanFault(), false);
16096893a46SBrandon Wyman         EXPECT_EQ(psu->hasTempFault(), false);
1612916ea52SBrandon Wyman         EXPECT_EQ(psu->hasPgoodFault(), false);
162*39ea02bcSBrandon Wyman         EXPECT_EQ(psu->hasPSKillFault(), false);
163*39ea02bcSBrandon Wyman         EXPECT_EQ(psu->hasPS12VcsFault(), false);
164*39ea02bcSBrandon Wyman         EXPECT_EQ(psu->hasPSCS12VFault(), false);
1653f1242f3SBrandon Wyman     }
1661d7a7df8SBrandon Wyman     catch (...)
1671d7a7df8SBrandon Wyman     {
1681d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have caught exception.";
1691d7a7df8SBrandon Wyman     }
170681b2a36SB. J. Wyman 
171681b2a36SB. J. Wyman     // Test with valid arguments
172681b2a36SB. J. Wyman     // TODO: Using D-Bus inventory path for presence.
173681b2a36SB. J. Wyman     try
174681b2a36SB. J. Wyman     {
175681b2a36SB. J. Wyman         // FIXME: How do I get that presenceGPIO.read() in the startup to throw
176681b2a36SB. J. Wyman         // an exception?
177681b2a36SB. J. Wyman 
178681b2a36SB. J. Wyman         // EXPECT_CALL(mockedUtil, getPresence(_,
179681b2a36SB. J. Wyman         // StrEq(PSUInventoryPath)))
180681b2a36SB. J. Wyman         //    .Times(1);
181681b2a36SB. J. Wyman     }
182681b2a36SB. J. Wyman     catch (...)
183681b2a36SB. J. Wyman     {
184681b2a36SB. J. Wyman         ADD_FAILURE() << "Should not have caught exception.";
185681b2a36SB. J. Wyman     }
1861d7a7df8SBrandon Wyman }
1873f1242f3SBrandon Wyman 
1883f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Analyze)
1893f1242f3SBrandon Wyman {
1903f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
1913f1242f3SBrandon Wyman 
192b654c619SBrandon Wyman     {
193681b2a36SB. J. Wyman         // If I default to reading the GPIO, I will NOT expect a call to
194681b2a36SB. J. Wyman         // getPresence().
195681b2a36SB. J. Wyman 
196681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
1973ca062aeSAdriana Kobylak         MockedGPIOInterface* mockPresenceGPIO =
1983ca062aeSAdriana Kobylak             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
199681b2a36SB. J. Wyman         EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0));
200681b2a36SB. J. Wyman 
2013f1242f3SBrandon Wyman         psu.analyze();
2023f1242f3SBrandon Wyman         // By default, nothing should change.
2033f1242f3SBrandon Wyman         EXPECT_EQ(psu.isPresent(), false);
2043f1242f3SBrandon Wyman         EXPECT_EQ(psu.isFaulted(), false);
2053f1242f3SBrandon Wyman         EXPECT_EQ(psu.hasInputFault(), false);
2063f1242f3SBrandon Wyman         EXPECT_EQ(psu.hasMFRFault(), false);
2073f1242f3SBrandon Wyman         EXPECT_EQ(psu.hasVINUVFault(), false);
20885c7bf41SBrandon Wyman         EXPECT_EQ(psu.hasCommFault(), false);
2096710ba2cSBrandon Wyman         EXPECT_EQ(psu.hasVoutOVFault(), false);
210b10b3be0SBrandon Wyman         EXPECT_EQ(psu.hasIoutOCFault(), false);
2112cf46945SBrandon Wyman         EXPECT_EQ(psu.hasVoutUVFault(), false);
2127ee4d7e4SBrandon Wyman         EXPECT_EQ(psu.hasFanFault(), false);
21396893a46SBrandon Wyman         EXPECT_EQ(psu.hasTempFault(), false);
2142916ea52SBrandon Wyman         EXPECT_EQ(psu.hasPgoodFault(), false);
215*39ea02bcSBrandon Wyman         EXPECT_EQ(psu.hasPSKillFault(), false);
216*39ea02bcSBrandon Wyman         EXPECT_EQ(psu.hasPS12VcsFault(), false);
217*39ea02bcSBrandon Wyman         EXPECT_EQ(psu.hasPSCS12VFault(), false);
218b654c619SBrandon Wyman     }
2193f1242f3SBrandon Wyman 
220681b2a36SB. J. Wyman     PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
221681b2a36SB. J. Wyman     // In order to get the various faults tested, the power supply needs to
222681b2a36SB. J. Wyman     // be present in order to read from the PMBus device(s).
2233ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO2 =
2243ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO());
22506ca4590SBrandon Wyman     // Always return 1 to indicate present.
22606ca4590SBrandon Wyman     // Each analyze() call will trigger a read of the presence GPIO.
22706ca4590SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO2, read()).WillRepeatedly(Return(1));
228681b2a36SB. J. Wyman     EXPECT_EQ(psu2.isPresent(), false);
2293f1242f3SBrandon Wyman 
2303f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus());
23106ca4590SBrandon Wyman     // First analyze() call will trigger missing to present, requiring update
23206ca4590SBrandon Wyman     // to find the new HWMON directory.
23306ca4590SBrandon Wyman     EXPECT_CALL(mockPMBus, findHwmonDir());
2348da35c51SBrandon Wyman     // Presence change from missing to present will trigger write to
2358da35c51SBrandon Wyman     // ON_OFF_CONFIG.
2368da35c51SBrandon Wyman     EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, _, _));
237b654c619SBrandon Wyman     // Presence change from missing to present will trigger in1_input read
238b654c619SBrandon Wyman     // in an attempt to get CLEAR_FAULTS called.
239f07bc797SBrandon Wyman     EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(206000));
24006ca4590SBrandon Wyman     // Change from missing to present will trigger call to update Present
24106ca4590SBrandon Wyman     // property in the inventory
24206ca4590SBrandon Wyman     EXPECT_CALL(mockedUtil, setPresence(_, _, true, _));
243b654c619SBrandon Wyman 
244b654c619SBrandon Wyman     // STATUS_WORD INPUT fault.
245b654c619SBrandon Wyman     {
246b654c619SBrandon Wyman         // Start with STATUS_WORD 0x0000. Powered on, no faults.
247b654c619SBrandon Wyman         // Set expectations for a no fault
248b654c619SBrandon Wyman         PMBusExpectations expectations;
249b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
2503f1242f3SBrandon Wyman         psu2.analyze();
2513f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
2523f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), false);
2533f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
2543f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
2553f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
25685c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
2576710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
258b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
2592cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
2607ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
26196893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
2622916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
263*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
264*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
265*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
2663f1242f3SBrandon Wyman 
267b654c619SBrandon Wyman         // Update expectations for STATUS_WORD input fault/warn
26896893a46SBrandon Wyman         // STATUS_INPUT fault bits ... on.
269b654c619SBrandon Wyman         expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
270b654c619SBrandon Wyman         expectations.statusInputValue = 0x38;
271b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
2723f1242f3SBrandon Wyman         psu2.analyze();
2733f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
2743f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
2753f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), true);
2763f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
2773f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
27885c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
2796710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
280b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
2812cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
2827ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
28396893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
2842916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
285*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
286*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
287*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
288b654c619SBrandon Wyman     }
2893f1242f3SBrandon Wyman 
2903f1242f3SBrandon Wyman     // STATUS_WORD INPUT/UV fault.
291b654c619SBrandon Wyman     {
2923f1242f3SBrandon Wyman         // First need it to return good status, then the fault
293b654c619SBrandon Wyman         PMBusExpectations expectations;
294b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
2953f1242f3SBrandon Wyman         psu2.analyze();
2968da35c51SBrandon Wyman         // Now set fault bits in STATUS_WORD
297b654c619SBrandon Wyman         expectations.statusWordValue =
2988da35c51SBrandon Wyman             (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT);
2998da35c51SBrandon Wyman         // STATUS_INPUT fault bits ... on.
300b654c619SBrandon Wyman         expectations.statusInputValue = 0x38;
301b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
3023f1242f3SBrandon Wyman         psu2.analyze();
3033f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
3043f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
305f07bc797SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), true);
3063f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
3073f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), true);
30885c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
3096710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
310b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
3112cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
3127ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
31396893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
3142916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
315*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
316*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
317*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
318b654c619SBrandon Wyman     }
3193f1242f3SBrandon Wyman 
3203f1242f3SBrandon Wyman     // STATUS_WORD MFR fault.
321b654c619SBrandon Wyman     {
322f07bc797SBrandon Wyman         // First need it to return good status, then the fault
323b654c619SBrandon Wyman         PMBusExpectations expectations;
324b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
3253f1242f3SBrandon Wyman         psu2.analyze();
3268da35c51SBrandon Wyman         // Now STATUS_WORD with MFR fault bit on.
327b654c619SBrandon Wyman         expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
3288da35c51SBrandon Wyman         // STATUS_MFR bits on.
329b654c619SBrandon Wyman         expectations.statusMFRValue = 0xFF;
330b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
3313f1242f3SBrandon Wyman         psu2.analyze();
3323f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
3333f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
3343f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
3353f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), true);
3363f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
33785c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
3386710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
339b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
3402cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
3417ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
34296893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
3432916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
344*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), true);
345*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), true);
346*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), true);
347b654c619SBrandon Wyman     }
3483f1242f3SBrandon Wyman 
34996893a46SBrandon Wyman     // Temperature fault.
350b654c619SBrandon Wyman     {
351f07bc797SBrandon Wyman         // First STATUS_WORD with no bits set, then with temperature fault.
352b654c619SBrandon Wyman         PMBusExpectations expectations;
353b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
3543f1242f3SBrandon Wyman         psu2.analyze();
3558da35c51SBrandon Wyman         // STATUS_WORD with temperature fault bit on.
356b654c619SBrandon Wyman         expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
35796893a46SBrandon Wyman         // STATUS_TEMPERATURE with fault bit(s) on.
35896893a46SBrandon Wyman         expectations.statusTempValue = 0x10;
359b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
3603f1242f3SBrandon Wyman         psu2.analyze();
3613f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
36296893a46SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
3633f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
3643f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
3653f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
36685c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
3676710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
368b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
3692cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
3707ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
37196893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), true);
3722916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
373*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
374*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
375*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
376b654c619SBrandon Wyman     }
37785c7bf41SBrandon Wyman 
37885c7bf41SBrandon Wyman     // CML fault
379b654c619SBrandon Wyman     {
38085c7bf41SBrandon Wyman         // First STATUS_WORD wit no bits set, then with CML fault.
381b654c619SBrandon Wyman         PMBusExpectations expectations;
382b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
38385c7bf41SBrandon Wyman         psu2.analyze();
3848da35c51SBrandon Wyman         // STATUS_WORD with CML fault bit on.
385b654c619SBrandon Wyman         expectations.statusWordValue = (status_word::CML_FAULT);
38685c7bf41SBrandon Wyman         // Turn on STATUS_CML fault bit(s)
387b654c619SBrandon Wyman         expectations.statusCMLValue = 0xFF;
388b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
38985c7bf41SBrandon Wyman         psu2.analyze();
39085c7bf41SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
39185c7bf41SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
39285c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
39385c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
39485c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
39585c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), true);
3966710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
397b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
3982cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
3997ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
40096893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
4012916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
402*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
403*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
404*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
405b654c619SBrandon Wyman     }
4066710ba2cSBrandon Wyman 
4076710ba2cSBrandon Wyman     // VOUT_OV_FAULT fault
408b654c619SBrandon Wyman     {
4096710ba2cSBrandon Wyman         // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault.
410b654c619SBrandon Wyman         PMBusExpectations expectations;
411b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
4126710ba2cSBrandon Wyman         psu2.analyze();
4136710ba2cSBrandon Wyman         // STATUS_WORD with VOUT/VOUT_OV fault.
414b654c619SBrandon Wyman         expectations.statusWordValue =
4156710ba2cSBrandon Wyman             ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT));
4166710ba2cSBrandon Wyman         // Turn on STATUS_VOUT fault bit(s)
417b654c619SBrandon Wyman         expectations.statusVOUTValue = 0xA0;
41896893a46SBrandon Wyman         // STATUS_TEMPERATURE don't care (default)
419b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
4206710ba2cSBrandon Wyman         psu2.analyze();
4216710ba2cSBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
4226710ba2cSBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
4236710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
4246710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
4256710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
4266710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
4276710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), true);
4282cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
429b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
4307ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
431b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
432b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
433*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
434*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
435*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
436b10b3be0SBrandon Wyman     }
437b10b3be0SBrandon Wyman 
438b10b3be0SBrandon Wyman     // IOUT_OC_FAULT fault
439b10b3be0SBrandon Wyman     {
440b10b3be0SBrandon Wyman         // First STATUS_WORD with no bits set, then with IOUT_OC fault.
441b10b3be0SBrandon Wyman         PMBusExpectations expectations;
442b10b3be0SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
443b10b3be0SBrandon Wyman         psu2.analyze();
444b10b3be0SBrandon Wyman         // STATUS_WORD with IOUT_OC fault.
445b10b3be0SBrandon Wyman         expectations.statusWordValue = status_word::IOUT_OC_FAULT;
446b10b3be0SBrandon Wyman         // Turn on STATUS_IOUT fault bit(s)
447b10b3be0SBrandon Wyman         expectations.statusIOUTValue = 0x88;
448b10b3be0SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
449b10b3be0SBrandon Wyman         psu2.analyze();
450b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
451b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
452b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
453b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
454b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
455b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
456b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
457b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), true);
4582cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
4597ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
4602cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
4612cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
462*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
463*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
464*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
4652cf46945SBrandon Wyman     }
4662cf46945SBrandon Wyman 
4672cf46945SBrandon Wyman     // VOUT_UV_FAULT
4682cf46945SBrandon Wyman     {
4692cf46945SBrandon Wyman         // First STATUS_WORD with no bits set, then with VOUT fault.
4702cf46945SBrandon Wyman         PMBusExpectations expectations;
4712cf46945SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
4722cf46945SBrandon Wyman         psu2.analyze();
4732cf46945SBrandon Wyman         // Change STATUS_WORD to indicate VOUT fault.
4742cf46945SBrandon Wyman         expectations.statusWordValue = (status_word::VOUT_FAULT);
4752cf46945SBrandon Wyman         // Turn on STATUS_VOUT fault bit(s)
4762cf46945SBrandon Wyman         expectations.statusVOUTValue = 0x30;
4772cf46945SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
4782cf46945SBrandon Wyman         psu2.analyze();
4792cf46945SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
4802cf46945SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
4812cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
4822cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
4832cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
4842cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
4852cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
4862cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
4872cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), true);
4887ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
48996893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
4902916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
491*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
492*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
493*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
494b654c619SBrandon Wyman     }
4953f1242f3SBrandon Wyman 
4967ee4d7e4SBrandon Wyman     // Fan fault
497b654c619SBrandon Wyman     {
498b654c619SBrandon Wyman         // First STATUS_WORD with no bits set, then with fan fault.
499b654c619SBrandon Wyman         PMBusExpectations expectations;
500b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
5013f1242f3SBrandon Wyman         psu2.analyze();
502b654c619SBrandon Wyman         expectations.statusWordValue = (status_word::FAN_FAULT);
5037ee4d7e4SBrandon Wyman         // STATUS_FANS_1_2 with fan 1 warning & fault bits on.
5047ee4d7e4SBrandon Wyman         expectations.statusFans12Value = 0xA0;
505b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
5063f1242f3SBrandon Wyman         psu2.analyze();
5073f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
5087ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
5093f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
5103f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
5113f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
51285c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
5136710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
514b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
5152cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
5167ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), true);
51796893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
5182916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
519*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
520*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
521*39ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
522b654c619SBrandon Wyman     }
5232916ea52SBrandon Wyman 
52406ca4590SBrandon Wyman     // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT.
5252cf46945SBrandon Wyman     {
5262916ea52SBrandon Wyman         // First STATUS_WORD with no bits set.
5272916ea52SBrandon Wyman         PMBusExpectations expectations;
5282916ea52SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
5292916ea52SBrandon Wyman         psu2.analyze();
5302916ea52SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), false);
5312916ea52SBrandon Wyman         // POWER_GOOD# inactive, and OFF bit on.
5322916ea52SBrandon Wyman         expectations.statusWordValue =
5332916ea52SBrandon Wyman             ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF));
53406ca4590SBrandon Wyman         for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
53506ca4590SBrandon Wyman         {
5362916ea52SBrandon Wyman             // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and
5372916ea52SBrandon Wyman             // STATUS_TEMPERATURE: Don't care if bits set or not (defaults).
5382916ea52SBrandon Wyman             setPMBusExpectations(mockPMBus, expectations);
5392916ea52SBrandon Wyman             psu2.analyze();
5402916ea52SBrandon Wyman             EXPECT_EQ(psu2.isPresent(), true);
54106ca4590SBrandon Wyman             if (x < DEGLITCH_LIMIT)
54206ca4590SBrandon Wyman             {
54306ca4590SBrandon Wyman                 EXPECT_EQ(psu2.isFaulted(), false);
54406ca4590SBrandon Wyman             }
54506ca4590SBrandon Wyman             else
54606ca4590SBrandon Wyman             {
5472916ea52SBrandon Wyman                 EXPECT_EQ(psu2.isFaulted(), true);
54806ca4590SBrandon Wyman             }
5492916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasInputFault(), false);
5502916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasMFRFault(), false);
5512916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasVINUVFault(), false);
5522916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasCommFault(), false);
5532916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasVoutOVFault(), false);
5542cf46945SBrandon Wyman             EXPECT_EQ(psu2.hasVoutUVFault(), false);
555b10b3be0SBrandon Wyman             EXPECT_EQ(psu2.hasIoutOCFault(), false);
5567ee4d7e4SBrandon Wyman             EXPECT_EQ(psu2.hasFanFault(), false);
5572916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasTempFault(), false);
55806ca4590SBrandon Wyman             if (x < DEGLITCH_LIMIT)
55906ca4590SBrandon Wyman             {
56006ca4590SBrandon Wyman                 EXPECT_EQ(psu2.hasPgoodFault(), false);
56106ca4590SBrandon Wyman             }
56206ca4590SBrandon Wyman             else
56306ca4590SBrandon Wyman             {
5642916ea52SBrandon Wyman                 EXPECT_EQ(psu2.hasPgoodFault(), true);
5652916ea52SBrandon Wyman             }
56606ca4590SBrandon Wyman         }
56706ca4590SBrandon Wyman     }
5682916ea52SBrandon Wyman 
5693f1242f3SBrandon Wyman     // TODO: ReadFailure
5703f1242f3SBrandon Wyman }
5713f1242f3SBrandon Wyman 
57259a35793SBrandon Wyman TEST_F(PowerSupplyTests, OnOffConfig)
57359a35793SBrandon Wyman {
57459a35793SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
57559a35793SBrandon Wyman     uint8_t data = 0x15;
57659a35793SBrandon Wyman 
57759a35793SBrandon Wyman     // Test where PSU is NOT present
57859a35793SBrandon Wyman     try
57959a35793SBrandon Wyman     {
580681b2a36SB. J. Wyman         // Assume GPIO presence, not inventory presence?
581681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
582681b2a36SB. J. Wyman 
5833ca062aeSAdriana Kobylak         MockedGPIOInterface* mockPresenceGPIO =
5843ca062aeSAdriana Kobylak             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
585681b2a36SB. J. Wyman         ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0));
58659a35793SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
587681b2a36SB. J. Wyman         // Constructor should set initial presence, default read returns 0.
58859a35793SBrandon Wyman         // If it is not present, I should not be trying to write to it.
58959a35793SBrandon Wyman         EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0);
59059a35793SBrandon Wyman         psu.onOffConfig(data);
59159a35793SBrandon Wyman     }
59259a35793SBrandon Wyman     catch (...)
5930c9a33d6SAdriana Kobylak     {}
59459a35793SBrandon Wyman 
59559a35793SBrandon Wyman     // Test where PSU is present
59659a35793SBrandon Wyman     try
59759a35793SBrandon Wyman     {
598681b2a36SB. J. Wyman         // Assume GPIO presence, not inventory presence?
599681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
6003ca062aeSAdriana Kobylak         MockedGPIOInterface* mockPresenceGPIO =
6013ca062aeSAdriana Kobylak             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
602681b2a36SB. J. Wyman         ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(1));
60359a35793SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
604681b2a36SB. J. Wyman         // TODO: expect setPresence call?
605681b2a36SB. J. Wyman         // updatePresence() private function reads gpio, called by analyze().
606681b2a36SB. J. Wyman         psu.analyze();
60759a35793SBrandon Wyman         // TODO: ???should I check the filename?
60859a35793SBrandon Wyman         EXPECT_CALL(mockPMBus,
60959a35793SBrandon Wyman                     writeBinary(_, ElementsAre(0x15), Type::HwmonDeviceDebug))
61059a35793SBrandon Wyman             .Times(1);
61159a35793SBrandon Wyman         psu.onOffConfig(data);
61259a35793SBrandon Wyman     }
61359a35793SBrandon Wyman     catch (...)
6140c9a33d6SAdriana Kobylak     {}
61559a35793SBrandon Wyman }
61659a35793SBrandon Wyman 
6173f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, ClearFaults)
6183f1242f3SBrandon Wyman {
6193f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
620681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, PSUGPIOLineName};
6213ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
6223ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
62306ca4590SBrandon Wyman     // Always return 1 to indicate present.
62406ca4590SBrandon Wyman     // Each analyze() call will trigger a read of the presence GPIO.
62506ca4590SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
626681b2a36SB. J. Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
62706ca4590SBrandon Wyman     // Change from missing to present will trigger HWMON directory update.
62806ca4590SBrandon Wyman     EXPECT_CALL(mockPMBus, findHwmonDir());
62906ca4590SBrandon Wyman     // Change from missing to present will trigger ON_OFF_CONFIG write.
63006ca4590SBrandon Wyman     EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, _, _));
6318da35c51SBrandon Wyman     // Presence change from missing to present will trigger in1_input read in
6328da35c51SBrandon Wyman     // an attempt to get CLEAR_FAULTS called.
6338da35c51SBrandon Wyman     EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(206000));
63406ca4590SBrandon Wyman     // Missing/present call will update Presence in inventory.
63506ca4590SBrandon Wyman     EXPECT_CALL(mockedUtil, setPresence(_, _, true, _));
6368da35c51SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
637b654c619SBrandon Wyman     PMBusExpectations expectations;
638b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
639681b2a36SB. J. Wyman     psu.analyze();
6403f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), true);
6413f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), false);
6423f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
6433f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
6443f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
64585c7bf41SBrandon Wyman     EXPECT_EQ(psu.hasCommFault(), false);
6466710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), false);
647b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), false);
6482cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
6497ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), false);
65096893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), false);
6512916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
652*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
653*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
654*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
655b654c619SBrandon Wyman 
656f07bc797SBrandon Wyman     // STATUS_WORD with fault bits galore!
657b654c619SBrandon Wyman     expectations.statusWordValue = 0xFFFF;
658f07bc797SBrandon Wyman     // STATUS_INPUT with fault bits on.
659b654c619SBrandon Wyman     expectations.statusInputValue = 0xFF;
660f07bc797SBrandon Wyman     // STATUS_MFR_SPEFIC with bits on.
661b654c619SBrandon Wyman     expectations.statusMFRValue = 0xFF;
66285c7bf41SBrandon Wyman     // STATUS_CML with bits on.
663b654c619SBrandon Wyman     expectations.statusCMLValue = 0xFF;
6646710ba2cSBrandon Wyman     // STATUS_VOUT with bits on.
665b654c619SBrandon Wyman     expectations.statusVOUTValue = 0xFF;
666b10b3be0SBrandon Wyman     // STATUS_IOUT with bits on.
667b10b3be0SBrandon Wyman     expectations.statusIOUTValue = 0xFF;
6687ee4d7e4SBrandon Wyman     // STATUS_FANS_1_2 with bits on.
6697ee4d7e4SBrandon Wyman     expectations.statusFans12Value = 0xFF;
67096893a46SBrandon Wyman     // STATUS_TEMPERATURE with bits on.
67196893a46SBrandon Wyman     expectations.statusTempValue = 0xFF;
672b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
6733f1242f3SBrandon Wyman     psu.analyze();
6743f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), true);
6753f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), true);
6763f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), true);
6773f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), true);
6783f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), true);
67985c7bf41SBrandon Wyman     EXPECT_EQ(psu.hasCommFault(), true);
6806710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), true);
681b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), true);
6822cf46945SBrandon Wyman     // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
6832cf46945SBrandon Wyman     // Rely on HasVoutUVFault() to verify this sets and clears.
6842cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
6857ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), true);
68696893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), true);
68706ca4590SBrandon Wyman     // pgoodFault is deglitched up to DEGLITCH_LIMIT
68806ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
68906ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
69006ca4590SBrandon Wyman     psu.analyze();
69106ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
69206ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
69306ca4590SBrandon Wyman     psu.analyze();
69406ca4590SBrandon Wyman     // DEGLITCH_LIMIT reached for pgoodFault
6952916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), true);
696*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), true);
697*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), true);
698*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), true);
6992cf46945SBrandon Wyman 
7003c208464SBrandon Wyman     EXPECT_CALL(mockPMBus, read("in1_input", _))
7013c208464SBrandon Wyman         .Times(1)
7023c208464SBrandon Wyman         .WillOnce(Return(209000));
7033f1242f3SBrandon Wyman     psu.clearFaults();
7043f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), true);
7053f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), false);
7063f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
7073f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
7083f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
70985c7bf41SBrandon Wyman     EXPECT_EQ(psu.hasCommFault(), false);
7106710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), false);
711b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), false);
7122cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
7137ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), false);
71496893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), false);
7152916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
716*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
717*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
718*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
719681b2a36SB. J. Wyman 
720681b2a36SB. J. Wyman     // TODO: Faults clear on missing/present?
7213f1242f3SBrandon Wyman }
7223f1242f3SBrandon Wyman 
7233f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory)
7243f1242f3SBrandon Wyman {
7253f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
7261d7a7df8SBrandon Wyman 
7271d7a7df8SBrandon Wyman     try
7281d7a7df8SBrandon Wyman     {
729681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
7301d7a7df8SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
7311d7a7df8SBrandon Wyman         // If it is not present, I should not be trying to read a string
7321d7a7df8SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(_, _)).Times(0);
7331d7a7df8SBrandon Wyman         psu.updateInventory();
7341d7a7df8SBrandon Wyman     }
7351d7a7df8SBrandon Wyman     catch (...)
7361d7a7df8SBrandon Wyman     {
7371d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have caught exception.";
7381d7a7df8SBrandon Wyman     }
7391d7a7df8SBrandon Wyman 
7401d7a7df8SBrandon Wyman     try
7411d7a7df8SBrandon Wyman     {
742681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, PSUGPIOLineName};
7433ca062aeSAdriana Kobylak         MockedGPIOInterface* mockPresenceGPIO =
7443ca062aeSAdriana Kobylak             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
745681b2a36SB. J. Wyman         // GPIO read return 1 to indicate present.
746681b2a36SB. J. Wyman         EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
747681b2a36SB. J. Wyman         psu.analyze();
7481d7a7df8SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
7491d7a7df8SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return(""));
7503f1242f3SBrandon Wyman         psu.updateInventory();
7511d7a7df8SBrandon Wyman 
7523c530fbdSBrandon Wyman #if IBM_VPD
7531d7a7df8SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(_, _))
7541d7a7df8SBrandon Wyman             .WillOnce(Return("CCIN"))
7551d7a7df8SBrandon Wyman             .WillOnce(Return("PN3456"))
7561d7a7df8SBrandon Wyman             .WillOnce(Return("FN3456"))
7571d7a7df8SBrandon Wyman             .WillOnce(Return("HEADER"))
7581d7a7df8SBrandon Wyman             .WillOnce(Return("SN3456"))
7591d7a7df8SBrandon Wyman             .WillOnce(Return("FW3456"));
7603c530fbdSBrandon Wyman #endif
7611d7a7df8SBrandon Wyman         psu.updateInventory();
7621d7a7df8SBrandon Wyman         // TODO: D-Bus mocking to verify values stored on D-Bus (???)
7631d7a7df8SBrandon Wyman     }
7641d7a7df8SBrandon Wyman     catch (...)
7651d7a7df8SBrandon Wyman     {
7661d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have caught exception.";
7671d7a7df8SBrandon Wyman     }
7683f1242f3SBrandon Wyman }
7693f1242f3SBrandon Wyman 
7703f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent)
7713f1242f3SBrandon Wyman {
7723f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
773681b2a36SB. J. Wyman 
774681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
7753ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
7763ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
7773f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), false);
7783f1242f3SBrandon Wyman 
779681b2a36SB. J. Wyman     // Change GPIO read to return 1 to indicate present.
780681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
781681b2a36SB. J. Wyman     psu.analyze();
782681b2a36SB. J. Wyman     EXPECT_EQ(psu.isPresent(), true);
7833f1242f3SBrandon Wyman }
7843f1242f3SBrandon Wyman 
7853f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted)
7863f1242f3SBrandon Wyman {
7873f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
788681b2a36SB. J. Wyman 
789681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, PSUGPIOLineName};
7903ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
7913ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
792681b2a36SB. J. Wyman     // Always return 1 to indicate present.
793681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
794681b2a36SB. J. Wyman     psu.analyze();
7953f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), false);
7963f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
797b654c619SBrandon Wyman     PMBusExpectations expectations;
798f07bc797SBrandon Wyman     // STATUS_WORD with fault bits on.
799b654c619SBrandon Wyman     expectations.statusWordValue = 0xFFFF;
800f07bc797SBrandon Wyman     // STATUS_INPUT with fault bits on.
801b654c619SBrandon Wyman     expectations.statusInputValue = 0xFF;
802f07bc797SBrandon Wyman     // STATUS_MFR_SPECIFIC with faults bits on.
803b654c619SBrandon Wyman     expectations.statusMFRValue = 0xFF;
80485c7bf41SBrandon Wyman     // STATUS_CML with faults bits on.
805b654c619SBrandon Wyman     expectations.statusCMLValue = 0xFF;
8066710ba2cSBrandon Wyman     // STATUS_VOUT with fault bits on.
807b654c619SBrandon Wyman     expectations.statusVOUTValue = 0xFF;
808b10b3be0SBrandon Wyman     // STATUS_IOUT with fault bits on.
809b10b3be0SBrandon Wyman     expectations.statusIOUTValue = 0xFF;
8107ee4d7e4SBrandon Wyman     // STATUS_FANS_1_2 with bits on.
8117ee4d7e4SBrandon Wyman     expectations.statusFans12Value = 0xFF;
81296893a46SBrandon Wyman     // STATUS_TEMPERATURE with fault bits on.
81396893a46SBrandon Wyman     expectations.statusTempValue = 0xFF;
814b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
8153f1242f3SBrandon Wyman     psu.analyze();
8163f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), true);
8173f1242f3SBrandon Wyman }
8183f1242f3SBrandon Wyman 
8193f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasInputFault)
8203f1242f3SBrandon Wyman {
8213f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
822681b2a36SB. J. Wyman 
823681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
8243ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
8253ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
826681b2a36SB. J. Wyman     // Always return 1 to indicate present.
827681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
828681b2a36SB. J. Wyman     psu.analyze();
8293f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
8303f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
8318da35c51SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
832b654c619SBrandon Wyman     PMBusExpectations expectations;
833b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
8343f1242f3SBrandon Wyman     psu.analyze();
8353f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
836f07bc797SBrandon Wyman     // STATUS_WORD with input fault/warn on.
837b654c619SBrandon Wyman     expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
838f07bc797SBrandon Wyman     // STATUS_INPUT with an input fault bit on.
839b654c619SBrandon Wyman     expectations.statusInputValue = 0x80;
840b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
8413f1242f3SBrandon Wyman     psu.analyze();
8423f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), true);
843f07bc797SBrandon Wyman     // STATUS_WORD with no bits on.
844b654c619SBrandon Wyman     expectations.statusWordValue = 0;
845b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
8463f1242f3SBrandon Wyman     psu.analyze();
8473f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
8483f1242f3SBrandon Wyman }
8493f1242f3SBrandon Wyman 
8503f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault)
8513f1242f3SBrandon Wyman {
8523f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
853681b2a36SB. J. Wyman 
854681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
8553ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
8563ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
857681b2a36SB. J. Wyman     // Always return 1 to indicate present.
858681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
859681b2a36SB. J. Wyman     psu.analyze();
8603f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
8613f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
862f07bc797SBrandon Wyman     // First return STATUS_WORD with no bits on.
8638da35c51SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
864b654c619SBrandon Wyman     PMBusExpectations expectations;
865b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
8663f1242f3SBrandon Wyman     psu.analyze();
8673f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
868f07bc797SBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
869b654c619SBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
870f07bc797SBrandon Wyman     // STATUS_MFR_SPEFIC with bit(s) on.
871b654c619SBrandon Wyman     expectations.statusMFRValue = 0xFF;
872b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
8733f1242f3SBrandon Wyman     psu.analyze();
8743f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), true);
875f07bc797SBrandon Wyman     // Back to no bits on in STATUS_WORD
876b654c619SBrandon Wyman     expectations.statusWordValue = 0;
877b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
8783f1242f3SBrandon Wyman     psu.analyze();
8793f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
8803f1242f3SBrandon Wyman }
8813f1242f3SBrandon Wyman 
8823f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault)
8833f1242f3SBrandon Wyman {
8843f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
885681b2a36SB. J. Wyman 
886681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
8873ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
8883ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
889681b2a36SB. J. Wyman     // Always return 1 to indicate present.
890681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
891681b2a36SB. J. Wyman     psu.analyze();
8923f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
8933f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
8948da35c51SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
895b654c619SBrandon Wyman     PMBusExpectations expectations;
896b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
8973f1242f3SBrandon Wyman     psu.analyze();
8983f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
899f07bc797SBrandon Wyman     // Turn fault on.
900b654c619SBrandon Wyman     expectations.statusWordValue = (status_word::VIN_UV_FAULT);
90185c7bf41SBrandon Wyman     // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by
90285c7bf41SBrandon Wyman     // Figure 16, and assume bits on in STATUS_INPUT.
903b654c619SBrandon Wyman     expectations.statusInputValue = 0x18;
904b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
9053f1242f3SBrandon Wyman     psu.analyze();
9063f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), true);
907f07bc797SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
908b654c619SBrandon Wyman     expectations.statusWordValue = 0;
909b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
9103f1242f3SBrandon Wyman     psu.analyze();
9113f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
9123f1242f3SBrandon Wyman }
9136710ba2cSBrandon Wyman 
9146710ba2cSBrandon Wyman TEST_F(PowerSupplyTests, HasVoutOVFault)
9156710ba2cSBrandon Wyman {
9166710ba2cSBrandon Wyman     auto bus = sdbusplus::bus::new_default();
9176710ba2cSBrandon Wyman 
9186710ba2cSBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x69, PSUGPIOLineName};
9196710ba2cSBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
9206710ba2cSBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
9216710ba2cSBrandon Wyman     // Always return 1 to indicate present.
9226710ba2cSBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
9236710ba2cSBrandon Wyman     psu.analyze();
9246710ba2cSBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
9256710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), false);
9266710ba2cSBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
927b654c619SBrandon Wyman     PMBusExpectations expectations;
928b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
9296710ba2cSBrandon Wyman     psu.analyze();
9306710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), false);
9316710ba2cSBrandon Wyman     // Turn fault on.
932b654c619SBrandon Wyman     expectations.statusWordValue = (status_word::VOUT_OV_FAULT);
9336710ba2cSBrandon Wyman     // STATUS_VOUT fault bit(s)
934b654c619SBrandon Wyman     expectations.statusVOUTValue = 0x80;
93596893a46SBrandon Wyman     // STATUS_TEMPERATURE default.
936b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
9376710ba2cSBrandon Wyman     psu.analyze();
9386710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), true);
9396710ba2cSBrandon Wyman     // Back to no fault bits on in STATUS_WORD
940b654c619SBrandon Wyman     expectations.statusWordValue = 0;
941b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
9426710ba2cSBrandon Wyman     psu.analyze();
9436710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), false);
9446710ba2cSBrandon Wyman }
94596893a46SBrandon Wyman 
946b10b3be0SBrandon Wyman TEST_F(PowerSupplyTests, HasIoutOCFault)
947b10b3be0SBrandon Wyman {
948b10b3be0SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
949b10b3be0SBrandon Wyman 
950b10b3be0SBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName};
951b10b3be0SBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
952b10b3be0SBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
953b10b3be0SBrandon Wyman     // Always return 1 to indicate present.
954b10b3be0SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
955b10b3be0SBrandon Wyman     psu.analyze();
956b10b3be0SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
957b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), false);
958b10b3be0SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
959b10b3be0SBrandon Wyman     PMBusExpectations expectations;
960b10b3be0SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
961b10b3be0SBrandon Wyman     psu.analyze();
962b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), false);
963b10b3be0SBrandon Wyman     // Turn fault on.
964b10b3be0SBrandon Wyman     expectations.statusWordValue = status_word::IOUT_OC_FAULT;
965b10b3be0SBrandon Wyman     // STATUS_IOUT fault bit(s)
966b10b3be0SBrandon Wyman     expectations.statusIOUTValue = 0x88;
967b10b3be0SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
968b10b3be0SBrandon Wyman     psu.analyze();
969b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), true);
970b10b3be0SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
971b10b3be0SBrandon Wyman     expectations.statusWordValue = 0;
972b10b3be0SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
973b10b3be0SBrandon Wyman     psu.analyze();
974b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), false);
975b10b3be0SBrandon Wyman }
976b10b3be0SBrandon Wyman 
9772cf46945SBrandon Wyman TEST_F(PowerSupplyTests, HasVoutUVFault)
9782cf46945SBrandon Wyman {
9792cf46945SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
9802cf46945SBrandon Wyman 
9812cf46945SBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName};
9822cf46945SBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
9832cf46945SBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
9842cf46945SBrandon Wyman     // Always return 1 to indicate present.
9852cf46945SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
9862cf46945SBrandon Wyman     psu.analyze();
9872cf46945SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
9882cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
9892cf46945SBrandon Wyman     PMBusExpectations expectations;
9902cf46945SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
9912cf46945SBrandon Wyman     psu.analyze();
9922cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
9932cf46945SBrandon Wyman     // Turn fault on.
9942cf46945SBrandon Wyman     expectations.statusWordValue = (status_word::VOUT_FAULT);
9952cf46945SBrandon Wyman     // STATUS_VOUT fault bit(s)
9962cf46945SBrandon Wyman     expectations.statusVOUTValue = 0x30;
9972cf46945SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
9982cf46945SBrandon Wyman     psu.analyze();
9992cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), true);
10002cf46945SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
10012cf46945SBrandon Wyman     expectations.statusWordValue = 0;
10022cf46945SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
10032cf46945SBrandon Wyman     psu.analyze();
10042cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
10052cf46945SBrandon Wyman }
10062cf46945SBrandon Wyman 
10077ee4d7e4SBrandon Wyman TEST_F(PowerSupplyTests, HasFanFault)
10087ee4d7e4SBrandon Wyman {
10097ee4d7e4SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
10107ee4d7e4SBrandon Wyman 
10117ee4d7e4SBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName};
10127ee4d7e4SBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
10137ee4d7e4SBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
10147ee4d7e4SBrandon Wyman     // Always return 1 to indicate present.
10157ee4d7e4SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
10167ee4d7e4SBrandon Wyman     psu.analyze();
10177ee4d7e4SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
10187ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), false);
10197ee4d7e4SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
10207ee4d7e4SBrandon Wyman     PMBusExpectations expectations;
10217ee4d7e4SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
10227ee4d7e4SBrandon Wyman     psu.analyze();
10237ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), false);
10247ee4d7e4SBrandon Wyman     // Turn fault on.
10257ee4d7e4SBrandon Wyman     expectations.statusWordValue = (status_word::FAN_FAULT);
10267ee4d7e4SBrandon Wyman     // STATUS_FANS_1_2 fault bit on (Fan 1 Fault)
10277ee4d7e4SBrandon Wyman     expectations.statusFans12Value = 0x80;
10287ee4d7e4SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
10297ee4d7e4SBrandon Wyman     psu.analyze();
10307ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), true);
10317ee4d7e4SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
10327ee4d7e4SBrandon Wyman     expectations.statusWordValue = 0;
10337ee4d7e4SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
10347ee4d7e4SBrandon Wyman     psu.analyze();
10357ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), false);
10367ee4d7e4SBrandon Wyman }
10377ee4d7e4SBrandon Wyman 
103896893a46SBrandon Wyman TEST_F(PowerSupplyTests, HasTempFault)
103996893a46SBrandon Wyman {
104096893a46SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
104196893a46SBrandon Wyman 
104296893a46SBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName};
104396893a46SBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
104496893a46SBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
104596893a46SBrandon Wyman     // Always return 1 to indicate present.
104696893a46SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
104796893a46SBrandon Wyman     psu.analyze();
104896893a46SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
104996893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), false);
105096893a46SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
105196893a46SBrandon Wyman     PMBusExpectations expectations;
105296893a46SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
105396893a46SBrandon Wyman     psu.analyze();
105496893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), false);
105596893a46SBrandon Wyman     // Turn fault on.
105696893a46SBrandon Wyman     expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
105796893a46SBrandon Wyman     // STATUS_TEMPERATURE fault bit on (OT Fault)
105896893a46SBrandon Wyman     expectations.statusTempValue = 0x80;
105996893a46SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
106096893a46SBrandon Wyman     psu.analyze();
106196893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), true);
106296893a46SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
106396893a46SBrandon Wyman     expectations.statusWordValue = 0;
106496893a46SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
106596893a46SBrandon Wyman     psu.analyze();
106696893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), false);
106796893a46SBrandon Wyman }
10682916ea52SBrandon Wyman 
10692916ea52SBrandon Wyman TEST_F(PowerSupplyTests, HasPgoodFault)
10702916ea52SBrandon Wyman {
10712916ea52SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
10722916ea52SBrandon Wyman 
10732916ea52SBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6b, PSUGPIOLineName};
10742916ea52SBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
10752916ea52SBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
10762916ea52SBrandon Wyman     // Always return 1 to indicate present.
10772916ea52SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
10782916ea52SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
107906ca4590SBrandon Wyman     EXPECT_CALL(mockPMBus, findHwmonDir());
108006ca4590SBrandon Wyman     // Presence change from missing to present will trigger write to
108106ca4590SBrandon Wyman     // ON_OFF_CONFIG.
108206ca4590SBrandon Wyman     EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, _, _));
108306ca4590SBrandon Wyman     // Missing/present will trigger read of "in1_input" to try CLEAR_FAULTS.
108406ca4590SBrandon Wyman     EXPECT_CALL(mockPMBus, read("in1_input", _))
108506ca4590SBrandon Wyman         .Times(1)
108606ca4590SBrandon Wyman         .WillOnce(Return(207000));
108706ca4590SBrandon Wyman     // Missing/present call will update Presence in inventory.
108806ca4590SBrandon Wyman     EXPECT_CALL(mockedUtil, setPresence(_, _, true, _));
10892916ea52SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
10902916ea52SBrandon Wyman     PMBusExpectations expectations;
10912916ea52SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
10922916ea52SBrandon Wyman     psu.analyze();
10932916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
10942916ea52SBrandon Wyman     // Turn PGOOD# off (fault on).
10952916ea52SBrandon Wyman     expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED);
10962916ea52SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
10972916ea52SBrandon Wyman     psu.analyze();
109806ca4590SBrandon Wyman     // Expect false until reaches DEGLITCH_LIMIT
109906ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
110006ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
110106ca4590SBrandon Wyman     psu.analyze();
110206ca4590SBrandon Wyman     // Expect false until reaches DEGLITCH_LIMIT
110306ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
110406ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
110506ca4590SBrandon Wyman     psu.analyze();
110606ca4590SBrandon Wyman     // DEGLITCH_LIMIT reached, expect true.
11072916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), true);
11082916ea52SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
11092916ea52SBrandon Wyman     expectations.statusWordValue = 0;
11102916ea52SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
11112916ea52SBrandon Wyman     psu.analyze();
11122916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
11132916ea52SBrandon Wyman     // Turn OFF bit on
11142916ea52SBrandon Wyman     expectations.statusWordValue = (status_word::UNIT_IS_OFF);
11152916ea52SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
11162916ea52SBrandon Wyman     psu.analyze();
111706ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
111806ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
111906ca4590SBrandon Wyman     psu.analyze();
112006ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
112106ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
112206ca4590SBrandon Wyman     psu.analyze();
11232916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), true);
11242916ea52SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
11252916ea52SBrandon Wyman     expectations.statusWordValue = 0;
11262916ea52SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
11272916ea52SBrandon Wyman     psu.analyze();
11282916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
11292916ea52SBrandon Wyman }
1130*39ea02bcSBrandon Wyman 
1131*39ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSKillFault)
1132*39ea02bcSBrandon Wyman {
1133*39ea02bcSBrandon Wyman     auto bus = sdbusplus::bus::new_default();
1134*39ea02bcSBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 4, 0x6d, PSUGPIOLineName};
1135*39ea02bcSBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
1136*39ea02bcSBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1137*39ea02bcSBrandon Wyman     // Always return 1 to indicate present.
1138*39ea02bcSBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1139*39ea02bcSBrandon Wyman     psu.analyze();
1140*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
1141*39ea02bcSBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1142*39ea02bcSBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
1143*39ea02bcSBrandon Wyman     PMBusExpectations expectations;
1144*39ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1145*39ea02bcSBrandon Wyman     psu.analyze();
1146*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
1147*39ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
1148*39ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1149*39ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit(s) on.
1150*39ea02bcSBrandon Wyman     expectations.statusMFRValue = 0xFF;
1151*39ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1152*39ea02bcSBrandon Wyman     psu.analyze();
1153*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), true);
1154*39ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
1155*39ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
1156*39ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1157*39ea02bcSBrandon Wyman     psu.analyze();
1158*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
1159*39ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
1160*39ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1161*39ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit 4 on.
1162*39ea02bcSBrandon Wyman     expectations.statusMFRValue = 0x10;
1163*39ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1164*39ea02bcSBrandon Wyman     psu.analyze();
1165*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), true);
1166*39ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
1167*39ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
1168*39ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1169*39ea02bcSBrandon Wyman     psu.analyze();
1170*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
1171*39ea02bcSBrandon Wyman }
1172*39ea02bcSBrandon Wyman 
1173*39ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPS12VcsFault)
1174*39ea02bcSBrandon Wyman {
1175*39ea02bcSBrandon Wyman     auto bus = sdbusplus::bus::new_default();
1176*39ea02bcSBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 5, 0x6e, PSUGPIOLineName};
1177*39ea02bcSBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
1178*39ea02bcSBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1179*39ea02bcSBrandon Wyman     // Always return 1 to indicate present.
1180*39ea02bcSBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1181*39ea02bcSBrandon Wyman     psu.analyze();
1182*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
1183*39ea02bcSBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1184*39ea02bcSBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
1185*39ea02bcSBrandon Wyman     PMBusExpectations expectations;
1186*39ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1187*39ea02bcSBrandon Wyman     psu.analyze();
1188*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
1189*39ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
1190*39ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1191*39ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit(s) on.
1192*39ea02bcSBrandon Wyman     expectations.statusMFRValue = 0xFF;
1193*39ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1194*39ea02bcSBrandon Wyman     psu.analyze();
1195*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), true);
1196*39ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
1197*39ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
1198*39ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1199*39ea02bcSBrandon Wyman     psu.analyze();
1200*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
1201*39ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
1202*39ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1203*39ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit 6 on.
1204*39ea02bcSBrandon Wyman     expectations.statusMFRValue = 0x40;
1205*39ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1206*39ea02bcSBrandon Wyman     psu.analyze();
1207*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), true);
1208*39ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
1209*39ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
1210*39ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1211*39ea02bcSBrandon Wyman     psu.analyze();
1212*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
1213*39ea02bcSBrandon Wyman }
1214*39ea02bcSBrandon Wyman 
1215*39ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSCS12VFault)
1216*39ea02bcSBrandon Wyman {
1217*39ea02bcSBrandon Wyman     auto bus = sdbusplus::bus::new_default();
1218*39ea02bcSBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f, PSUGPIOLineName};
1219*39ea02bcSBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
1220*39ea02bcSBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1221*39ea02bcSBrandon Wyman     // Always return 1 to indicate present.
1222*39ea02bcSBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1223*39ea02bcSBrandon Wyman     psu.analyze();
1224*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
1225*39ea02bcSBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1226*39ea02bcSBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
1227*39ea02bcSBrandon Wyman     PMBusExpectations expectations;
1228*39ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1229*39ea02bcSBrandon Wyman     psu.analyze();
1230*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
1231*39ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
1232*39ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1233*39ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit(s) on.
1234*39ea02bcSBrandon Wyman     expectations.statusMFRValue = 0xFF;
1235*39ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1236*39ea02bcSBrandon Wyman     psu.analyze();
1237*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), true);
1238*39ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
1239*39ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
1240*39ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1241*39ea02bcSBrandon Wyman     psu.analyze();
1242*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
1243*39ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
1244*39ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1245*39ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit 7 on.
1246*39ea02bcSBrandon Wyman     expectations.statusMFRValue = 0x80;
1247*39ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1248*39ea02bcSBrandon Wyman     psu.analyze();
1249*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), true);
1250*39ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
1251*39ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
1252*39ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1253*39ea02bcSBrandon Wyman     psu.analyze();
1254*39ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
1255*39ea02bcSBrandon Wyman }
1256