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