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