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 
95*391a0690SBrandon Wyman // Helper function for when a power supply goes from missing to present.
96*391a0690SBrandon Wyman void setMissingToPresentExpects(MockedPMBus& pmbus, const MockedUtil& util)
97*391a0690SBrandon Wyman {
98*391a0690SBrandon Wyman     // Call to analyze() will update to present, that will trigger updating
99*391a0690SBrandon Wyman     // to the correct/latest HWMON directory, in case it changes.
100*391a0690SBrandon Wyman     EXPECT_CALL(pmbus, findHwmonDir());
101*391a0690SBrandon Wyman     // Presence change from missing to present will trigger write to
102*391a0690SBrandon Wyman     // ON_OFF_CONFIG.
103*391a0690SBrandon Wyman     EXPECT_CALL(pmbus, writeBinary(ON_OFF_CONFIG, _, _));
104*391a0690SBrandon Wyman     // Presence change from missing to present will trigger in1_input read
105*391a0690SBrandon Wyman     // in an attempt to get CLEAR_FAULTS called.
106*391a0690SBrandon Wyman     EXPECT_CALL(pmbus, read(READ_VIN, _)).Times(1).WillOnce(Return(1));
107*391a0690SBrandon Wyman     // Missing/present call will update Presence in inventory.
108*391a0690SBrandon Wyman     // EXPECT_CALL(mockedUtil, setPresence(_, _, true, _));
109*391a0690SBrandon Wyman     EXPECT_CALL(util, setPresence(_, _, true, _));
110*391a0690SBrandon Wyman }
111*391a0690SBrandon Wyman 
1123f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Constructor)
1133f1242f3SBrandon Wyman {
1143f1242f3SBrandon Wyman     /**
1153f1242f3SBrandon Wyman      * @param[in] invpath - String for inventory path to use
1163f1242f3SBrandon Wyman      * @param[in] i2cbus - The bus number this power supply is on
1173f1242f3SBrandon Wyman      * @param[in] i2caddr - The 16-bit I2C address of the power supply
118681b2a36SB. J. Wyman      * @param[in] gpioLineName - The string for the gpio-line-name to read for
119681b2a36SB. J. Wyman      * presence.
120681b2a36SB. J. Wyman      * @param[in] bindDelay - Time in milliseconds to delay binding the device
121681b2a36SB. J. Wyman      * driver after seeing the presence line go active.
1223f1242f3SBrandon Wyman      */
1233f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
1241d7a7df8SBrandon Wyman 
1251d7a7df8SBrandon Wyman     // Try where inventory path is empty, constructor should fail.
1261d7a7df8SBrandon Wyman     try
1271d7a7df8SBrandon Wyman     {
128681b2a36SB. J. Wyman         auto psu =
129681b2a36SB. J. Wyman             std::make_unique<PowerSupply>(bus, "", 3, 0x68, PSUGPIOLineName);
1301d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have reached this line.";
1311d7a7df8SBrandon Wyman     }
1321d7a7df8SBrandon Wyman     catch (const std::invalid_argument& e)
1331d7a7df8SBrandon Wyman     {
1341d7a7df8SBrandon Wyman         EXPECT_STREQ(e.what(), "Invalid empty inventoryPath");
1351d7a7df8SBrandon Wyman     }
1361d7a7df8SBrandon Wyman     catch (...)
1371d7a7df8SBrandon Wyman     {
1381d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have caught exception.";
1391d7a7df8SBrandon Wyman     }
1401d7a7df8SBrandon Wyman 
141681b2a36SB. J. Wyman     // TODO: Try invalid i2c address?
142681b2a36SB. J. Wyman 
143681b2a36SB. J. Wyman     // Try where gpioLineName is empty.
1441d7a7df8SBrandon Wyman     try
1451d7a7df8SBrandon Wyman     {
1461d7a7df8SBrandon Wyman         auto psu =
147681b2a36SB. J. Wyman             std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, "");
148681b2a36SB. J. Wyman         ADD_FAILURE()
149681b2a36SB. J. Wyman             << "Should not have reached this line. Invalid gpioLineName.";
150681b2a36SB. J. Wyman     }
151681b2a36SB. J. Wyman     catch (const std::invalid_argument& e)
152681b2a36SB. J. Wyman     {
153681b2a36SB. J. Wyman         EXPECT_STREQ(e.what(), "Invalid empty gpioLineName");
154681b2a36SB. J. Wyman     }
155681b2a36SB. J. Wyman     catch (...)
156681b2a36SB. J. Wyman     {
157681b2a36SB. J. Wyman         ADD_FAILURE() << "Should not have caught exception.";
158681b2a36SB. J. Wyman     }
159681b2a36SB. J. Wyman 
160681b2a36SB. J. Wyman     // Test with valid arguments
161681b2a36SB. J. Wyman     // NOT using D-Bus inventory path for presence.
162681b2a36SB. J. Wyman     try
163681b2a36SB. J. Wyman     {
164681b2a36SB. J. Wyman         auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68,
165681b2a36SB. J. Wyman                                                  PSUGPIOLineName);
1663f1242f3SBrandon Wyman 
1673f1242f3SBrandon Wyman         EXPECT_EQ(psu->isPresent(), false);
1683f1242f3SBrandon Wyman         EXPECT_EQ(psu->isFaulted(), false);
1698da35c51SBrandon Wyman         EXPECT_EQ(psu->hasCommFault(), false);
1703f1242f3SBrandon Wyman         EXPECT_EQ(psu->hasInputFault(), false);
1713f1242f3SBrandon Wyman         EXPECT_EQ(psu->hasMFRFault(), false);
1723f1242f3SBrandon Wyman         EXPECT_EQ(psu->hasVINUVFault(), false);
1736710ba2cSBrandon Wyman         EXPECT_EQ(psu->hasVoutOVFault(), false);
174b10b3be0SBrandon Wyman         EXPECT_EQ(psu->hasIoutOCFault(), false);
1752cf46945SBrandon Wyman         EXPECT_EQ(psu->hasVoutUVFault(), false);
1767ee4d7e4SBrandon Wyman         EXPECT_EQ(psu->hasFanFault(), false);
17796893a46SBrandon Wyman         EXPECT_EQ(psu->hasTempFault(), false);
1782916ea52SBrandon Wyman         EXPECT_EQ(psu->hasPgoodFault(), false);
17939ea02bcSBrandon Wyman         EXPECT_EQ(psu->hasPSKillFault(), false);
18039ea02bcSBrandon Wyman         EXPECT_EQ(psu->hasPS12VcsFault(), false);
18139ea02bcSBrandon Wyman         EXPECT_EQ(psu->hasPSCS12VFault(), false);
1823f1242f3SBrandon Wyman     }
1831d7a7df8SBrandon Wyman     catch (...)
1841d7a7df8SBrandon Wyman     {
1851d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have caught exception.";
1861d7a7df8SBrandon Wyman     }
187681b2a36SB. J. Wyman 
188681b2a36SB. J. Wyman     // Test with valid arguments
189681b2a36SB. J. Wyman     // TODO: Using D-Bus inventory path for presence.
190681b2a36SB. J. Wyman     try
191681b2a36SB. J. Wyman     {
192681b2a36SB. J. Wyman         // FIXME: How do I get that presenceGPIO.read() in the startup to throw
193681b2a36SB. J. Wyman         // an exception?
194681b2a36SB. J. Wyman 
195681b2a36SB. J. Wyman         // EXPECT_CALL(mockedUtil, getPresence(_,
196681b2a36SB. J. Wyman         // StrEq(PSUInventoryPath)))
197681b2a36SB. J. Wyman         //    .Times(1);
198681b2a36SB. J. Wyman     }
199681b2a36SB. J. Wyman     catch (...)
200681b2a36SB. J. Wyman     {
201681b2a36SB. J. Wyman         ADD_FAILURE() << "Should not have caught exception.";
202681b2a36SB. J. Wyman     }
2031d7a7df8SBrandon Wyman }
2043f1242f3SBrandon Wyman 
2053f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Analyze)
2063f1242f3SBrandon Wyman {
2073f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
2083f1242f3SBrandon Wyman 
209b654c619SBrandon Wyman     {
210681b2a36SB. J. Wyman         // If I default to reading the GPIO, I will NOT expect a call to
211681b2a36SB. J. Wyman         // getPresence().
212681b2a36SB. J. Wyman 
213681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
2143ca062aeSAdriana Kobylak         MockedGPIOInterface* mockPresenceGPIO =
2153ca062aeSAdriana Kobylak             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
216681b2a36SB. J. Wyman         EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0));
217681b2a36SB. J. Wyman 
2183f1242f3SBrandon Wyman         psu.analyze();
2193f1242f3SBrandon Wyman         // By default, nothing should change.
2203f1242f3SBrandon Wyman         EXPECT_EQ(psu.isPresent(), false);
2213f1242f3SBrandon Wyman         EXPECT_EQ(psu.isFaulted(), false);
2223f1242f3SBrandon Wyman         EXPECT_EQ(psu.hasInputFault(), false);
2233f1242f3SBrandon Wyman         EXPECT_EQ(psu.hasMFRFault(), false);
2243f1242f3SBrandon Wyman         EXPECT_EQ(psu.hasVINUVFault(), false);
22585c7bf41SBrandon Wyman         EXPECT_EQ(psu.hasCommFault(), false);
2266710ba2cSBrandon Wyman         EXPECT_EQ(psu.hasVoutOVFault(), false);
227b10b3be0SBrandon Wyman         EXPECT_EQ(psu.hasIoutOCFault(), false);
2282cf46945SBrandon Wyman         EXPECT_EQ(psu.hasVoutUVFault(), false);
2297ee4d7e4SBrandon Wyman         EXPECT_EQ(psu.hasFanFault(), false);
23096893a46SBrandon Wyman         EXPECT_EQ(psu.hasTempFault(), false);
2312916ea52SBrandon Wyman         EXPECT_EQ(psu.hasPgoodFault(), false);
23239ea02bcSBrandon Wyman         EXPECT_EQ(psu.hasPSKillFault(), false);
23339ea02bcSBrandon Wyman         EXPECT_EQ(psu.hasPS12VcsFault(), false);
23439ea02bcSBrandon Wyman         EXPECT_EQ(psu.hasPSCS12VFault(), false);
235b654c619SBrandon Wyman     }
2363f1242f3SBrandon Wyman 
237681b2a36SB. J. Wyman     PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
238681b2a36SB. J. Wyman     // In order to get the various faults tested, the power supply needs to
239681b2a36SB. J. Wyman     // be present in order to read from the PMBus device(s).
2403ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO2 =
2413ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO());
24206ca4590SBrandon Wyman     // Always return 1 to indicate present.
24306ca4590SBrandon Wyman     // Each analyze() call will trigger a read of the presence GPIO.
24406ca4590SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO2, read()).WillRepeatedly(Return(1));
245681b2a36SB. J. Wyman     EXPECT_EQ(psu2.isPresent(), false);
2463f1242f3SBrandon Wyman 
2473f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus());
248*391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
249b654c619SBrandon Wyman 
250b654c619SBrandon Wyman     // STATUS_WORD INPUT fault.
251b654c619SBrandon Wyman     {
252b654c619SBrandon Wyman         // Start with STATUS_WORD 0x0000. Powered on, no faults.
253b654c619SBrandon Wyman         // Set expectations for a no fault
254b654c619SBrandon Wyman         PMBusExpectations expectations;
255b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
2563f1242f3SBrandon Wyman         psu2.analyze();
2573f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
2583f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), false);
2593f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
2603f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
2613f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
26285c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
2636710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
264b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
2652cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
2667ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
26796893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
2682916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
26939ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
27039ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
27139ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
2723f1242f3SBrandon Wyman 
273b654c619SBrandon Wyman         // Update expectations for STATUS_WORD input fault/warn
27496893a46SBrandon Wyman         // STATUS_INPUT fault bits ... on.
275b654c619SBrandon Wyman         expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
276b654c619SBrandon Wyman         expectations.statusInputValue = 0x38;
277b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
2783f1242f3SBrandon Wyman         psu2.analyze();
2793f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
2803f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
2813f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), true);
2823f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
2833f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
28485c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
2856710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
286b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
2872cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
2887ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
28996893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
2902916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
29139ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
29239ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
29339ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
294b654c619SBrandon Wyman     }
2953f1242f3SBrandon Wyman 
2963f1242f3SBrandon Wyman     // STATUS_WORD INPUT/UV fault.
297b654c619SBrandon Wyman     {
2983f1242f3SBrandon Wyman         // First need it to return good status, then the fault
299b654c619SBrandon Wyman         PMBusExpectations expectations;
300b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
3013f1242f3SBrandon Wyman         psu2.analyze();
3028da35c51SBrandon Wyman         // Now set fault bits in STATUS_WORD
303b654c619SBrandon Wyman         expectations.statusWordValue =
3048da35c51SBrandon Wyman             (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT);
3058da35c51SBrandon Wyman         // STATUS_INPUT fault bits ... on.
306b654c619SBrandon Wyman         expectations.statusInputValue = 0x38;
307b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
3083f1242f3SBrandon Wyman         psu2.analyze();
3093f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
3103f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
311f07bc797SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), true);
3123f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
3133f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), true);
31485c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
3156710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
316b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
3172cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
3187ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
31996893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
3202916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
32139ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
32239ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
32339ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
324b654c619SBrandon Wyman     }
3253f1242f3SBrandon Wyman 
3263f1242f3SBrandon Wyman     // STATUS_WORD MFR fault.
327b654c619SBrandon Wyman     {
328f07bc797SBrandon Wyman         // First need it to return good status, then the fault
329b654c619SBrandon Wyman         PMBusExpectations expectations;
330b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
3313f1242f3SBrandon Wyman         psu2.analyze();
3328da35c51SBrandon Wyman         // Now STATUS_WORD with MFR fault bit on.
333b654c619SBrandon Wyman         expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
3348da35c51SBrandon Wyman         // STATUS_MFR bits on.
335b654c619SBrandon Wyman         expectations.statusMFRValue = 0xFF;
336b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
3373f1242f3SBrandon Wyman         psu2.analyze();
3383f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
3393f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
3403f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
3413f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), true);
3423f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
34385c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
3446710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
345b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
3462cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
3477ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
34896893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
3492916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
35039ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), true);
35139ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), true);
35239ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), true);
353b654c619SBrandon Wyman     }
3543f1242f3SBrandon Wyman 
35596893a46SBrandon Wyman     // Temperature fault.
356b654c619SBrandon Wyman     {
357f07bc797SBrandon Wyman         // First STATUS_WORD with no bits set, then with temperature fault.
358b654c619SBrandon Wyman         PMBusExpectations expectations;
359b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
3603f1242f3SBrandon Wyman         psu2.analyze();
3618da35c51SBrandon Wyman         // STATUS_WORD with temperature fault bit on.
362b654c619SBrandon Wyman         expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
36396893a46SBrandon Wyman         // STATUS_TEMPERATURE with fault bit(s) on.
36496893a46SBrandon Wyman         expectations.statusTempValue = 0x10;
365b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
3663f1242f3SBrandon Wyman         psu2.analyze();
3673f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
36896893a46SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
3693f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
3703f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
3713f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
37285c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
3736710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
374b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
3752cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
3767ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
37796893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), true);
3782916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
37939ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
38039ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
38139ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
382b654c619SBrandon Wyman     }
38385c7bf41SBrandon Wyman 
38485c7bf41SBrandon Wyman     // CML fault
385b654c619SBrandon Wyman     {
38685c7bf41SBrandon Wyman         // First STATUS_WORD wit no bits set, then with CML fault.
387b654c619SBrandon Wyman         PMBusExpectations expectations;
388b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
38985c7bf41SBrandon Wyman         psu2.analyze();
3908da35c51SBrandon Wyman         // STATUS_WORD with CML fault bit on.
391b654c619SBrandon Wyman         expectations.statusWordValue = (status_word::CML_FAULT);
39285c7bf41SBrandon Wyman         // Turn on STATUS_CML fault bit(s)
393b654c619SBrandon Wyman         expectations.statusCMLValue = 0xFF;
394b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
39585c7bf41SBrandon Wyman         psu2.analyze();
39685c7bf41SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
39785c7bf41SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
39885c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
39985c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
40085c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
40185c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), true);
4026710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
403b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
4042cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
4057ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
40696893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
4072916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
40839ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
40939ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
41039ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
411b654c619SBrandon Wyman     }
4126710ba2cSBrandon Wyman 
4136710ba2cSBrandon Wyman     // VOUT_OV_FAULT fault
414b654c619SBrandon Wyman     {
4156710ba2cSBrandon Wyman         // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault.
416b654c619SBrandon Wyman         PMBusExpectations expectations;
417b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
4186710ba2cSBrandon Wyman         psu2.analyze();
4196710ba2cSBrandon Wyman         // STATUS_WORD with VOUT/VOUT_OV fault.
420b654c619SBrandon Wyman         expectations.statusWordValue =
4216710ba2cSBrandon Wyman             ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT));
4226710ba2cSBrandon Wyman         // Turn on STATUS_VOUT fault bit(s)
423b654c619SBrandon Wyman         expectations.statusVOUTValue = 0xA0;
42496893a46SBrandon Wyman         // STATUS_TEMPERATURE don't care (default)
425b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
4266710ba2cSBrandon Wyman         psu2.analyze();
4276710ba2cSBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
4286710ba2cSBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
4296710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
4306710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
4316710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
4326710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
4336710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), true);
4342cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
435b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
4367ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
437b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
438b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
43939ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
44039ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
44139ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
442b10b3be0SBrandon Wyman     }
443b10b3be0SBrandon Wyman 
444b10b3be0SBrandon Wyman     // IOUT_OC_FAULT fault
445b10b3be0SBrandon Wyman     {
446b10b3be0SBrandon Wyman         // First STATUS_WORD with no bits set, then with IOUT_OC fault.
447b10b3be0SBrandon Wyman         PMBusExpectations expectations;
448b10b3be0SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
449b10b3be0SBrandon Wyman         psu2.analyze();
450b10b3be0SBrandon Wyman         // STATUS_WORD with IOUT_OC fault.
451b10b3be0SBrandon Wyman         expectations.statusWordValue = status_word::IOUT_OC_FAULT;
452b10b3be0SBrandon Wyman         // Turn on STATUS_IOUT fault bit(s)
453b10b3be0SBrandon Wyman         expectations.statusIOUTValue = 0x88;
454b10b3be0SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
455b10b3be0SBrandon Wyman         psu2.analyze();
456b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
457b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
458b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
459b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
460b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
461b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
462b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
463b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), true);
4642cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
4657ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
4662cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
4672cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
46839ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
46939ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
47039ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
4712cf46945SBrandon Wyman     }
4722cf46945SBrandon Wyman 
4732cf46945SBrandon Wyman     // VOUT_UV_FAULT
4742cf46945SBrandon Wyman     {
4752cf46945SBrandon Wyman         // First STATUS_WORD with no bits set, then with VOUT fault.
4762cf46945SBrandon Wyman         PMBusExpectations expectations;
4772cf46945SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
4782cf46945SBrandon Wyman         psu2.analyze();
4792cf46945SBrandon Wyman         // Change STATUS_WORD to indicate VOUT fault.
4802cf46945SBrandon Wyman         expectations.statusWordValue = (status_word::VOUT_FAULT);
4812cf46945SBrandon Wyman         // Turn on STATUS_VOUT fault bit(s)
4822cf46945SBrandon Wyman         expectations.statusVOUTValue = 0x30;
4832cf46945SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
4842cf46945SBrandon Wyman         psu2.analyze();
4852cf46945SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
4862cf46945SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
4872cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
4882cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
4892cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
4902cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
4912cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
4922cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
4932cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), true);
4947ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), false);
49596893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
4962916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
49739ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
49839ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
49939ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
500b654c619SBrandon Wyman     }
5013f1242f3SBrandon Wyman 
5027ee4d7e4SBrandon Wyman     // Fan fault
503b654c619SBrandon Wyman     {
504b654c619SBrandon Wyman         // First STATUS_WORD with no bits set, then with fan fault.
505b654c619SBrandon Wyman         PMBusExpectations expectations;
506b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
5073f1242f3SBrandon Wyman         psu2.analyze();
508b654c619SBrandon Wyman         expectations.statusWordValue = (status_word::FAN_FAULT);
5097ee4d7e4SBrandon Wyman         // STATUS_FANS_1_2 with fan 1 warning & fault bits on.
5107ee4d7e4SBrandon Wyman         expectations.statusFans12Value = 0xA0;
511b654c619SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
5123f1242f3SBrandon Wyman         psu2.analyze();
5133f1242f3SBrandon Wyman         EXPECT_EQ(psu2.isPresent(), true);
5147ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), true);
5153f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasInputFault(), false);
5163f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasMFRFault(), false);
5173f1242f3SBrandon Wyman         EXPECT_EQ(psu2.hasVINUVFault(), false);
51885c7bf41SBrandon Wyman         EXPECT_EQ(psu2.hasCommFault(), false);
5196710ba2cSBrandon Wyman         EXPECT_EQ(psu2.hasVoutOVFault(), false);
520b10b3be0SBrandon Wyman         EXPECT_EQ(psu2.hasIoutOCFault(), false);
5212cf46945SBrandon Wyman         EXPECT_EQ(psu2.hasVoutUVFault(), false);
5227ee4d7e4SBrandon Wyman         EXPECT_EQ(psu2.hasFanFault(), true);
52396893a46SBrandon Wyman         EXPECT_EQ(psu2.hasTempFault(), false);
5242916ea52SBrandon Wyman         EXPECT_EQ(psu2.hasPgoodFault(), false);
52539ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSKillFault(), false);
52639ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
52739ea02bcSBrandon Wyman         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
528b654c619SBrandon Wyman     }
5292916ea52SBrandon Wyman 
53006ca4590SBrandon Wyman     // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT.
5312cf46945SBrandon Wyman     {
5322916ea52SBrandon Wyman         // First STATUS_WORD with no bits set.
5332916ea52SBrandon Wyman         PMBusExpectations expectations;
5342916ea52SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
5352916ea52SBrandon Wyman         psu2.analyze();
5362916ea52SBrandon Wyman         EXPECT_EQ(psu2.isFaulted(), false);
5372916ea52SBrandon Wyman         // POWER_GOOD# inactive, and OFF bit on.
5382916ea52SBrandon Wyman         expectations.statusWordValue =
5392916ea52SBrandon Wyman             ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF));
54006ca4590SBrandon Wyman         for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
54106ca4590SBrandon Wyman         {
5422916ea52SBrandon Wyman             // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and
5432916ea52SBrandon Wyman             // STATUS_TEMPERATURE: Don't care if bits set or not (defaults).
5442916ea52SBrandon Wyman             setPMBusExpectations(mockPMBus, expectations);
5452916ea52SBrandon Wyman             psu2.analyze();
5462916ea52SBrandon Wyman             EXPECT_EQ(psu2.isPresent(), true);
54706ca4590SBrandon Wyman             if (x < DEGLITCH_LIMIT)
54806ca4590SBrandon Wyman             {
54906ca4590SBrandon Wyman                 EXPECT_EQ(psu2.isFaulted(), false);
55006ca4590SBrandon Wyman             }
55106ca4590SBrandon Wyman             else
55206ca4590SBrandon Wyman             {
5532916ea52SBrandon Wyman                 EXPECT_EQ(psu2.isFaulted(), true);
55406ca4590SBrandon Wyman             }
5552916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasInputFault(), false);
5562916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasMFRFault(), false);
5572916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasVINUVFault(), false);
5582916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasCommFault(), false);
5592916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasVoutOVFault(), false);
5602cf46945SBrandon Wyman             EXPECT_EQ(psu2.hasVoutUVFault(), false);
561b10b3be0SBrandon Wyman             EXPECT_EQ(psu2.hasIoutOCFault(), false);
5627ee4d7e4SBrandon Wyman             EXPECT_EQ(psu2.hasFanFault(), false);
5632916ea52SBrandon Wyman             EXPECT_EQ(psu2.hasTempFault(), false);
56406ca4590SBrandon Wyman             if (x < DEGLITCH_LIMIT)
56506ca4590SBrandon Wyman             {
56606ca4590SBrandon Wyman                 EXPECT_EQ(psu2.hasPgoodFault(), false);
56706ca4590SBrandon Wyman             }
56806ca4590SBrandon Wyman             else
56906ca4590SBrandon Wyman             {
5702916ea52SBrandon Wyman                 EXPECT_EQ(psu2.hasPgoodFault(), true);
5712916ea52SBrandon Wyman             }
57206ca4590SBrandon Wyman         }
57306ca4590SBrandon Wyman     }
5742916ea52SBrandon Wyman 
5753f1242f3SBrandon Wyman     // TODO: ReadFailure
5763f1242f3SBrandon Wyman }
5773f1242f3SBrandon Wyman 
57859a35793SBrandon Wyman TEST_F(PowerSupplyTests, OnOffConfig)
57959a35793SBrandon Wyman {
58059a35793SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
58159a35793SBrandon Wyman     uint8_t data = 0x15;
58259a35793SBrandon Wyman 
58359a35793SBrandon Wyman     // Test where PSU is NOT present
58459a35793SBrandon Wyman     try
58559a35793SBrandon Wyman     {
586681b2a36SB. J. Wyman         // Assume GPIO presence, not inventory presence?
587681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
588681b2a36SB. J. Wyman 
5893ca062aeSAdriana Kobylak         MockedGPIOInterface* mockPresenceGPIO =
5903ca062aeSAdriana Kobylak             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
591681b2a36SB. J. Wyman         ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0));
59259a35793SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
593681b2a36SB. J. Wyman         // Constructor should set initial presence, default read returns 0.
59459a35793SBrandon Wyman         // If it is not present, I should not be trying to write to it.
59559a35793SBrandon Wyman         EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0);
59659a35793SBrandon Wyman         psu.onOffConfig(data);
59759a35793SBrandon Wyman     }
59859a35793SBrandon Wyman     catch (...)
5990c9a33d6SAdriana Kobylak     {}
60059a35793SBrandon Wyman 
60159a35793SBrandon Wyman     // Test where PSU is present
60259a35793SBrandon Wyman     try
60359a35793SBrandon Wyman     {
604681b2a36SB. J. Wyman         // Assume GPIO presence, not inventory presence?
605681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
6063ca062aeSAdriana Kobylak         MockedGPIOInterface* mockPresenceGPIO =
6073ca062aeSAdriana Kobylak             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
608*391a0690SBrandon Wyman         // There will potentially be multiple calls, we want it to continue
609*391a0690SBrandon Wyman         // returning 1 for the GPIO read to keep the power supply present.
610*391a0690SBrandon Wyman         EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
61159a35793SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
612*391a0690SBrandon Wyman         setMissingToPresentExpects(mockPMBus, mockedUtil);
613*391a0690SBrandon Wyman         // If I am calling analyze(), I should probably give it good data.
614*391a0690SBrandon Wyman         // STATUS_WORD 0x0000 is powered on, no faults.
615*391a0690SBrandon Wyman         PMBusExpectations expectations;
616*391a0690SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
617681b2a36SB. J. Wyman         psu.analyze();
618*391a0690SBrandon Wyman         // I definitely should be writting ON_OFF_CONFIG if I call the function
619*391a0690SBrandon Wyman         EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, ElementsAre(0x15),
620*391a0690SBrandon Wyman                                            Type::HwmonDeviceDebug))
62159a35793SBrandon Wyman             .Times(1);
62259a35793SBrandon Wyman         psu.onOffConfig(data);
62359a35793SBrandon Wyman     }
62459a35793SBrandon Wyman     catch (...)
6250c9a33d6SAdriana Kobylak     {}
62659a35793SBrandon Wyman }
62759a35793SBrandon Wyman 
6283f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, ClearFaults)
6293f1242f3SBrandon Wyman {
6303f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
631681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, PSUGPIOLineName};
6323ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
6333ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
63406ca4590SBrandon Wyman     // Always return 1 to indicate present.
63506ca4590SBrandon Wyman     // Each analyze() call will trigger a read of the presence GPIO.
63606ca4590SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
637681b2a36SB. J. Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
638*391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
6398da35c51SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
640b654c619SBrandon Wyman     PMBusExpectations expectations;
641b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
642681b2a36SB. J. Wyman     psu.analyze();
6433f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), true);
6443f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), false);
6453f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
6463f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
6473f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
64885c7bf41SBrandon Wyman     EXPECT_EQ(psu.hasCommFault(), false);
6496710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), false);
650b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), false);
6512cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
6527ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), false);
65396893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), false);
6542916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
65539ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
65639ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
65739ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
658b654c619SBrandon Wyman 
659f07bc797SBrandon Wyman     // STATUS_WORD with fault bits galore!
660b654c619SBrandon Wyman     expectations.statusWordValue = 0xFFFF;
661f07bc797SBrandon Wyman     // STATUS_INPUT with fault bits on.
662b654c619SBrandon Wyman     expectations.statusInputValue = 0xFF;
663f07bc797SBrandon Wyman     // STATUS_MFR_SPEFIC with bits on.
664b654c619SBrandon Wyman     expectations.statusMFRValue = 0xFF;
66585c7bf41SBrandon Wyman     // STATUS_CML with bits on.
666b654c619SBrandon Wyman     expectations.statusCMLValue = 0xFF;
6676710ba2cSBrandon Wyman     // STATUS_VOUT with bits on.
668b654c619SBrandon Wyman     expectations.statusVOUTValue = 0xFF;
669b10b3be0SBrandon Wyman     // STATUS_IOUT with bits on.
670b10b3be0SBrandon Wyman     expectations.statusIOUTValue = 0xFF;
6717ee4d7e4SBrandon Wyman     // STATUS_FANS_1_2 with bits on.
6727ee4d7e4SBrandon Wyman     expectations.statusFans12Value = 0xFF;
67396893a46SBrandon Wyman     // STATUS_TEMPERATURE with bits on.
67496893a46SBrandon Wyman     expectations.statusTempValue = 0xFF;
675b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
6763f1242f3SBrandon Wyman     psu.analyze();
6773f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), true);
6783f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), true);
6793f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), true);
6803f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), true);
6813f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), true);
68285c7bf41SBrandon Wyman     EXPECT_EQ(psu.hasCommFault(), true);
6836710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), true);
684b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), true);
6852cf46945SBrandon Wyman     // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
6862cf46945SBrandon Wyman     // Rely on HasVoutUVFault() to verify this sets and clears.
6872cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
6887ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), true);
68996893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), true);
69006ca4590SBrandon Wyman     // pgoodFault is deglitched up to DEGLITCH_LIMIT
69106ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
69206ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
69306ca4590SBrandon Wyman     psu.analyze();
69406ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
69506ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
69606ca4590SBrandon Wyman     psu.analyze();
69706ca4590SBrandon Wyman     // DEGLITCH_LIMIT reached for pgoodFault
6982916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), true);
69939ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), true);
70039ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), true);
70139ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), true);
7022cf46945SBrandon Wyman 
703*391a0690SBrandon Wyman     EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(207000));
7043f1242f3SBrandon Wyman     psu.clearFaults();
7053f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), true);
7063f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), false);
7073f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
7083f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
7093f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
71085c7bf41SBrandon Wyman     EXPECT_EQ(psu.hasCommFault(), false);
7116710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), false);
712b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), false);
7132cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
7147ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), false);
71596893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), false);
7162916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
71739ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
71839ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
71939ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
720681b2a36SB. J. Wyman 
721681b2a36SB. J. Wyman     // TODO: Faults clear on missing/present?
7223f1242f3SBrandon Wyman }
7233f1242f3SBrandon Wyman 
7243f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory)
7253f1242f3SBrandon Wyman {
7263f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
7271d7a7df8SBrandon Wyman 
7281d7a7df8SBrandon Wyman     try
7291d7a7df8SBrandon Wyman     {
730681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
7311d7a7df8SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
7321d7a7df8SBrandon Wyman         // If it is not present, I should not be trying to read a string
7331d7a7df8SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(_, _)).Times(0);
7341d7a7df8SBrandon Wyman         psu.updateInventory();
7351d7a7df8SBrandon Wyman     }
7361d7a7df8SBrandon Wyman     catch (...)
7371d7a7df8SBrandon Wyman     {
7381d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have caught exception.";
7391d7a7df8SBrandon Wyman     }
7401d7a7df8SBrandon Wyman 
7411d7a7df8SBrandon Wyman     try
7421d7a7df8SBrandon Wyman     {
743681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, PSUGPIOLineName};
7443ca062aeSAdriana Kobylak         MockedGPIOInterface* mockPresenceGPIO =
7453ca062aeSAdriana Kobylak             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
746681b2a36SB. J. Wyman         // GPIO read return 1 to indicate present.
747681b2a36SB. J. Wyman         EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
7481d7a7df8SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
749*391a0690SBrandon Wyman         setMissingToPresentExpects(mockPMBus, mockedUtil);
750*391a0690SBrandon Wyman         // STATUS_WORD 0x0000 is powered on, no faults.
751*391a0690SBrandon Wyman         PMBusExpectations expectations;
752*391a0690SBrandon Wyman         setPMBusExpectations(mockPMBus, expectations);
753*391a0690SBrandon Wyman         // Need analyze call to update power supply from missing to present.
754*391a0690SBrandon Wyman         psu.analyze();
7551d7a7df8SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return(""));
7563f1242f3SBrandon Wyman         psu.updateInventory();
7571d7a7df8SBrandon Wyman 
7583c530fbdSBrandon Wyman #if IBM_VPD
7591d7a7df8SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(_, _))
7601d7a7df8SBrandon Wyman             .WillOnce(Return("CCIN"))
7611d7a7df8SBrandon Wyman             .WillOnce(Return("PN3456"))
7621d7a7df8SBrandon Wyman             .WillOnce(Return("FN3456"))
7631d7a7df8SBrandon Wyman             .WillOnce(Return("HEADER"))
7641d7a7df8SBrandon Wyman             .WillOnce(Return("SN3456"))
7651d7a7df8SBrandon Wyman             .WillOnce(Return("FW3456"));
7663c530fbdSBrandon Wyman #endif
7671d7a7df8SBrandon Wyman         psu.updateInventory();
7681d7a7df8SBrandon Wyman         // TODO: D-Bus mocking to verify values stored on D-Bus (???)
7691d7a7df8SBrandon Wyman     }
7701d7a7df8SBrandon Wyman     catch (...)
7711d7a7df8SBrandon Wyman     {
7721d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have caught exception.";
7731d7a7df8SBrandon Wyman     }
7743f1242f3SBrandon Wyman }
7753f1242f3SBrandon Wyman 
7763f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent)
7773f1242f3SBrandon Wyman {
7783f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
779681b2a36SB. J. Wyman 
780681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
7813ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
7823ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
7833f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), false);
7843f1242f3SBrandon Wyman 
785681b2a36SB. J. Wyman     // Change GPIO read to return 1 to indicate present.
786681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
787*391a0690SBrandon Wyman     // Call to analyze() will update to present, that will trigger updating
788*391a0690SBrandon Wyman     // to the correct/latest HWMON directory, in case it changes.
789*391a0690SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
790*391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
791*391a0690SBrandon Wyman     // Call to analyze things will trigger read of STATUS_WORD and READ_VIN.
792*391a0690SBrandon Wyman     // Default expectations will be on, no faults.
793*391a0690SBrandon Wyman     PMBusExpectations expectations;
794*391a0690SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
795681b2a36SB. J. Wyman     psu.analyze();
796681b2a36SB. J. Wyman     EXPECT_EQ(psu.isPresent(), true);
7973f1242f3SBrandon Wyman }
7983f1242f3SBrandon Wyman 
7993f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted)
8003f1242f3SBrandon Wyman {
8013f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
802681b2a36SB. J. Wyman 
803681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, PSUGPIOLineName};
8043ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
8053ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
806681b2a36SB. J. Wyman     // Always return 1 to indicate present.
807681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
808*391a0690SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
809*391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
810*391a0690SBrandon Wyman     // Call to analyze things will trigger read of STATUS_WORD and READ_VIN.
811*391a0690SBrandon Wyman     // Default expectations will be on, no faults.
812*391a0690SBrandon Wyman     PMBusExpectations expectations;
813*391a0690SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
814681b2a36SB. J. Wyman     psu.analyze();
8153f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), false);
816f07bc797SBrandon Wyman     // STATUS_WORD with fault bits on.
817b654c619SBrandon Wyman     expectations.statusWordValue = 0xFFFF;
818f07bc797SBrandon Wyman     // STATUS_INPUT with fault bits on.
819b654c619SBrandon Wyman     expectations.statusInputValue = 0xFF;
820f07bc797SBrandon Wyman     // STATUS_MFR_SPECIFIC with faults bits on.
821b654c619SBrandon Wyman     expectations.statusMFRValue = 0xFF;
82285c7bf41SBrandon Wyman     // STATUS_CML with faults bits on.
823b654c619SBrandon Wyman     expectations.statusCMLValue = 0xFF;
8246710ba2cSBrandon Wyman     // STATUS_VOUT with fault bits on.
825b654c619SBrandon Wyman     expectations.statusVOUTValue = 0xFF;
826b10b3be0SBrandon Wyman     // STATUS_IOUT with fault bits on.
827b10b3be0SBrandon Wyman     expectations.statusIOUTValue = 0xFF;
8287ee4d7e4SBrandon Wyman     // STATUS_FANS_1_2 with bits on.
8297ee4d7e4SBrandon Wyman     expectations.statusFans12Value = 0xFF;
83096893a46SBrandon Wyman     // STATUS_TEMPERATURE with fault bits on.
83196893a46SBrandon Wyman     expectations.statusTempValue = 0xFF;
832b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
8333f1242f3SBrandon Wyman     psu.analyze();
8343f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), true);
8353f1242f3SBrandon Wyman }
8363f1242f3SBrandon Wyman 
8373f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasInputFault)
8383f1242f3SBrandon Wyman {
8393f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
840681b2a36SB. J. Wyman 
841681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
8423ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
8433ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
844681b2a36SB. J. Wyman     // Always return 1 to indicate present.
845681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
8463f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
847*391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
8488da35c51SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
849b654c619SBrandon Wyman     PMBusExpectations expectations;
850b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
8513f1242f3SBrandon Wyman     psu.analyze();
8523f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
853f07bc797SBrandon Wyman     // STATUS_WORD with input fault/warn on.
854b654c619SBrandon Wyman     expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
855f07bc797SBrandon Wyman     // STATUS_INPUT with an input fault bit on.
856b654c619SBrandon Wyman     expectations.statusInputValue = 0x80;
857b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
8583f1242f3SBrandon Wyman     psu.analyze();
8593f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), true);
860f07bc797SBrandon Wyman     // STATUS_WORD with no bits on.
861b654c619SBrandon Wyman     expectations.statusWordValue = 0;
862b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
8633f1242f3SBrandon Wyman     psu.analyze();
8643f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
8653f1242f3SBrandon Wyman }
8663f1242f3SBrandon Wyman 
8673f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault)
8683f1242f3SBrandon Wyman {
8693f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
870681b2a36SB. J. Wyman 
871681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
8723ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
8733ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
874681b2a36SB. J. Wyman     // Always return 1 to indicate present.
875681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
8763f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
877*391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
878f07bc797SBrandon Wyman     // First return STATUS_WORD with no bits on.
8798da35c51SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
880b654c619SBrandon Wyman     PMBusExpectations expectations;
881b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
8823f1242f3SBrandon Wyman     psu.analyze();
8833f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
884f07bc797SBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
885b654c619SBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
886f07bc797SBrandon Wyman     // STATUS_MFR_SPEFIC with bit(s) on.
887b654c619SBrandon Wyman     expectations.statusMFRValue = 0xFF;
888b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
8893f1242f3SBrandon Wyman     psu.analyze();
8903f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), true);
891f07bc797SBrandon Wyman     // Back to no bits on in STATUS_WORD
892b654c619SBrandon Wyman     expectations.statusWordValue = 0;
893b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
8943f1242f3SBrandon Wyman     psu.analyze();
8953f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
8963f1242f3SBrandon Wyman }
8973f1242f3SBrandon Wyman 
8983f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault)
8993f1242f3SBrandon Wyman {
9003f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
901681b2a36SB. J. Wyman 
902681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
9033ca062aeSAdriana Kobylak     MockedGPIOInterface* mockPresenceGPIO =
9043ca062aeSAdriana Kobylak         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
905681b2a36SB. J. Wyman     // Always return 1 to indicate present.
906681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
9073f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
908*391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
9098da35c51SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
910b654c619SBrandon Wyman     PMBusExpectations expectations;
911b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
9123f1242f3SBrandon Wyman     psu.analyze();
9133f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
914f07bc797SBrandon Wyman     // Turn fault on.
915b654c619SBrandon Wyman     expectations.statusWordValue = (status_word::VIN_UV_FAULT);
91685c7bf41SBrandon Wyman     // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by
91785c7bf41SBrandon Wyman     // Figure 16, and assume bits on in STATUS_INPUT.
918b654c619SBrandon Wyman     expectations.statusInputValue = 0x18;
919b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
9203f1242f3SBrandon Wyman     psu.analyze();
9213f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), true);
922f07bc797SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
923b654c619SBrandon Wyman     expectations.statusWordValue = 0;
924b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
9253f1242f3SBrandon Wyman     psu.analyze();
9263f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
9273f1242f3SBrandon Wyman }
9286710ba2cSBrandon Wyman 
9296710ba2cSBrandon Wyman TEST_F(PowerSupplyTests, HasVoutOVFault)
9306710ba2cSBrandon Wyman {
9316710ba2cSBrandon Wyman     auto bus = sdbusplus::bus::new_default();
9326710ba2cSBrandon Wyman 
9336710ba2cSBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x69, PSUGPIOLineName};
9346710ba2cSBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
9356710ba2cSBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
9366710ba2cSBrandon Wyman     // Always return 1 to indicate present.
9376710ba2cSBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
9386710ba2cSBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
939*391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
9406710ba2cSBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
941b654c619SBrandon Wyman     PMBusExpectations expectations;
942b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
9436710ba2cSBrandon Wyman     psu.analyze();
9446710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), false);
9456710ba2cSBrandon Wyman     // Turn fault on.
946b654c619SBrandon Wyman     expectations.statusWordValue = (status_word::VOUT_OV_FAULT);
9476710ba2cSBrandon Wyman     // STATUS_VOUT fault bit(s)
948b654c619SBrandon Wyman     expectations.statusVOUTValue = 0x80;
94996893a46SBrandon Wyman     // STATUS_TEMPERATURE default.
950b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
9516710ba2cSBrandon Wyman     psu.analyze();
9526710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), true);
9536710ba2cSBrandon Wyman     // Back to no fault bits on in STATUS_WORD
954b654c619SBrandon Wyman     expectations.statusWordValue = 0;
955b654c619SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
9566710ba2cSBrandon Wyman     psu.analyze();
9576710ba2cSBrandon Wyman     EXPECT_EQ(psu.hasVoutOVFault(), false);
9586710ba2cSBrandon Wyman }
95996893a46SBrandon Wyman 
960b10b3be0SBrandon Wyman TEST_F(PowerSupplyTests, HasIoutOCFault)
961b10b3be0SBrandon Wyman {
962b10b3be0SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
963b10b3be0SBrandon Wyman 
964b10b3be0SBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName};
965b10b3be0SBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
966b10b3be0SBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
967b10b3be0SBrandon Wyman     // Always return 1 to indicate present.
968b10b3be0SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
969b10b3be0SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
970*391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
971b10b3be0SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
972b10b3be0SBrandon Wyman     PMBusExpectations expectations;
973b10b3be0SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
974b10b3be0SBrandon Wyman     psu.analyze();
975b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), false);
976b10b3be0SBrandon Wyman     // Turn fault on.
977b10b3be0SBrandon Wyman     expectations.statusWordValue = status_word::IOUT_OC_FAULT;
978b10b3be0SBrandon Wyman     // STATUS_IOUT fault bit(s)
979b10b3be0SBrandon Wyman     expectations.statusIOUTValue = 0x88;
980b10b3be0SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
981b10b3be0SBrandon Wyman     psu.analyze();
982b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), true);
983b10b3be0SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
984b10b3be0SBrandon Wyman     expectations.statusWordValue = 0;
985b10b3be0SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
986b10b3be0SBrandon Wyman     psu.analyze();
987b10b3be0SBrandon Wyman     EXPECT_EQ(psu.hasIoutOCFault(), false);
988b10b3be0SBrandon Wyman }
989b10b3be0SBrandon Wyman 
9902cf46945SBrandon Wyman TEST_F(PowerSupplyTests, HasVoutUVFault)
9912cf46945SBrandon Wyman {
9922cf46945SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
9932cf46945SBrandon Wyman 
9942cf46945SBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName};
9952cf46945SBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
9962cf46945SBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
9972cf46945SBrandon Wyman     // Always return 1 to indicate present.
9982cf46945SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
9992cf46945SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1000*391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
1001*391a0690SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
10022cf46945SBrandon Wyman     PMBusExpectations expectations;
10032cf46945SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
10042cf46945SBrandon Wyman     psu.analyze();
10052cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
10062cf46945SBrandon Wyman     // Turn fault on.
10072cf46945SBrandon Wyman     expectations.statusWordValue = (status_word::VOUT_FAULT);
10082cf46945SBrandon Wyman     // STATUS_VOUT fault bit(s)
10092cf46945SBrandon Wyman     expectations.statusVOUTValue = 0x30;
10102cf46945SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
10112cf46945SBrandon Wyman     psu.analyze();
10122cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), true);
10132cf46945SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
10142cf46945SBrandon Wyman     expectations.statusWordValue = 0;
10152cf46945SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
10162cf46945SBrandon Wyman     psu.analyze();
10172cf46945SBrandon Wyman     EXPECT_EQ(psu.hasVoutUVFault(), false);
10182cf46945SBrandon Wyman }
10192cf46945SBrandon Wyman 
10207ee4d7e4SBrandon Wyman TEST_F(PowerSupplyTests, HasFanFault)
10217ee4d7e4SBrandon Wyman {
10227ee4d7e4SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
10237ee4d7e4SBrandon Wyman 
10247ee4d7e4SBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName};
10257ee4d7e4SBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
10267ee4d7e4SBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
10277ee4d7e4SBrandon Wyman     // Always return 1 to indicate present.
10287ee4d7e4SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
10297ee4d7e4SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1030*391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
10317ee4d7e4SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
10327ee4d7e4SBrandon Wyman     PMBusExpectations expectations;
10337ee4d7e4SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
10347ee4d7e4SBrandon Wyman     psu.analyze();
10357ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), false);
10367ee4d7e4SBrandon Wyman     // Turn fault on.
10377ee4d7e4SBrandon Wyman     expectations.statusWordValue = (status_word::FAN_FAULT);
10387ee4d7e4SBrandon Wyman     // STATUS_FANS_1_2 fault bit on (Fan 1 Fault)
10397ee4d7e4SBrandon Wyman     expectations.statusFans12Value = 0x80;
10407ee4d7e4SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
10417ee4d7e4SBrandon Wyman     psu.analyze();
10427ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), true);
10437ee4d7e4SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
10447ee4d7e4SBrandon Wyman     expectations.statusWordValue = 0;
10457ee4d7e4SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
10467ee4d7e4SBrandon Wyman     psu.analyze();
10477ee4d7e4SBrandon Wyman     EXPECT_EQ(psu.hasFanFault(), false);
10487ee4d7e4SBrandon Wyman }
10497ee4d7e4SBrandon Wyman 
105096893a46SBrandon Wyman TEST_F(PowerSupplyTests, HasTempFault)
105196893a46SBrandon Wyman {
105296893a46SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
105396893a46SBrandon Wyman 
105496893a46SBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName};
105596893a46SBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
105696893a46SBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
105796893a46SBrandon Wyman     // Always return 1 to indicate present.
105896893a46SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
105996893a46SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1060*391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
106196893a46SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
106296893a46SBrandon Wyman     PMBusExpectations expectations;
106396893a46SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
106496893a46SBrandon Wyman     psu.analyze();
106596893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), false);
106696893a46SBrandon Wyman     // Turn fault on.
106796893a46SBrandon Wyman     expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
106896893a46SBrandon Wyman     // STATUS_TEMPERATURE fault bit on (OT Fault)
106996893a46SBrandon Wyman     expectations.statusTempValue = 0x80;
107096893a46SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
107196893a46SBrandon Wyman     psu.analyze();
107296893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), true);
107396893a46SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
107496893a46SBrandon Wyman     expectations.statusWordValue = 0;
107596893a46SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
107696893a46SBrandon Wyman     psu.analyze();
107796893a46SBrandon Wyman     EXPECT_EQ(psu.hasTempFault(), false);
107896893a46SBrandon Wyman }
10792916ea52SBrandon Wyman 
10802916ea52SBrandon Wyman TEST_F(PowerSupplyTests, HasPgoodFault)
10812916ea52SBrandon Wyman {
10822916ea52SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
10832916ea52SBrandon Wyman 
10842916ea52SBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6b, PSUGPIOLineName};
10852916ea52SBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
10862916ea52SBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
10872916ea52SBrandon Wyman     // Always return 1 to indicate present.
10882916ea52SBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
10892916ea52SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1090*391a0690SBrandon Wyman     setMissingToPresentExpects(mockPMBus, mockedUtil);
10912916ea52SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
10922916ea52SBrandon Wyman     PMBusExpectations expectations;
10932916ea52SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
10942916ea52SBrandon Wyman     psu.analyze();
10952916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
1096*391a0690SBrandon Wyman     // Setup another expectation of no faults.
1097*391a0690SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
1098*391a0690SBrandon Wyman     psu.analyze();
1099*391a0690SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
11002916ea52SBrandon Wyman     // Turn PGOOD# off (fault on).
11012916ea52SBrandon Wyman     expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED);
11022916ea52SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
11032916ea52SBrandon Wyman     psu.analyze();
110406ca4590SBrandon Wyman     // Expect false until reaches DEGLITCH_LIMIT
110506ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
110606ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
110706ca4590SBrandon Wyman     psu.analyze();
110806ca4590SBrandon Wyman     // Expect false until reaches DEGLITCH_LIMIT
110906ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
111006ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
111106ca4590SBrandon Wyman     psu.analyze();
111206ca4590SBrandon Wyman     // DEGLITCH_LIMIT reached, expect true.
11132916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), true);
11142916ea52SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
11152916ea52SBrandon Wyman     expectations.statusWordValue = 0;
11162916ea52SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
11172916ea52SBrandon Wyman     psu.analyze();
11182916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
11192916ea52SBrandon Wyman     // Turn OFF bit on
11202916ea52SBrandon Wyman     expectations.statusWordValue = (status_word::UNIT_IS_OFF);
11212916ea52SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
11222916ea52SBrandon Wyman     psu.analyze();
112306ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
112406ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
112506ca4590SBrandon Wyman     psu.analyze();
112606ca4590SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
112706ca4590SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
112806ca4590SBrandon Wyman     psu.analyze();
11292916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), true);
11302916ea52SBrandon Wyman     // Back to no fault bits on in STATUS_WORD
11312916ea52SBrandon Wyman     expectations.statusWordValue = 0;
11322916ea52SBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
11332916ea52SBrandon Wyman     psu.analyze();
11342916ea52SBrandon Wyman     EXPECT_EQ(psu.hasPgoodFault(), false);
11352916ea52SBrandon Wyman }
113639ea02bcSBrandon Wyman 
113739ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSKillFault)
113839ea02bcSBrandon Wyman {
113939ea02bcSBrandon Wyman     auto bus = sdbusplus::bus::new_default();
114039ea02bcSBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 4, 0x6d, PSUGPIOLineName};
114139ea02bcSBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
114239ea02bcSBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
114339ea02bcSBrandon Wyman     // Always return 1 to indicate present.
114439ea02bcSBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
114539ea02bcSBrandon Wyman     psu.analyze();
114639ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
114739ea02bcSBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
114839ea02bcSBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
114939ea02bcSBrandon Wyman     PMBusExpectations expectations;
115039ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
115139ea02bcSBrandon Wyman     psu.analyze();
115239ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
115339ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
115439ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
115539ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit(s) on.
115639ea02bcSBrandon Wyman     expectations.statusMFRValue = 0xFF;
115739ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
115839ea02bcSBrandon Wyman     psu.analyze();
115939ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), true);
116039ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
116139ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
116239ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
116339ea02bcSBrandon Wyman     psu.analyze();
116439ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
116539ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
116639ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
116739ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit 4 on.
116839ea02bcSBrandon Wyman     expectations.statusMFRValue = 0x10;
116939ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
117039ea02bcSBrandon Wyman     psu.analyze();
117139ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), true);
117239ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
117339ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
117439ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
117539ea02bcSBrandon Wyman     psu.analyze();
117639ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSKillFault(), false);
117739ea02bcSBrandon Wyman }
117839ea02bcSBrandon Wyman 
117939ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPS12VcsFault)
118039ea02bcSBrandon Wyman {
118139ea02bcSBrandon Wyman     auto bus = sdbusplus::bus::new_default();
118239ea02bcSBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 5, 0x6e, PSUGPIOLineName};
118339ea02bcSBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
118439ea02bcSBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
118539ea02bcSBrandon Wyman     // Always return 1 to indicate present.
118639ea02bcSBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
118739ea02bcSBrandon Wyman     psu.analyze();
118839ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
118939ea02bcSBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
119039ea02bcSBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
119139ea02bcSBrandon Wyman     PMBusExpectations expectations;
119239ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
119339ea02bcSBrandon Wyman     psu.analyze();
119439ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
119539ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
119639ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
119739ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit(s) on.
119839ea02bcSBrandon Wyman     expectations.statusMFRValue = 0xFF;
119939ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
120039ea02bcSBrandon Wyman     psu.analyze();
120139ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), true);
120239ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
120339ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
120439ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
120539ea02bcSBrandon Wyman     psu.analyze();
120639ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
120739ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
120839ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
120939ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit 6 on.
121039ea02bcSBrandon Wyman     expectations.statusMFRValue = 0x40;
121139ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
121239ea02bcSBrandon Wyman     psu.analyze();
121339ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), true);
121439ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
121539ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
121639ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
121739ea02bcSBrandon Wyman     psu.analyze();
121839ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPS12VcsFault(), false);
121939ea02bcSBrandon Wyman }
122039ea02bcSBrandon Wyman 
122139ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSCS12VFault)
122239ea02bcSBrandon Wyman {
122339ea02bcSBrandon Wyman     auto bus = sdbusplus::bus::new_default();
122439ea02bcSBrandon Wyman     PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f, PSUGPIOLineName};
122539ea02bcSBrandon Wyman     MockedGPIOInterface* mockPresenceGPIO =
122639ea02bcSBrandon Wyman         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
122739ea02bcSBrandon Wyman     // Always return 1 to indicate present.
122839ea02bcSBrandon Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
122939ea02bcSBrandon Wyman     psu.analyze();
123039ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
123139ea02bcSBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
123239ea02bcSBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
123339ea02bcSBrandon Wyman     PMBusExpectations expectations;
123439ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
123539ea02bcSBrandon Wyman     psu.analyze();
123639ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
123739ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
123839ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
123939ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit(s) on.
124039ea02bcSBrandon Wyman     expectations.statusMFRValue = 0xFF;
124139ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
124239ea02bcSBrandon Wyman     psu.analyze();
124339ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), true);
124439ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
124539ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
124639ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
124739ea02bcSBrandon Wyman     psu.analyze();
124839ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
124939ea02bcSBrandon Wyman     // Next return STATUS_WORD with MFR fault bit on.
125039ea02bcSBrandon Wyman     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
125139ea02bcSBrandon Wyman     // STATUS_MFR_SPEFIC with bit 7 on.
125239ea02bcSBrandon Wyman     expectations.statusMFRValue = 0x80;
125339ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
125439ea02bcSBrandon Wyman     psu.analyze();
125539ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), true);
125639ea02bcSBrandon Wyman     // Back to no bits on in STATUS_WORD
125739ea02bcSBrandon Wyman     expectations.statusWordValue = 0;
125839ea02bcSBrandon Wyman     setPMBusExpectations(mockPMBus, expectations);
125939ea02bcSBrandon Wyman     psu.analyze();
126039ea02bcSBrandon Wyman     EXPECT_EQ(psu.hasPSCS12VFault(), false);
126139ea02bcSBrandon Wyman }
1262