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 258da35c51SBrandon Wyman // Helper function to setup expectations for various STATUS_* commands 268da35c51SBrandon Wyman void setPMBusExpectations(MockedPMBus& mockPMBus, uint16_t statusWordValue, 278da35c51SBrandon Wyman uint8_t statusInputValue = 0, 288da35c51SBrandon Wyman uint8_t statusMFRValue = 0, 29*6710ba2cSBrandon Wyman uint8_t statusCMLValue = 0, 30*6710ba2cSBrandon Wyman uint8_t statusVOUTValue = 0) 318da35c51SBrandon Wyman { 328da35c51SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 338da35c51SBrandon Wyman .Times(1) 348da35c51SBrandon Wyman .WillOnce(Return(statusWordValue)); 358da35c51SBrandon Wyman 368da35c51SBrandon Wyman if (statusWordValue != 0) 378da35c51SBrandon Wyman { 388da35c51SBrandon Wyman // If fault bits are on in STATUS_WORD, there will also be a read of 398da35c51SBrandon Wyman // STATUS_INPUT, STATUS_MFR, and STATUS_CML. 408da35c51SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _)) 418da35c51SBrandon Wyman .Times(1) 428da35c51SBrandon Wyman .WillOnce(Return(statusInputValue)); 438da35c51SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _)) 448da35c51SBrandon Wyman .Times(1) 458da35c51SBrandon Wyman .WillOnce(Return(statusMFRValue)); 468da35c51SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _)) 478da35c51SBrandon Wyman .Times(1) 488da35c51SBrandon Wyman .WillOnce(Return(statusCMLValue)); 49*6710ba2cSBrandon Wyman // Page will need to be set to 0 to read STATUS_VOUT. 50*6710ba2cSBrandon Wyman EXPECT_CALL(mockPMBus, insertPageNum(STATUS_VOUT, 0)) 51*6710ba2cSBrandon Wyman .Times(1) 52*6710ba2cSBrandon Wyman .WillOnce(Return("status0_vout")); 53*6710ba2cSBrandon Wyman EXPECT_CALL(mockPMBus, read("status0_vout", _)) 54*6710ba2cSBrandon Wyman .Times(1) 55*6710ba2cSBrandon Wyman .WillOnce(Return(statusVOUTValue)); 568da35c51SBrandon Wyman } 578da35c51SBrandon Wyman } 588da35c51SBrandon Wyman 593f1242f3SBrandon Wyman class PowerSupplyTests : public ::testing::Test 603f1242f3SBrandon Wyman { 613f1242f3SBrandon Wyman public: 623f1242f3SBrandon Wyman PowerSupplyTests() : 633f1242f3SBrandon Wyman mockedUtil(reinterpret_cast<const MockedUtil&>(getUtils())) 643f1242f3SBrandon Wyman { 653f1242f3SBrandon Wyman ON_CALL(mockedUtil, getPresence(_, _)).WillByDefault(Return(false)); 663f1242f3SBrandon Wyman } 673f1242f3SBrandon Wyman 683f1242f3SBrandon Wyman ~PowerSupplyTests() override 693f1242f3SBrandon Wyman { 703f1242f3SBrandon Wyman freeUtils(); 713f1242f3SBrandon Wyman } 723f1242f3SBrandon Wyman 733f1242f3SBrandon Wyman const MockedUtil& mockedUtil; 743f1242f3SBrandon Wyman }; 753f1242f3SBrandon Wyman 763f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Constructor) 773f1242f3SBrandon Wyman { 783f1242f3SBrandon Wyman /** 793f1242f3SBrandon Wyman * @param[in] invpath - String for inventory path to use 803f1242f3SBrandon Wyman * @param[in] i2cbus - The bus number this power supply is on 813f1242f3SBrandon Wyman * @param[in] i2caddr - The 16-bit I2C address of the power supply 82681b2a36SB. J. Wyman * @param[in] gpioLineName - The string for the gpio-line-name to read for 83681b2a36SB. J. Wyman * presence. 84681b2a36SB. J. Wyman * @param[in] bindDelay - Time in milliseconds to delay binding the device 85681b2a36SB. J. Wyman * driver after seeing the presence line go active. 863f1242f3SBrandon Wyman */ 873f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 881d7a7df8SBrandon Wyman 891d7a7df8SBrandon Wyman // Try where inventory path is empty, constructor should fail. 901d7a7df8SBrandon Wyman try 911d7a7df8SBrandon Wyman { 92681b2a36SB. J. Wyman auto psu = 93681b2a36SB. J. Wyman std::make_unique<PowerSupply>(bus, "", 3, 0x68, PSUGPIOLineName); 941d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have reached this line."; 951d7a7df8SBrandon Wyman } 961d7a7df8SBrandon Wyman catch (const std::invalid_argument& e) 971d7a7df8SBrandon Wyman { 981d7a7df8SBrandon Wyman EXPECT_STREQ(e.what(), "Invalid empty inventoryPath"); 991d7a7df8SBrandon Wyman } 1001d7a7df8SBrandon Wyman catch (...) 1011d7a7df8SBrandon Wyman { 1021d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 1031d7a7df8SBrandon Wyman } 1041d7a7df8SBrandon Wyman 105681b2a36SB. J. Wyman // TODO: Try invalid i2c address? 106681b2a36SB. J. Wyman 107681b2a36SB. J. Wyman // Try where gpioLineName is empty. 1081d7a7df8SBrandon Wyman try 1091d7a7df8SBrandon Wyman { 1101d7a7df8SBrandon Wyman auto psu = 111681b2a36SB. J. Wyman std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, ""); 112681b2a36SB. J. Wyman ADD_FAILURE() 113681b2a36SB. J. Wyman << "Should not have reached this line. Invalid gpioLineName."; 114681b2a36SB. J. Wyman } 115681b2a36SB. J. Wyman catch (const std::invalid_argument& e) 116681b2a36SB. J. Wyman { 117681b2a36SB. J. Wyman EXPECT_STREQ(e.what(), "Invalid empty gpioLineName"); 118681b2a36SB. J. Wyman } 119681b2a36SB. J. Wyman catch (...) 120681b2a36SB. J. Wyman { 121681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 122681b2a36SB. J. Wyman } 123681b2a36SB. J. Wyman 124681b2a36SB. J. Wyman // Test with valid arguments 125681b2a36SB. J. Wyman // NOT using D-Bus inventory path for presence. 126681b2a36SB. J. Wyman try 127681b2a36SB. J. Wyman { 128681b2a36SB. J. Wyman auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, 129681b2a36SB. J. Wyman PSUGPIOLineName); 1303f1242f3SBrandon Wyman 1313f1242f3SBrandon Wyman EXPECT_EQ(psu->isPresent(), false); 1323f1242f3SBrandon Wyman EXPECT_EQ(psu->isFaulted(), false); 1338da35c51SBrandon Wyman EXPECT_EQ(psu->hasCommFault(), false); 1343f1242f3SBrandon Wyman EXPECT_EQ(psu->hasInputFault(), false); 1353f1242f3SBrandon Wyman EXPECT_EQ(psu->hasMFRFault(), false); 1363f1242f3SBrandon Wyman EXPECT_EQ(psu->hasVINUVFault(), false); 137*6710ba2cSBrandon Wyman EXPECT_EQ(psu->hasVoutOVFault(), false); 1383f1242f3SBrandon Wyman } 1391d7a7df8SBrandon Wyman catch (...) 1401d7a7df8SBrandon Wyman { 1411d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 1421d7a7df8SBrandon Wyman } 143681b2a36SB. J. Wyman 144681b2a36SB. J. Wyman // Test with valid arguments 145681b2a36SB. J. Wyman // TODO: Using D-Bus inventory path for presence. 146681b2a36SB. J. Wyman try 147681b2a36SB. J. Wyman { 148681b2a36SB. J. Wyman // FIXME: How do I get that presenceGPIO.read() in the startup to throw 149681b2a36SB. J. Wyman // an exception? 150681b2a36SB. J. Wyman 151681b2a36SB. J. Wyman // EXPECT_CALL(mockedUtil, getPresence(_, 152681b2a36SB. J. Wyman // StrEq(PSUInventoryPath))) 153681b2a36SB. J. Wyman // .Times(1); 154681b2a36SB. J. Wyman } 155681b2a36SB. J. Wyman catch (...) 156681b2a36SB. J. Wyman { 157681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 158681b2a36SB. J. Wyman } 1591d7a7df8SBrandon Wyman } 1603f1242f3SBrandon Wyman 1613f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Analyze) 1623f1242f3SBrandon Wyman { 1633f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1643f1242f3SBrandon Wyman 165681b2a36SB. J. Wyman // If I default to reading the GPIO, I will NOT expect a call to 166681b2a36SB. J. Wyman // getPresence(). 167681b2a36SB. J. Wyman 168681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName}; 1693ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 1703ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 171681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0)); 172681b2a36SB. J. Wyman 1733f1242f3SBrandon Wyman psu.analyze(); 1743f1242f3SBrandon Wyman // By default, nothing should change. 1753f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 1763f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 1773f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 1783f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 1793f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 18085c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 181*6710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 1823f1242f3SBrandon Wyman 183681b2a36SB. J. Wyman PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName}; 184681b2a36SB. J. Wyman // In order to get the various faults tested, the power supply needs to 185681b2a36SB. J. Wyman // be present in order to read from the PMBus device(s). 1863ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO2 = 1873ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO()); 188681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO2, read()).WillByDefault(Return(1)); 189681b2a36SB. J. Wyman 190681b2a36SB. J. Wyman EXPECT_EQ(psu2.isPresent(), false); 1913f1242f3SBrandon Wyman 1923f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus()); 1938da35c51SBrandon Wyman // Presence change from missing to present will trigger write to 1948da35c51SBrandon Wyman // ON_OFF_CONFIG. 1958da35c51SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, _, _)); 196f07bc797SBrandon Wyman // Presence change from missing to present will trigger in1_input read in 197f07bc797SBrandon Wyman // an attempt to get CLEAR_FAULTS called. 198f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(206000)); 19985c7bf41SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 2008da35c51SBrandon Wyman uint16_t statusWordValue = 0; 2018da35c51SBrandon Wyman uint8_t statusInputValue = 0; 2028da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 2033f1242f3SBrandon Wyman psu2.analyze(); 2043f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2053f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 2063f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 2073f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 2083f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 20985c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 210*6710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 2113f1242f3SBrandon Wyman 2123f1242f3SBrandon Wyman // STATUS_WORD input fault/warn 2138da35c51SBrandon Wyman statusWordValue = (status_word::INPUT_FAULT_WARN); 214f07bc797SBrandon Wyman // STATUS_INPUT fault bits ... on. 2158da35c51SBrandon Wyman statusInputValue = 0x38; 216*6710ba2cSBrandon Wyman // STATUS_MFR, STATUS_CML, and STATUS_VOUT don't care 2178da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue, statusInputValue); 2183f1242f3SBrandon Wyman psu2.analyze(); 2193f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2203f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), true); 2213f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), true); 2223f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 2233f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 22485c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 225*6710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 2263f1242f3SBrandon Wyman 2273f1242f3SBrandon Wyman // STATUS_WORD INPUT/UV fault. 2283f1242f3SBrandon Wyman // First need it to return good status, then the fault 2298da35c51SBrandon Wyman statusWordValue = 0; 2308da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 2313f1242f3SBrandon Wyman psu2.analyze(); 2328da35c51SBrandon Wyman // Now set fault bits in STATUS_WORD 2338da35c51SBrandon Wyman statusWordValue = 2348da35c51SBrandon Wyman (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT); 2358da35c51SBrandon Wyman // STATUS_INPUT fault bits ... on. 2368da35c51SBrandon Wyman statusInputValue = 0x38; 237*6710ba2cSBrandon Wyman // STATUS_MFR, STATUS_CML, and STATUS_VOUT don't care 2388da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue, statusInputValue); 2393f1242f3SBrandon Wyman psu2.analyze(); 2403f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2413f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), true); 242f07bc797SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), true); 2433f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 2443f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), true); 24585c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 246*6710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 2473f1242f3SBrandon Wyman 2483f1242f3SBrandon Wyman // STATUS_WORD MFR fault. 249f07bc797SBrandon Wyman // First need it to return good status, then the fault 2508da35c51SBrandon Wyman statusWordValue = 0; 2518da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 2523f1242f3SBrandon Wyman psu2.analyze(); 2538da35c51SBrandon Wyman // Now STATUS_WORD with MFR fault bit on. 2548da35c51SBrandon Wyman statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 2558da35c51SBrandon Wyman // STATUS_INPUT fault bits ... don't care. 2568da35c51SBrandon Wyman statusInputValue = 0; 2578da35c51SBrandon Wyman // STATUS_MFR bits on. 2588da35c51SBrandon Wyman uint8_t statusMFRValue = 0xFF; 259*6710ba2cSBrandon Wyman // STATUS_CML and STATUS_VOUT don't care 2608da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue, statusInputValue, 2618da35c51SBrandon Wyman statusMFRValue); 2623f1242f3SBrandon Wyman psu2.analyze(); 2633f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2643f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), true); 2653f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 2663f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), true); 2673f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 26885c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 269*6710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 2703f1242f3SBrandon Wyman 2713f1242f3SBrandon Wyman // Ignore Temperature fault. 272f07bc797SBrandon Wyman // First STATUS_WORD with no bits set, then with temperature fault. 2738da35c51SBrandon Wyman statusWordValue = 0; 2748da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 2753f1242f3SBrandon Wyman psu2.analyze(); 2768da35c51SBrandon Wyman // STATUS_WORD with temperature fault bit on. 2778da35c51SBrandon Wyman statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 278*6710ba2cSBrandon Wyman // STATUS_INPUT, STATUS_MFR, STATUS_CML, and STATUS_VOUT fault bits ... 279*6710ba2cSBrandon Wyman // don't care. 2808da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 2813f1242f3SBrandon Wyman psu2.analyze(); 2823f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2833f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 2843f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 2853f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 2863f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 28785c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 288*6710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 28985c7bf41SBrandon Wyman 29085c7bf41SBrandon Wyman // CML fault 29185c7bf41SBrandon Wyman // First STATUS_WORD wit no bits set, then with CML fault. 2928da35c51SBrandon Wyman statusWordValue = 0; 2938da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 29485c7bf41SBrandon Wyman psu2.analyze(); 2958da35c51SBrandon Wyman // STATUS_WORD with CML fault bit on. 2968da35c51SBrandon Wyman statusWordValue = (status_word::CML_FAULT); 2978da35c51SBrandon Wyman // STATUS_INPUT fault bits ... don't care. 2988da35c51SBrandon Wyman statusInputValue = 0; 2998da35c51SBrandon Wyman // STATUS_MFR don't care 3008da35c51SBrandon Wyman statusMFRValue = 0; 30185c7bf41SBrandon Wyman // Turn on STATUS_CML fault bit(s) 3028da35c51SBrandon Wyman uint8_t statusCMLValue = 0xFF; 303*6710ba2cSBrandon Wyman // STATUS_VOUT don't care 3048da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue, statusInputValue, 3058da35c51SBrandon Wyman statusMFRValue, statusCMLValue); 30685c7bf41SBrandon Wyman psu2.analyze(); 30785c7bf41SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 30885c7bf41SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), true); 30985c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 31085c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 31185c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 31285c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), true); 313*6710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 314*6710ba2cSBrandon Wyman 315*6710ba2cSBrandon Wyman // VOUT_OV_FAULT fault 316*6710ba2cSBrandon Wyman // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault. 317*6710ba2cSBrandon Wyman statusWordValue = 0; 318*6710ba2cSBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 319*6710ba2cSBrandon Wyman psu2.analyze(); 320*6710ba2cSBrandon Wyman // STATUS_WORD with VOUT/VOUT_OV fault. 321*6710ba2cSBrandon Wyman statusWordValue = 322*6710ba2cSBrandon Wyman ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT)); 323*6710ba2cSBrandon Wyman // STATUS_INPUT fault bits ... don't care. 324*6710ba2cSBrandon Wyman statusInputValue = 0; 325*6710ba2cSBrandon Wyman // STATUS_MFR don't care 326*6710ba2cSBrandon Wyman statusMFRValue = 0; 327*6710ba2cSBrandon Wyman // STATUS_CML don't care 328*6710ba2cSBrandon Wyman statusCMLValue = 0; 329*6710ba2cSBrandon Wyman // Turn on STATUS_VOUT fault bit(s) 330*6710ba2cSBrandon Wyman uint8_t statusVOUTValue = 0xA0; 331*6710ba2cSBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue, statusInputValue, 332*6710ba2cSBrandon Wyman statusMFRValue, statusCMLValue, statusVOUTValue); 333*6710ba2cSBrandon Wyman psu2.analyze(); 334*6710ba2cSBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 335*6710ba2cSBrandon Wyman EXPECT_EQ(psu2.isFaulted(), true); 336*6710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 337*6710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 338*6710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 339*6710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 340*6710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), true); 3413f1242f3SBrandon Wyman 3423f1242f3SBrandon Wyman // Ignore fan fault 3438da35c51SBrandon Wyman // First STATUS_WORD with no bits set, then with fan 3448da35c51SBrandon Wyman // fault. 3458da35c51SBrandon Wyman statusWordValue = 0; 3468da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 3473f1242f3SBrandon Wyman psu2.analyze(); 3488da35c51SBrandon Wyman statusWordValue = (status_word::FAN_FAULT); 349*6710ba2cSBrandon Wyman // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT: Don't care if 350*6710ba2cSBrandon Wyman // bits set or not. 3518da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 3523f1242f3SBrandon Wyman psu2.analyze(); 3533f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 3543f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 3553f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 3563f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 3573f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 35885c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 359*6710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 3603f1242f3SBrandon Wyman 3613f1242f3SBrandon Wyman // TODO: ReadFailure 3623f1242f3SBrandon Wyman } 3633f1242f3SBrandon Wyman 36459a35793SBrandon Wyman TEST_F(PowerSupplyTests, OnOffConfig) 36559a35793SBrandon Wyman { 36659a35793SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 36759a35793SBrandon Wyman uint8_t data = 0x15; 36859a35793SBrandon Wyman 36959a35793SBrandon Wyman // Test where PSU is NOT present 37059a35793SBrandon Wyman try 37159a35793SBrandon Wyman { 372681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 373681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName}; 374681b2a36SB. J. Wyman 3753ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 3763ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 377681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0)); 37859a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 379681b2a36SB. J. Wyman // Constructor should set initial presence, default read returns 0. 38059a35793SBrandon Wyman // If it is not present, I should not be trying to write to it. 38159a35793SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0); 38259a35793SBrandon Wyman psu.onOffConfig(data); 38359a35793SBrandon Wyman } 38459a35793SBrandon Wyman catch (...) 3850c9a33d6SAdriana Kobylak {} 38659a35793SBrandon Wyman 38759a35793SBrandon Wyman // Test where PSU is present 38859a35793SBrandon Wyman try 38959a35793SBrandon Wyman { 390681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 391681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName}; 3923ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 3933ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 394681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(1)); 39559a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 396681b2a36SB. J. Wyman // TODO: expect setPresence call? 397681b2a36SB. J. Wyman // updatePresence() private function reads gpio, called by analyze(). 398681b2a36SB. J. Wyman psu.analyze(); 39959a35793SBrandon Wyman // TODO: ???should I check the filename? 40059a35793SBrandon Wyman EXPECT_CALL(mockPMBus, 40159a35793SBrandon Wyman writeBinary(_, ElementsAre(0x15), Type::HwmonDeviceDebug)) 40259a35793SBrandon Wyman .Times(1); 40359a35793SBrandon Wyman psu.onOffConfig(data); 40459a35793SBrandon Wyman } 40559a35793SBrandon Wyman catch (...) 4060c9a33d6SAdriana Kobylak {} 40759a35793SBrandon Wyman } 40859a35793SBrandon Wyman 4093f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, ClearFaults) 4103f1242f3SBrandon Wyman { 4113f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 412681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, PSUGPIOLineName}; 4133ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 4143ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 415681b2a36SB. J. Wyman // GPIO read return 1 to indicate present. 416681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(1)); 417681b2a36SB. J. Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 4188da35c51SBrandon Wyman // Presence change from missing to present will trigger in1_input read in 4198da35c51SBrandon Wyman // an attempt to get CLEAR_FAULTS called. 4208da35c51SBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(206000)); 4218da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 4228da35c51SBrandon Wyman uint16_t statusWordValue = 0; 4238da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 424681b2a36SB. J. Wyman psu.analyze(); 4253f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 4263f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 4273f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 4283f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 4293f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 43085c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 431*6710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 432f07bc797SBrandon Wyman // STATUS_WORD with fault bits galore! 4338da35c51SBrandon Wyman statusWordValue = 0xFFFF; 434f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 4358da35c51SBrandon Wyman uint8_t statusInputValue = 0xFF; 436f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 4378da35c51SBrandon Wyman uint8_t statusMFRValue = 0xFF; 43885c7bf41SBrandon Wyman // STATUS_CML with bits on. 4398da35c51SBrandon Wyman uint8_t statusCMLValue = 0xFF; 440*6710ba2cSBrandon Wyman // STATUS_VOUT with bits on. 441*6710ba2cSBrandon Wyman uint8_t statusVOUTValue = 0xFF; 4428da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue, statusInputValue, 443*6710ba2cSBrandon Wyman statusMFRValue, statusCMLValue, statusVOUTValue); 4443f1242f3SBrandon Wyman psu.analyze(); 4453f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 4463f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 4473f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 4483f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 4493f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 45085c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), true); 451*6710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 4523c208464SBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_input", _)) 4533c208464SBrandon Wyman .Times(1) 4543c208464SBrandon Wyman .WillOnce(Return(209000)); 4553f1242f3SBrandon Wyman psu.clearFaults(); 4563f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 4573f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 4583f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 4593f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 4603f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 46185c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 462*6710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 463681b2a36SB. J. Wyman 464681b2a36SB. J. Wyman // TODO: Faults clear on missing/present? 4653f1242f3SBrandon Wyman } 4663f1242f3SBrandon Wyman 4673f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory) 4683f1242f3SBrandon Wyman { 4693f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 4701d7a7df8SBrandon Wyman 4711d7a7df8SBrandon Wyman try 4721d7a7df8SBrandon Wyman { 473681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 4741d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 4751d7a7df8SBrandon Wyman // If it is not present, I should not be trying to read a string 4761d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).Times(0); 4771d7a7df8SBrandon Wyman psu.updateInventory(); 4781d7a7df8SBrandon Wyman } 4791d7a7df8SBrandon Wyman catch (...) 4801d7a7df8SBrandon Wyman { 4811d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 4821d7a7df8SBrandon Wyman } 4831d7a7df8SBrandon Wyman 4841d7a7df8SBrandon Wyman try 4851d7a7df8SBrandon Wyman { 486681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, PSUGPIOLineName}; 4873ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 4883ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 489681b2a36SB. J. Wyman // GPIO read return 1 to indicate present. 490681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 491681b2a36SB. J. Wyman psu.analyze(); 4921d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 4931d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return("")); 4943f1242f3SBrandon Wyman psu.updateInventory(); 4951d7a7df8SBrandon Wyman 4963c530fbdSBrandon Wyman #if IBM_VPD 4971d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)) 4981d7a7df8SBrandon Wyman .WillOnce(Return("CCIN")) 4991d7a7df8SBrandon Wyman .WillOnce(Return("PN3456")) 5001d7a7df8SBrandon Wyman .WillOnce(Return("FN3456")) 5011d7a7df8SBrandon Wyman .WillOnce(Return("HEADER")) 5021d7a7df8SBrandon Wyman .WillOnce(Return("SN3456")) 5031d7a7df8SBrandon Wyman .WillOnce(Return("FW3456")); 5043c530fbdSBrandon Wyman #endif 5051d7a7df8SBrandon Wyman psu.updateInventory(); 5061d7a7df8SBrandon Wyman // TODO: D-Bus mocking to verify values stored on D-Bus (???) 5071d7a7df8SBrandon Wyman } 5081d7a7df8SBrandon Wyman catch (...) 5091d7a7df8SBrandon Wyman { 5101d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 5111d7a7df8SBrandon Wyman } 5123f1242f3SBrandon Wyman } 5133f1242f3SBrandon Wyman 5143f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent) 5153f1242f3SBrandon Wyman { 5163f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 517681b2a36SB. J. Wyman 518681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 5193ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 5203ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 5213f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 5223f1242f3SBrandon Wyman 523681b2a36SB. J. Wyman // Change GPIO read to return 1 to indicate present. 524681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 525681b2a36SB. J. Wyman psu.analyze(); 526681b2a36SB. J. Wyman EXPECT_EQ(psu.isPresent(), true); 5273f1242f3SBrandon Wyman } 5283f1242f3SBrandon Wyman 5293f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted) 5303f1242f3SBrandon Wyman { 5313f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 532681b2a36SB. J. Wyman 533681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, PSUGPIOLineName}; 5343ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 5353ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 536681b2a36SB. J. Wyman // Always return 1 to indicate present. 537681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 538681b2a36SB. J. Wyman psu.analyze(); 5393f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 5403f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 541f07bc797SBrandon Wyman // STATUS_WORD with fault bits on. 5428da35c51SBrandon Wyman uint16_t statusWordValue = 0xFFFF; 543f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 5448da35c51SBrandon Wyman uint8_t statusInputValue = 0xFF; 545f07bc797SBrandon Wyman // STATUS_MFR_SPECIFIC with faults bits on. 5468da35c51SBrandon Wyman uint8_t statusMFRValue = 0xFF; 54785c7bf41SBrandon Wyman // STATUS_CML with faults bits on. 5488da35c51SBrandon Wyman uint8_t statusCMLValue = 0xFF; 549*6710ba2cSBrandon Wyman // STATUS_VOUT with fault bits on. 550*6710ba2cSBrandon Wyman uint8_t statusVOUTValue = 0xFF; 5518da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue, statusInputValue, 552*6710ba2cSBrandon Wyman statusMFRValue, statusCMLValue, statusVOUTValue); 5533f1242f3SBrandon Wyman psu.analyze(); 5543f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 5553f1242f3SBrandon Wyman } 5563f1242f3SBrandon Wyman 5573f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasInputFault) 5583f1242f3SBrandon Wyman { 5593f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 560681b2a36SB. J. Wyman 561681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 5623ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 5633ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 564681b2a36SB. J. Wyman // Always return 1 to indicate present. 565681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 566681b2a36SB. J. Wyman psu.analyze(); 5673f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 5683f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 5698da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 5708da35c51SBrandon Wyman uint16_t statusWordValue = 0; 5718da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 5723f1242f3SBrandon Wyman psu.analyze(); 5733f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 574f07bc797SBrandon Wyman // STATUS_WORD with input fault/warn on. 5758da35c51SBrandon Wyman statusWordValue = (status_word::INPUT_FAULT_WARN); 576f07bc797SBrandon Wyman // STATUS_INPUT with an input fault bit on. 5778da35c51SBrandon Wyman uint8_t statusInputValue = 0x80; 578*6710ba2cSBrandon Wyman // STATUS_MFR, STATUS_CML, and STATUS_VOUT don't care. 5798da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue, statusInputValue); 5803f1242f3SBrandon Wyman psu.analyze(); 5813f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 582f07bc797SBrandon Wyman // STATUS_WORD with no bits on. 5838da35c51SBrandon Wyman statusWordValue = 0; 5848da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 5853f1242f3SBrandon Wyman psu.analyze(); 5863f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 5873f1242f3SBrandon Wyman } 5883f1242f3SBrandon Wyman 5893f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault) 5903f1242f3SBrandon Wyman { 5913f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 592681b2a36SB. J. Wyman 593681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 5943ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 5953ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 596681b2a36SB. J. Wyman // Always return 1 to indicate present. 597681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 598681b2a36SB. J. Wyman psu.analyze(); 5993f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 6003f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 601f07bc797SBrandon Wyman // First return STATUS_WORD with no bits on. 6028da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 6038da35c51SBrandon Wyman uint16_t statusWordValue = 0; 6048da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 6053f1242f3SBrandon Wyman psu.analyze(); 6063f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 607f07bc797SBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 6088da35c51SBrandon Wyman statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 609f07bc797SBrandon Wyman // STATUS_INPUT don't care 6108da35c51SBrandon Wyman uint8_t statusInputValue = 0; 611f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 6128da35c51SBrandon Wyman uint8_t statusMFRValue = 0xFF; 613*6710ba2cSBrandon Wyman // STATUS_CML and STATUS_VOUT don't care. 6148da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue, statusInputValue, 6158da35c51SBrandon Wyman statusMFRValue); 6163f1242f3SBrandon Wyman psu.analyze(); 6173f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 618f07bc797SBrandon Wyman // Back to no bits on in STATUS_WORD 6198da35c51SBrandon Wyman statusWordValue = 0; 6208da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 6213f1242f3SBrandon Wyman psu.analyze(); 6223f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 6233f1242f3SBrandon Wyman } 6243f1242f3SBrandon Wyman 6253f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault) 6263f1242f3SBrandon Wyman { 6273f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 628681b2a36SB. J. Wyman 629681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 6303ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 6313ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 632681b2a36SB. J. Wyman // Always return 1 to indicate present. 633681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 634681b2a36SB. J. Wyman psu.analyze(); 6353f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 6363f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 6378da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 6388da35c51SBrandon Wyman uint16_t statusWordValue = 0; 6398da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 6403f1242f3SBrandon Wyman psu.analyze(); 6413f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 642f07bc797SBrandon Wyman // Turn fault on. 6438da35c51SBrandon Wyman statusWordValue = (status_word::VIN_UV_FAULT); 64485c7bf41SBrandon Wyman // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by 64585c7bf41SBrandon Wyman // Figure 16, and assume bits on in STATUS_INPUT. 6468da35c51SBrandon Wyman uint8_t statusInputValue = 0x18; 647*6710ba2cSBrandon Wyman // STATUS_MFR, STATUS_CML, and STATUS_VOUT don't care. 6488da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue, statusInputValue); 6493f1242f3SBrandon Wyman psu.analyze(); 6503f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 651f07bc797SBrandon Wyman // Back to no fault bits on in STATUS_WORD 6528da35c51SBrandon Wyman statusWordValue = 0; 6538da35c51SBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 6543f1242f3SBrandon Wyman psu.analyze(); 6553f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 6563f1242f3SBrandon Wyman } 657*6710ba2cSBrandon Wyman 658*6710ba2cSBrandon Wyman TEST_F(PowerSupplyTests, HasVoutOVFault) 659*6710ba2cSBrandon Wyman { 660*6710ba2cSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 661*6710ba2cSBrandon Wyman 662*6710ba2cSBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x69, PSUGPIOLineName}; 663*6710ba2cSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 664*6710ba2cSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 665*6710ba2cSBrandon Wyman // Always return 1 to indicate present. 666*6710ba2cSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 667*6710ba2cSBrandon Wyman psu.analyze(); 668*6710ba2cSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 669*6710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 670*6710ba2cSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 671*6710ba2cSBrandon Wyman uint16_t statusWordValue = 0; 672*6710ba2cSBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 673*6710ba2cSBrandon Wyman psu.analyze(); 674*6710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 675*6710ba2cSBrandon Wyman // Turn fault on. 676*6710ba2cSBrandon Wyman statusWordValue = (status_word::VOUT_OV_FAULT); 677*6710ba2cSBrandon Wyman // STATUS_INPUT don't care. 678*6710ba2cSBrandon Wyman uint8_t statusInputValue = 0; 679*6710ba2cSBrandon Wyman // STATUS_MFR don't care. 680*6710ba2cSBrandon Wyman uint8_t statusMFRValue = 0; 681*6710ba2cSBrandon Wyman // STATUS_CML don't care. 682*6710ba2cSBrandon Wyman uint8_t statusCMLValue = 0; 683*6710ba2cSBrandon Wyman // STATUS_VOUT fault bit(s) 684*6710ba2cSBrandon Wyman uint8_t statusVOUTValue = 0x80; 685*6710ba2cSBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue, statusInputValue, 686*6710ba2cSBrandon Wyman statusMFRValue, statusCMLValue, statusVOUTValue); 687*6710ba2cSBrandon Wyman psu.analyze(); 688*6710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 689*6710ba2cSBrandon Wyman // Back to no fault bits on in STATUS_WORD 690*6710ba2cSBrandon Wyman statusWordValue = 0; 691*6710ba2cSBrandon Wyman setPMBusExpectations(mockPMBus, statusWordValue); 692*6710ba2cSBrandon Wyman psu.analyze(); 693*6710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 694*6710ba2cSBrandon Wyman } 695