13f1242f3SBrandon Wyman #include "../power_supply.hpp" 2c3324424SBrandon Wyman #include "../record_manager.hpp" 33f1242f3SBrandon Wyman #include "mock.hpp" 43f1242f3SBrandon Wyman 53f1242f3SBrandon Wyman #include <xyz/openbmc_project/Common/Device/error.hpp> 63f1242f3SBrandon Wyman #include <xyz/openbmc_project/Common/error.hpp> 73f1242f3SBrandon Wyman 83f1242f3SBrandon Wyman #include <gmock/gmock.h> 93f1242f3SBrandon Wyman #include <gtest/gtest.h> 103f1242f3SBrandon Wyman 113f1242f3SBrandon Wyman using namespace phosphor::power::psu; 123f1242f3SBrandon Wyman using namespace phosphor::pmbus; 133f1242f3SBrandon Wyman 143f1242f3SBrandon Wyman using ::testing::_; 1559a35793SBrandon Wyman using ::testing::Args; 163f1242f3SBrandon Wyman using ::testing::Assign; 173f1242f3SBrandon Wyman using ::testing::DoAll; 1859a35793SBrandon Wyman using ::testing::ElementsAre; 1959a35793SBrandon Wyman using ::testing::NotNull; 203f1242f3SBrandon Wyman using ::testing::Return; 213f1242f3SBrandon Wyman using ::testing::StrEq; 223f1242f3SBrandon Wyman 233f1242f3SBrandon Wyman static auto PSUInventoryPath = "/xyz/bmc/inv/sys/chassis/board/powersupply0"; 24681b2a36SB. J. Wyman static auto PSUGPIOLineName = "presence-ps0"; 25*9464c429SGeorge Liu static auto isPowerOn = []() { return true; }; 263f1242f3SBrandon Wyman 27b654c619SBrandon Wyman struct PMBusExpectations 28b654c619SBrandon Wyman { 29b654c619SBrandon Wyman uint16_t statusWordValue{0x0000}; 30b654c619SBrandon Wyman uint8_t statusInputValue{0x00}; 31b654c619SBrandon Wyman uint8_t statusMFRValue{0x00}; 32b654c619SBrandon Wyman uint8_t statusCMLValue{0x00}; 33b654c619SBrandon Wyman uint8_t statusVOUTValue{0x00}; 34b10b3be0SBrandon Wyman uint8_t statusIOUTValue{0x00}; 357ee4d7e4SBrandon Wyman uint8_t statusFans12Value{0x00}; 3696893a46SBrandon Wyman uint8_t statusTempValue{0x00}; 37b654c619SBrandon Wyman }; 38b654c619SBrandon Wyman 398da35c51SBrandon Wyman // Helper function to setup expectations for various STATUS_* commands 40b654c619SBrandon Wyman void setPMBusExpectations(MockedPMBus& mockPMBus, 41b654c619SBrandon Wyman const PMBusExpectations& expectations) 428da35c51SBrandon Wyman { 4332453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _, _)) 448da35c51SBrandon Wyman .Times(1) 45b654c619SBrandon Wyman .WillOnce(Return(expectations.statusWordValue)); 468da35c51SBrandon Wyman 47b654c619SBrandon Wyman if (expectations.statusWordValue != 0) 488da35c51SBrandon Wyman { 498da35c51SBrandon Wyman // If fault bits are on in STATUS_WORD, there will also be a read of 5096893a46SBrandon Wyman // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT (page 0), and 5196893a46SBrandon Wyman // STATUS_TEMPERATURE. 5232453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _, _)) 538da35c51SBrandon Wyman .Times(1) 54b654c619SBrandon Wyman .WillOnce(Return(expectations.statusInputValue)); 5532453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _, _)) 568da35c51SBrandon Wyman .Times(1) 57b654c619SBrandon Wyman .WillOnce(Return(expectations.statusMFRValue)); 5832453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _, _)) 598da35c51SBrandon Wyman .Times(1) 60b654c619SBrandon Wyman .WillOnce(Return(expectations.statusCMLValue)); 616710ba2cSBrandon Wyman // Page will need to be set to 0 to read STATUS_VOUT. 626710ba2cSBrandon Wyman EXPECT_CALL(mockPMBus, insertPageNum(STATUS_VOUT, 0)) 636710ba2cSBrandon Wyman .Times(1) 646710ba2cSBrandon Wyman .WillOnce(Return("status0_vout")); 6532453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read("status0_vout", _, _)) 666710ba2cSBrandon Wyman .Times(1) 67b654c619SBrandon Wyman .WillOnce(Return(expectations.statusVOUTValue)); 6832453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_IOUT, _, _)) 69b10b3be0SBrandon Wyman .Times(1) 70b10b3be0SBrandon Wyman .WillOnce(Return(expectations.statusIOUTValue)); 7132453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_FANS_1_2, _, _)) 727ee4d7e4SBrandon Wyman .Times(1) 737ee4d7e4SBrandon Wyman .WillOnce(Return(expectations.statusFans12Value)); 7432453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_TEMPERATURE, _, _)) 7596893a46SBrandon Wyman .Times(1) 7696893a46SBrandon Wyman .WillOnce(Return(expectations.statusTempValue)); 778da35c51SBrandon Wyman } 788da35c51SBrandon Wyman } 798da35c51SBrandon Wyman 803f1242f3SBrandon Wyman class PowerSupplyTests : public ::testing::Test 813f1242f3SBrandon Wyman { 823f1242f3SBrandon Wyman public: 833f1242f3SBrandon Wyman PowerSupplyTests() : 843f1242f3SBrandon Wyman mockedUtil(reinterpret_cast<const MockedUtil&>(getUtils())) 853f1242f3SBrandon Wyman { 863f1242f3SBrandon Wyman ON_CALL(mockedUtil, getPresence(_, _)).WillByDefault(Return(false)); 873f1242f3SBrandon Wyman } 883f1242f3SBrandon Wyman 893f1242f3SBrandon Wyman ~PowerSupplyTests() override 903f1242f3SBrandon Wyman { 913f1242f3SBrandon Wyman freeUtils(); 923f1242f3SBrandon Wyman } 933f1242f3SBrandon Wyman 943f1242f3SBrandon Wyman const MockedUtil& mockedUtil; 953f1242f3SBrandon Wyman }; 963f1242f3SBrandon Wyman 97391a0690SBrandon Wyman // Helper function for when a power supply goes from missing to present. 98391a0690SBrandon Wyman void setMissingToPresentExpects(MockedPMBus& pmbus, const MockedUtil& util) 99391a0690SBrandon Wyman { 100391a0690SBrandon Wyman // Call to analyze() will update to present, that will trigger updating 101391a0690SBrandon Wyman // to the correct/latest HWMON directory, in case it changes. 102391a0690SBrandon Wyman EXPECT_CALL(pmbus, findHwmonDir()); 103391a0690SBrandon Wyman // Presence change from missing to present will trigger write to 104391a0690SBrandon Wyman // ON_OFF_CONFIG. 105391a0690SBrandon Wyman EXPECT_CALL(pmbus, writeBinary(ON_OFF_CONFIG, _, _)); 106391a0690SBrandon Wyman // Presence change from missing to present will trigger in1_input read 107391a0690SBrandon Wyman // in an attempt to get CLEAR_FAULTS called. 10882affd94SBrandon Wyman // This READ_VIN for CLEAR_FAULTS does not check the returned value. 1093225a45cSBrandon Wyman EXPECT_CALL(pmbus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 1103225a45cSBrandon Wyman // The call for clearing faults includes clearing VIN_UV fault. 1113225a45cSBrandon Wyman // The voltage defaults to 0, the first call to analyze should update the 1123225a45cSBrandon Wyman // voltage to the current reading, triggering clearing VIN_UV fault(s) 1133225a45cSBrandon Wyman // due to below minimum to within range voltage. 1143225a45cSBrandon Wyman EXPECT_CALL(pmbus, read("in1_lcrit_alarm", _, _)) 11582affd94SBrandon Wyman .Times(2) 1163225a45cSBrandon Wyman .WillRepeatedly(Return(1)); 117391a0690SBrandon Wyman // Missing/present call will update Presence in inventory. 118391a0690SBrandon Wyman EXPECT_CALL(util, setPresence(_, _, true, _)); 119391a0690SBrandon Wyman } 120391a0690SBrandon Wyman 1213f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Constructor) 1223f1242f3SBrandon Wyman { 1233f1242f3SBrandon Wyman /** 1243f1242f3SBrandon Wyman * @param[in] invpath - String for inventory path to use 1253f1242f3SBrandon Wyman * @param[in] i2cbus - The bus number this power supply is on 1263f1242f3SBrandon Wyman * @param[in] i2caddr - The 16-bit I2C address of the power supply 127681b2a36SB. J. Wyman * @param[in] gpioLineName - The string for the gpio-line-name to read for 128681b2a36SB. J. Wyman * presence. 129681b2a36SB. J. Wyman * @param[in] bindDelay - Time in milliseconds to delay binding the device 130681b2a36SB. J. Wyman * driver after seeing the presence line go active. 1313f1242f3SBrandon Wyman */ 1323f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1331d7a7df8SBrandon Wyman 1341d7a7df8SBrandon Wyman // Try where inventory path is empty, constructor should fail. 1351d7a7df8SBrandon Wyman try 1361d7a7df8SBrandon Wyman { 137c3324424SBrandon Wyman auto psu = std::make_unique<PowerSupply>(bus, "", 3, 0x68, "ibm-cffps", 138*9464c429SGeorge Liu PSUGPIOLineName, isPowerOn); 1391d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have reached this line."; 1401d7a7df8SBrandon Wyman } 1411d7a7df8SBrandon Wyman catch (const std::invalid_argument& e) 1421d7a7df8SBrandon Wyman { 1431d7a7df8SBrandon Wyman EXPECT_STREQ(e.what(), "Invalid empty inventoryPath"); 1441d7a7df8SBrandon Wyman } 1451d7a7df8SBrandon Wyman catch (...) 1461d7a7df8SBrandon Wyman { 1471d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 1481d7a7df8SBrandon Wyman } 1491d7a7df8SBrandon Wyman 150681b2a36SB. J. Wyman // TODO: Try invalid i2c address? 151681b2a36SB. J. Wyman 152681b2a36SB. J. Wyman // Try where gpioLineName is empty. 1531d7a7df8SBrandon Wyman try 1541d7a7df8SBrandon Wyman { 155c3324424SBrandon Wyman auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, 156*9464c429SGeorge Liu "ibm-cffps", "", isPowerOn); 157681b2a36SB. J. Wyman ADD_FAILURE() 158681b2a36SB. J. Wyman << "Should not have reached this line. Invalid gpioLineName."; 159681b2a36SB. J. Wyman } 160681b2a36SB. J. Wyman catch (const std::invalid_argument& e) 161681b2a36SB. J. Wyman { 162681b2a36SB. J. Wyman EXPECT_STREQ(e.what(), "Invalid empty gpioLineName"); 163681b2a36SB. J. Wyman } 164681b2a36SB. J. Wyman catch (...) 165681b2a36SB. J. Wyman { 166681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 167681b2a36SB. J. Wyman } 168681b2a36SB. J. Wyman 169681b2a36SB. J. Wyman // Test with valid arguments 170681b2a36SB. J. Wyman // NOT using D-Bus inventory path for presence. 171681b2a36SB. J. Wyman try 172681b2a36SB. J. Wyman { 173681b2a36SB. J. Wyman auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, 174*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, 175*9464c429SGeorge Liu isPowerOn); 1763f1242f3SBrandon Wyman 1773f1242f3SBrandon Wyman EXPECT_EQ(psu->isPresent(), false); 1783f1242f3SBrandon Wyman EXPECT_EQ(psu->isFaulted(), false); 1798da35c51SBrandon Wyman EXPECT_EQ(psu->hasCommFault(), false); 1803f1242f3SBrandon Wyman EXPECT_EQ(psu->hasInputFault(), false); 1813f1242f3SBrandon Wyman EXPECT_EQ(psu->hasMFRFault(), false); 1823f1242f3SBrandon Wyman EXPECT_EQ(psu->hasVINUVFault(), false); 1836710ba2cSBrandon Wyman EXPECT_EQ(psu->hasVoutOVFault(), false); 184b10b3be0SBrandon Wyman EXPECT_EQ(psu->hasIoutOCFault(), false); 1852cf46945SBrandon Wyman EXPECT_EQ(psu->hasVoutUVFault(), false); 1867ee4d7e4SBrandon Wyman EXPECT_EQ(psu->hasFanFault(), false); 18796893a46SBrandon Wyman EXPECT_EQ(psu->hasTempFault(), false); 1882916ea52SBrandon Wyman EXPECT_EQ(psu->hasPgoodFault(), false); 18939ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPSKillFault(), false); 19039ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPS12VcsFault(), false); 19139ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPSCS12VFault(), false); 1923f1242f3SBrandon Wyman } 1931d7a7df8SBrandon Wyman catch (...) 1941d7a7df8SBrandon Wyman { 1951d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 1961d7a7df8SBrandon Wyman } 197681b2a36SB. J. Wyman 198681b2a36SB. J. Wyman // Test with valid arguments 199681b2a36SB. J. Wyman // TODO: Using D-Bus inventory path for presence. 200681b2a36SB. J. Wyman try 201681b2a36SB. J. Wyman { 202681b2a36SB. J. Wyman // FIXME: How do I get that presenceGPIO.read() in the startup to throw 203681b2a36SB. J. Wyman // an exception? 204681b2a36SB. J. Wyman 205681b2a36SB. J. Wyman // EXPECT_CALL(mockedUtil, getPresence(_, 206681b2a36SB. J. Wyman // StrEq(PSUInventoryPath))) 207681b2a36SB. J. Wyman // .Times(1); 208681b2a36SB. J. Wyman } 209681b2a36SB. J. Wyman catch (...) 210681b2a36SB. J. Wyman { 211681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 212681b2a36SB. J. Wyman } 2131d7a7df8SBrandon Wyman } 2143f1242f3SBrandon Wyman 2153f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Analyze) 2163f1242f3SBrandon Wyman { 2173f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2183f1242f3SBrandon Wyman 219b654c619SBrandon Wyman { 220681b2a36SB. J. Wyman // If I default to reading the GPIO, I will NOT expect a call to 221681b2a36SB. J. Wyman // getPresence(). 222681b2a36SB. J. Wyman 223*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, 224*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 2253ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 2263ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 227681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0)); 228681b2a36SB. J. Wyman 2293f1242f3SBrandon Wyman psu.analyze(); 2303f1242f3SBrandon Wyman // By default, nothing should change. 2313f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 2323f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 2333f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 2343f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 2353f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 23685c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 2376710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 238b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 2392cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 2407ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 24196893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 2422916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 24339ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 24439ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 24539ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 246b654c619SBrandon Wyman } 2473f1242f3SBrandon Wyman 248*9464c429SGeorge Liu PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, 249*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 250681b2a36SB. J. Wyman // In order to get the various faults tested, the power supply needs to 251681b2a36SB. J. Wyman // be present in order to read from the PMBus device(s). 2523ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO2 = 2533ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO()); 25406ca4590SBrandon Wyman // Always return 1 to indicate present. 25506ca4590SBrandon Wyman // Each analyze() call will trigger a read of the presence GPIO. 25606ca4590SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO2, read()).WillRepeatedly(Return(1)); 257681b2a36SB. J. Wyman EXPECT_EQ(psu2.isPresent(), false); 2583f1242f3SBrandon Wyman 2593f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus()); 260391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 261ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 262ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 263ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 264ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 265ae35ac5dSBrandon Wyman .Times(1) 266ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 267b654c619SBrandon Wyman 268b654c619SBrandon Wyman // STATUS_WORD INPUT fault. 269b654c619SBrandon Wyman { 270b654c619SBrandon Wyman // Start with STATUS_WORD 0x0000. Powered on, no faults. 271b654c619SBrandon Wyman // Set expectations for a no fault 272b654c619SBrandon Wyman PMBusExpectations expectations; 273b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 27482affd94SBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 27582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 27682affd94SBrandon Wyman .Times(1) 27782affd94SBrandon Wyman .WillOnce(Return("206000")); 2783f1242f3SBrandon Wyman psu2.analyze(); 2793f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2803f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 2813f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 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); 2943f1242f3SBrandon Wyman 295b654c619SBrandon Wyman // Update expectations for STATUS_WORD input fault/warn 29696893a46SBrandon Wyman // STATUS_INPUT fault bits ... on. 297b654c619SBrandon Wyman expectations.statusWordValue = (status_word::INPUT_FAULT_WARN); 2983225a45cSBrandon Wyman // IIN_OC fault. 2993225a45cSBrandon Wyman expectations.statusInputValue = 0x04; 300c2906f47SBrandon Wyman 301c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 302c2906f47SBrandon Wyman { 303b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 30482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 30582affd94SBrandon Wyman .Times(1) 30682affd94SBrandon Wyman .WillOnce(Return("207000")); 3073f1242f3SBrandon Wyman psu2.analyze(); 3083f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 309c2906f47SBrandon Wyman // Should not be faulted until it reaches the deglitch limit. 310c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 311c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT); 3123f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 3133f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 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 } 325c2906f47SBrandon Wyman } 326c2906f47SBrandon Wyman 32732453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 3283225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 3293225a45cSBrandon Wyman .Times(1) 3303225a45cSBrandon Wyman .WillOnce(Return(1)); 331c2906f47SBrandon Wyman psu2.clearFaults(); 3323f1242f3SBrandon Wyman 3333f1242f3SBrandon Wyman // STATUS_WORD INPUT/UV fault. 334b654c619SBrandon Wyman { 3353f1242f3SBrandon Wyman // First need it to return good status, then the fault 336b654c619SBrandon Wyman PMBusExpectations expectations; 337b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 33882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 33982affd94SBrandon Wyman .Times(1) 34082affd94SBrandon Wyman .WillOnce(Return("208000")); 3413f1242f3SBrandon Wyman psu2.analyze(); 342c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 343c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 3448da35c51SBrandon Wyman // Now set fault bits in STATUS_WORD 345b654c619SBrandon Wyman expectations.statusWordValue = 3468da35c51SBrandon Wyman (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT); 3478da35c51SBrandon Wyman // STATUS_INPUT fault bits ... on. 3483225a45cSBrandon Wyman expectations.statusInputValue = 0x18; 349c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 350c2906f47SBrandon Wyman { 351b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 35282affd94SBrandon Wyman // Input/UV fault, so voltage should read back low. 35382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 35482affd94SBrandon Wyman .Times(1) 35582affd94SBrandon Wyman .WillOnce(Return("19123")); 3563f1242f3SBrandon Wyman psu2.analyze(); 3573f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 358c2906f47SBrandon Wyman // Only faulted if hit deglitch limit 359c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 360c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT); 361c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), x >= DEGLITCH_LIMIT); 3623f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 36385c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 3646710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 365b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 3662cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 3677ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 36896893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 3692916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 37039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 37139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 37239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 373c2906f47SBrandon Wyman } 37482affd94SBrandon Wyman // Turning VIN_UV fault off causes clearing of faults, causing read of 37582affd94SBrandon Wyman // in1_input as an attempt to get CLEAR_FAULTS called. 37682affd94SBrandon Wyman expectations.statusWordValue = 0; 37782affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 37882affd94SBrandon Wyman // The call to read the voltage 37982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 38082affd94SBrandon Wyman .Times(1) 38182affd94SBrandon Wyman .WillOnce(Return("209000")); 3823225a45cSBrandon Wyman // The call to clear VIN_UV/Off fault(s) 3833225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 38432453e9bSBrandon Wyman .Times(1) 3853225a45cSBrandon Wyman .WillOnce(Return(1)); 38682affd94SBrandon Wyman psu2.analyze(); 38782affd94SBrandon Wyman // Should remain present, no longer be faulted, no input fault, no 38882affd94SBrandon Wyman // VIN_UV fault. Nothing else should change. 38982affd94SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 39082affd94SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 39182affd94SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 39282affd94SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 393b654c619SBrandon Wyman } 3943f1242f3SBrandon Wyman 39532453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 3963225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 3973225a45cSBrandon Wyman .Times(1) 3983225a45cSBrandon Wyman .WillOnce(Return(1)); 399c2906f47SBrandon Wyman psu2.clearFaults(); 400c2906f47SBrandon Wyman 4013f1242f3SBrandon Wyman // STATUS_WORD MFR fault. 402b654c619SBrandon Wyman { 403f07bc797SBrandon Wyman // First need it to return good status, then the fault 404b654c619SBrandon Wyman PMBusExpectations expectations; 405b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 40682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 40782affd94SBrandon Wyman .Times(1) 40882affd94SBrandon Wyman .WillOnce(Return("210000")); 4093f1242f3SBrandon Wyman psu2.analyze(); 4108da35c51SBrandon Wyman // Now STATUS_WORD with MFR fault bit on. 411b654c619SBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 4128da35c51SBrandon Wyman // STATUS_MFR bits on. 413b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 414c2906f47SBrandon Wyman 415c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 416c2906f47SBrandon Wyman { 417b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 41882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 41982affd94SBrandon Wyman .Times(1) 42082affd94SBrandon Wyman .WillOnce(Return("211000")); 4213f1242f3SBrandon Wyman psu2.analyze(); 4223f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 423c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 4243f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 425c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), x >= DEGLITCH_LIMIT); 426c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), x >= DEGLITCH_LIMIT); 427c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 428c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 4293f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 43085c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 4316710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 432b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 4332cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 4347ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 43596893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 4362916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 437c2906f47SBrandon Wyman } 438b654c619SBrandon Wyman } 4393f1242f3SBrandon Wyman 44032453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 4413225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 4423225a45cSBrandon Wyman .Times(1) 4433225a45cSBrandon Wyman .WillOnce(Return(1)); 444c2906f47SBrandon Wyman psu2.clearFaults(); 4453225a45cSBrandon Wyman 44696893a46SBrandon Wyman // Temperature fault. 447b654c619SBrandon Wyman { 448f07bc797SBrandon Wyman // First STATUS_WORD with no bits set, then with temperature fault. 449b654c619SBrandon Wyman PMBusExpectations expectations; 450b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 45182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 45282affd94SBrandon Wyman .Times(1) 45382affd94SBrandon Wyman .WillOnce(Return("212000")); 4543f1242f3SBrandon Wyman psu2.analyze(); 4558da35c51SBrandon Wyman // STATUS_WORD with temperature fault bit on. 456b654c619SBrandon Wyman expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 45796893a46SBrandon Wyman // STATUS_TEMPERATURE with fault bit(s) on. 45896893a46SBrandon Wyman expectations.statusTempValue = 0x10; 459c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 460c2906f47SBrandon Wyman { 461b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 46282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 46382affd94SBrandon Wyman .Times(1) 46482affd94SBrandon Wyman .WillOnce(Return("213000")); 4653f1242f3SBrandon Wyman psu2.analyze(); 4663f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 467c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 4683f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 4693f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 4703f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 47185c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 4726710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 473b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 4742cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 4757ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 476c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), x >= DEGLITCH_LIMIT); 4772916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 47839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 47939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 48039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 481b654c619SBrandon Wyman } 482c2906f47SBrandon Wyman } 48385c7bf41SBrandon Wyman 48432453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 4853225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 4863225a45cSBrandon Wyman .Times(1) 4873225a45cSBrandon Wyman .WillOnce(Return(1)); 488c2906f47SBrandon Wyman psu2.clearFaults(); 4893225a45cSBrandon Wyman 49085c7bf41SBrandon Wyman // CML fault 491b654c619SBrandon Wyman { 49285c7bf41SBrandon Wyman // First STATUS_WORD wit no bits set, then with CML fault. 493b654c619SBrandon Wyman PMBusExpectations expectations; 494b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 49582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 49682affd94SBrandon Wyman .Times(1) 49782affd94SBrandon Wyman .WillOnce(Return("214000")); 49885c7bf41SBrandon Wyman psu2.analyze(); 4998da35c51SBrandon Wyman // STATUS_WORD with CML fault bit on. 500b654c619SBrandon Wyman expectations.statusWordValue = (status_word::CML_FAULT); 50185c7bf41SBrandon Wyman // Turn on STATUS_CML fault bit(s) 502b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 503c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 504c2906f47SBrandon Wyman { 505b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 50682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 50782affd94SBrandon Wyman .Times(1) 50882affd94SBrandon Wyman .WillOnce(Return("215000")); 50985c7bf41SBrandon Wyman psu2.analyze(); 51085c7bf41SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 511c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 512c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), x >= DEGLITCH_LIMIT); 51385c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 51485c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 51585c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 5166710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 517b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 5182cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 5197ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 52096893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 5212916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 52239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 52339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 52439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 525b654c619SBrandon Wyman } 526c2906f47SBrandon Wyman } 5276710ba2cSBrandon Wyman 52832453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 5293225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 5303225a45cSBrandon Wyman .Times(1) 5313225a45cSBrandon Wyman .WillOnce(Return(1)); 532c2906f47SBrandon Wyman psu2.clearFaults(); 5333225a45cSBrandon Wyman 5346710ba2cSBrandon Wyman // VOUT_OV_FAULT fault 535b654c619SBrandon Wyman { 5366710ba2cSBrandon Wyman // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault. 537b654c619SBrandon Wyman PMBusExpectations expectations; 538b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 53982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 54082affd94SBrandon Wyman .Times(1) 54182affd94SBrandon Wyman .WillOnce(Return("216000")); 5426710ba2cSBrandon Wyman psu2.analyze(); 5436710ba2cSBrandon Wyman // STATUS_WORD with VOUT/VOUT_OV fault. 544b654c619SBrandon Wyman expectations.statusWordValue = 5456710ba2cSBrandon Wyman ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT)); 5466710ba2cSBrandon Wyman // Turn on STATUS_VOUT fault bit(s) 547b654c619SBrandon Wyman expectations.statusVOUTValue = 0xA0; 548c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 549c2906f47SBrandon Wyman { 55096893a46SBrandon Wyman // STATUS_TEMPERATURE don't care (default) 551b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 55282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 55382affd94SBrandon Wyman .Times(1) 55482affd94SBrandon Wyman .WillOnce(Return("217000")); 5556710ba2cSBrandon Wyman psu2.analyze(); 5566710ba2cSBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 557c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 5586710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 5596710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 5606710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 5616710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 562c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 5632cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 564b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 5657ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 566b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 567b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 56839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 56939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 57039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 571b10b3be0SBrandon Wyman } 572c2906f47SBrandon Wyman } 573b10b3be0SBrandon Wyman 574b10b3be0SBrandon Wyman // IOUT_OC_FAULT fault 575b10b3be0SBrandon Wyman { 576b10b3be0SBrandon Wyman // First STATUS_WORD with no bits set, then with IOUT_OC fault. 577b10b3be0SBrandon Wyman PMBusExpectations expectations; 578b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 57982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 58082affd94SBrandon Wyman .Times(1) 58182affd94SBrandon Wyman .WillOnce(Return("218000")); 582b10b3be0SBrandon Wyman psu2.analyze(); 583b10b3be0SBrandon Wyman // STATUS_WORD with IOUT_OC fault. 584b10b3be0SBrandon Wyman expectations.statusWordValue = status_word::IOUT_OC_FAULT; 585b10b3be0SBrandon Wyman // Turn on STATUS_IOUT fault bit(s) 586b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0x88; 587c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 588c2906f47SBrandon Wyman { 589b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 59082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 59182affd94SBrandon Wyman .Times(1) 59282affd94SBrandon Wyman .WillOnce(Return("219000")); 593b10b3be0SBrandon Wyman psu2.analyze(); 594b10b3be0SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 595c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 596b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 597b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 598b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 599b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 600b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 601c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 6022cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 6037ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 6042cf46945SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6052cf46945SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 60639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 60739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 60839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 6092cf46945SBrandon Wyman } 610c2906f47SBrandon Wyman } 6112cf46945SBrandon Wyman 6122cf46945SBrandon Wyman // VOUT_UV_FAULT 6132cf46945SBrandon Wyman { 6142cf46945SBrandon Wyman // First STATUS_WORD with no bits set, then with VOUT fault. 6152cf46945SBrandon Wyman PMBusExpectations expectations; 6162cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 61782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 61882affd94SBrandon Wyman .Times(1) 61982affd94SBrandon Wyman .WillOnce(Return("220000")); 6202cf46945SBrandon Wyman psu2.analyze(); 6212cf46945SBrandon Wyman // Change STATUS_WORD to indicate VOUT fault. 6222cf46945SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_FAULT); 6232cf46945SBrandon Wyman // Turn on STATUS_VOUT fault bit(s) 6242cf46945SBrandon Wyman expectations.statusVOUTValue = 0x30; 625c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 626c2906f47SBrandon Wyman { 6272cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 62882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 62982affd94SBrandon Wyman .Times(1) 63082affd94SBrandon Wyman .WillOnce(Return("221000")); 6312cf46945SBrandon Wyman psu2.analyze(); 6322cf46945SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 633c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 6342cf46945SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 6352cf46945SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 6362cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 6372cf46945SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 6382cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 6392cf46945SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 640c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), x >= DEGLITCH_LIMIT); 6417ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 64296893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6432916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 64439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 64539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 64639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 647b654c619SBrandon Wyman } 648c2906f47SBrandon Wyman } 6493f1242f3SBrandon Wyman 6507ee4d7e4SBrandon Wyman // Fan fault 651b654c619SBrandon Wyman { 652b654c619SBrandon Wyman // First STATUS_WORD with no bits set, then with fan fault. 653b654c619SBrandon Wyman PMBusExpectations expectations; 654b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 65582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 65682affd94SBrandon Wyman .Times(1) 65782affd94SBrandon Wyman .WillOnce(Return("222000")); 6583f1242f3SBrandon Wyman psu2.analyze(); 659b654c619SBrandon Wyman expectations.statusWordValue = (status_word::FAN_FAULT); 6607ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with fan 1 warning & fault bits on. 6617ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xA0; 662c2906f47SBrandon Wyman 663c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 664c2906f47SBrandon Wyman { 665b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 66682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 66782affd94SBrandon Wyman .Times(1) 66882affd94SBrandon Wyman .WillOnce(Return("223000")); 6693f1242f3SBrandon Wyman psu2.analyze(); 6703f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 671c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 672c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), x >= DEGLITCH_LIMIT); 6733f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 6743f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 6753f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 67685c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 6776710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 678b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 6792cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 68096893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6812916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 68239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 68339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 68439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 685b654c619SBrandon Wyman } 686c2906f47SBrandon Wyman } 6872916ea52SBrandon Wyman 68806ca4590SBrandon Wyman // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT. 6892cf46945SBrandon Wyman { 6902916ea52SBrandon Wyman // First STATUS_WORD with no bits set. 6912916ea52SBrandon Wyman PMBusExpectations expectations; 6922916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 69382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 69482affd94SBrandon Wyman .Times(1) 69582affd94SBrandon Wyman .WillOnce(Return("123000")); 6962916ea52SBrandon Wyman psu2.analyze(); 6972916ea52SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 6982916ea52SBrandon Wyman // POWER_GOOD# inactive, and OFF bit on. 6992916ea52SBrandon Wyman expectations.statusWordValue = 7002916ea52SBrandon Wyman ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF)); 7016d469fd4SBrandon Wyman for (auto x = 1; x <= PGOOD_DEGLITCH_LIMIT; x++) 70206ca4590SBrandon Wyman { 7032916ea52SBrandon Wyman // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and 7042916ea52SBrandon Wyman // STATUS_TEMPERATURE: Don't care if bits set or not (defaults). 7052916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 70682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 70782affd94SBrandon Wyman .Times(1) 70882affd94SBrandon Wyman .WillOnce(Return("124000")); 7092916ea52SBrandon Wyman psu2.analyze(); 7102916ea52SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 7116d469fd4SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= PGOOD_DEGLITCH_LIMIT); 7122916ea52SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 7132916ea52SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 7142916ea52SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 7152916ea52SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 7162916ea52SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 7172cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 718b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 7197ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 7202916ea52SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 7216d469fd4SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), x >= PGOOD_DEGLITCH_LIMIT); 72206ca4590SBrandon Wyman } 72306ca4590SBrandon Wyman } 7242916ea52SBrandon Wyman 7253f1242f3SBrandon Wyman // TODO: ReadFailure 7263f1242f3SBrandon Wyman } 7273f1242f3SBrandon Wyman 72859a35793SBrandon Wyman TEST_F(PowerSupplyTests, OnOffConfig) 72959a35793SBrandon Wyman { 73059a35793SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 73159a35793SBrandon Wyman uint8_t data = 0x15; 73259a35793SBrandon Wyman 73359a35793SBrandon Wyman // Test where PSU is NOT present 73459a35793SBrandon Wyman try 73559a35793SBrandon Wyman { 736681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 7370975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, _)).Times(0); 738*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, 739*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 740681b2a36SB. J. Wyman 7413ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7423ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 743681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0)); 74459a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 745681b2a36SB. J. Wyman // Constructor should set initial presence, default read returns 0. 74659a35793SBrandon Wyman // If it is not present, I should not be trying to write to it. 74759a35793SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0); 74859a35793SBrandon Wyman psu.onOffConfig(data); 74959a35793SBrandon Wyman } 75059a35793SBrandon Wyman catch (...) 7510c9a33d6SAdriana Kobylak {} 75259a35793SBrandon Wyman 75359a35793SBrandon Wyman // Test where PSU is present 75459a35793SBrandon Wyman try 75559a35793SBrandon Wyman { 756681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 7570975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 758*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, 759*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 7603ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7613ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 762391a0690SBrandon Wyman // There will potentially be multiple calls, we want it to continue 763391a0690SBrandon Wyman // returning 1 for the GPIO read to keep the power supply present. 764391a0690SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 76559a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 766391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 767ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 768ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 769ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 770ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 771ae35ac5dSBrandon Wyman .Times(1) 772ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 773391a0690SBrandon Wyman // If I am calling analyze(), I should probably give it good data. 774391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 775391a0690SBrandon Wyman PMBusExpectations expectations; 776391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 77782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 77882affd94SBrandon Wyman .Times(1) 77982affd94SBrandon Wyman .WillOnce(Return("205000")); 780681b2a36SB. J. Wyman psu.analyze(); 781391a0690SBrandon Wyman // I definitely should be writting ON_OFF_CONFIG if I call the function 782391a0690SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, ElementsAre(0x15), 783391a0690SBrandon Wyman Type::HwmonDeviceDebug)) 78459a35793SBrandon Wyman .Times(1); 78559a35793SBrandon Wyman psu.onOffConfig(data); 78659a35793SBrandon Wyman } 78759a35793SBrandon Wyman catch (...) 7880c9a33d6SAdriana Kobylak {} 78959a35793SBrandon Wyman } 79059a35793SBrandon Wyman 7913f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, ClearFaults) 7923f1242f3SBrandon Wyman { 7933f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 794*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, 795*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 7963ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7973ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 79806ca4590SBrandon Wyman // Always return 1 to indicate present. 79906ca4590SBrandon Wyman // Each analyze() call will trigger a read of the presence GPIO. 80006ca4590SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 801681b2a36SB. J. Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 802391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 803ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 804ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 805ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 806ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 807ae35ac5dSBrandon Wyman .Times(1) 808ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 8098da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 810b654c619SBrandon Wyman PMBusExpectations expectations; 811b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 81282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 81382affd94SBrandon Wyman .Times(1) 81482affd94SBrandon Wyman .WillOnce(Return("207000")); 815681b2a36SB. J. Wyman psu.analyze(); 8163f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8173f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 8183f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 8193f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 8203f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 82185c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 8226710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 823b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 8242cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 8257ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 82696893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 8272916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 82839ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 82939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 83039ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 831b654c619SBrandon Wyman 832f07bc797SBrandon Wyman // STATUS_WORD with fault bits galore! 833b654c619SBrandon Wyman expectations.statusWordValue = 0xFFFF; 834f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 835b654c619SBrandon Wyman expectations.statusInputValue = 0xFF; 836f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 837b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 83885c7bf41SBrandon Wyman // STATUS_CML with bits on. 839b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 8406710ba2cSBrandon Wyman // STATUS_VOUT with bits on. 841b654c619SBrandon Wyman expectations.statusVOUTValue = 0xFF; 842b10b3be0SBrandon Wyman // STATUS_IOUT with bits on. 843b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0xFF; 8447ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with bits on. 8457ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xFF; 84696893a46SBrandon Wyman // STATUS_TEMPERATURE with bits on. 84796893a46SBrandon Wyman expectations.statusTempValue = 0xFF; 848c2906f47SBrandon Wyman 8496d469fd4SBrandon Wyman for (auto x = 1; x <= PGOOD_DEGLITCH_LIMIT; x++) 850c2906f47SBrandon Wyman { 851b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 85282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 85382affd94SBrandon Wyman .Times(1) 85482affd94SBrandon Wyman .WillOnce(Return("0")); 8550975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 8560975eaf4SMatt Spinler { 8570975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 8580975eaf4SMatt Spinler } 8593f1242f3SBrandon Wyman psu.analyze(); 8603f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8612cf46945SBrandon Wyman // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT. 8622cf46945SBrandon Wyman // Rely on HasVoutUVFault() to verify this sets and clears. 8632cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 8646d469fd4SBrandon Wyman // pgoodFault at PGOOD_DEGLITCH_LIMIT, all other faults are deglitched 8656d469fd4SBrandon Wyman // up to DEGLITCH_LIMIT 866c2906f47SBrandon Wyman EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT); 867c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 868c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 869c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 870c2906f47SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), x >= DEGLITCH_LIMIT); 871c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 872c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 873c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 874c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 8756d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), x >= PGOOD_DEGLITCH_LIMIT); 876c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 877c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 878c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 879c2906f47SBrandon Wyman } 880c2906f47SBrandon Wyman 88132453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)) 88232453e9bSBrandon Wyman .Times(1) 88332453e9bSBrandon Wyman .WillOnce(Return(207000)); 8843225a45cSBrandon Wyman // Clearing VIN_UV fault via in1_lcrit_alarm 8853225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 8863225a45cSBrandon Wyman .Times(1) 8873225a45cSBrandon Wyman .WillOnce(Return(1)); 8880975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 8893f1242f3SBrandon Wyman psu.clearFaults(); 8903f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8913f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 8923f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 8933f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 8943f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 89585c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 8966710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 897b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 8982cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 8997ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 90096893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 9012916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 90239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 90339ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 90439ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 905681b2a36SB. J. Wyman 90682affd94SBrandon Wyman // Faults clear on READ_VIN 0 -> !0 90782affd94SBrandon Wyman // STATUS_WORD with fault bits galore! 90882affd94SBrandon Wyman expectations.statusWordValue = 0xFFFF; 90982affd94SBrandon Wyman // STATUS_INPUT with fault bits on. 91082affd94SBrandon Wyman expectations.statusInputValue = 0xFF; 91182affd94SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 91282affd94SBrandon Wyman expectations.statusMFRValue = 0xFF; 91382affd94SBrandon Wyman // STATUS_CML with bits on. 91482affd94SBrandon Wyman expectations.statusCMLValue = 0xFF; 91582affd94SBrandon Wyman // STATUS_VOUT with bits on. 91682affd94SBrandon Wyman expectations.statusVOUTValue = 0xFF; 91782affd94SBrandon Wyman // STATUS_IOUT with bits on. 91882affd94SBrandon Wyman expectations.statusIOUTValue = 0xFF; 91982affd94SBrandon Wyman // STATUS_FANS_1_2 with bits on. 92082affd94SBrandon Wyman expectations.statusFans12Value = 0xFF; 92182affd94SBrandon Wyman // STATUS_TEMPERATURE with bits on. 92282affd94SBrandon Wyman expectations.statusTempValue = 0xFF; 923c2906f47SBrandon Wyman 9246d469fd4SBrandon Wyman // All faults deglitched now. Check for false before limit above. 925c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 926c2906f47SBrandon Wyman { 92782affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 92882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 92982affd94SBrandon Wyman .Times(1) 93082affd94SBrandon Wyman .WillOnce(Return("0")); 9310975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 9320975eaf4SMatt Spinler { 9330975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 9340975eaf4SMatt Spinler } 93582affd94SBrandon Wyman psu.analyze(); 936c2906f47SBrandon Wyman } 937c2906f47SBrandon Wyman 93882affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 93982affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 94082affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 94182affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 94282affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 94382affd94SBrandon Wyman // True due to CML fault bits on 94482affd94SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), true); 94582affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 94682affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), true); 94782affd94SBrandon Wyman // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT. 94882affd94SBrandon Wyman // Rely on HasVoutUVFault() to verify this sets and clears. 94982affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 95082affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), true); 95182affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), true); 9526d469fd4SBrandon Wyman // No PGOOD fault, as less than PGOOD_DEGLITCH_LIMIT 9536d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 95482affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), true); 95582affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), true); 95682affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), true); 95782affd94SBrandon Wyman // STATUS_WORD with INPUT/VIN_UV fault bits off. 95882affd94SBrandon Wyman expectations.statusWordValue = 0xDFF7; 95982affd94SBrandon Wyman // STATUS_INPUT with VIN_UV_WARNING, VIN_UV_FAULT, and Unit Off For 96082affd94SBrandon Wyman // Insufficient Input Voltage bits off. 96182affd94SBrandon Wyman expectations.statusInputValue = 0xC7; 96282affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 96382affd94SBrandon Wyman // READ_VIN back in range. 96482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 96582affd94SBrandon Wyman .Times(1) 96682affd94SBrandon Wyman .WillOnce(Return("206000")); 9673225a45cSBrandon Wyman // VIN_UV cleared via in1_lcrit_alarm when voltage back in range. 9683225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 9693225a45cSBrandon Wyman .Times(1) 9703225a45cSBrandon Wyman .WillOnce(Return(1)); 9713225a45cSBrandon Wyman psu.analyze(); 9723225a45cSBrandon Wyman // We only cleared the VIN_UV and OFF faults. 9733225a45cSBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 9743225a45cSBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 9753225a45cSBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 9763225a45cSBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 9773225a45cSBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 9783225a45cSBrandon Wyman EXPECT_EQ(psu.hasCommFault(), true); 9793225a45cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 9803225a45cSBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), true); 9813225a45cSBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 9823225a45cSBrandon Wyman EXPECT_EQ(psu.hasFanFault(), true); 9833225a45cSBrandon Wyman EXPECT_EQ(psu.hasTempFault(), true); 9846d469fd4SBrandon Wyman // No PGOOD fault, as less than PGOOD_DEGLITCH_LIMIT 9856d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 9863225a45cSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), true); 9873225a45cSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), true); 9883225a45cSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), true); 9893225a45cSBrandon Wyman 9903225a45cSBrandon Wyman // All faults cleared 9913225a45cSBrandon Wyman expectations = {0}; 9923225a45cSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 9933225a45cSBrandon Wyman // READ_VIN back in range. 9943225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 9953225a45cSBrandon Wyman .Times(1) 9963225a45cSBrandon Wyman .WillOnce(Return("206000")); 9970975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 99882affd94SBrandon Wyman psu.analyze(); 99982affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 100082affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 100182affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 100282affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 100382affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 100482affd94SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 100582affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 100682affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 100782affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 100882affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 100982affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 101082affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 101182affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 101282affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 101382affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 101482affd94SBrandon Wyman 1015681b2a36SB. J. Wyman // TODO: Faults clear on missing/present? 10163f1242f3SBrandon Wyman } 10173f1242f3SBrandon Wyman 10183f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory) 10193f1242f3SBrandon Wyman { 10203f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 10211d7a7df8SBrandon Wyman 10221d7a7df8SBrandon Wyman try 10231d7a7df8SBrandon Wyman { 1024*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 1025*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 10261d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 10271d7a7df8SBrandon Wyman // If it is not present, I should not be trying to read a string 10281d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).Times(0); 10291d7a7df8SBrandon Wyman psu.updateInventory(); 10301d7a7df8SBrandon Wyman } 10311d7a7df8SBrandon Wyman catch (...) 10321d7a7df8SBrandon Wyman { 10331d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 10341d7a7df8SBrandon Wyman } 10351d7a7df8SBrandon Wyman 10361d7a7df8SBrandon Wyman try 10371d7a7df8SBrandon Wyman { 1038*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, 1039*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 10403ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10413ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1042681b2a36SB. J. Wyman // GPIO read return 1 to indicate present. 1043681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 10441d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1045391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1046ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1047ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1048ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1049ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1050ae35ac5dSBrandon Wyman .Times(1) 1051ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1052391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1053391a0690SBrandon Wyman PMBusExpectations expectations; 1054391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 105582affd94SBrandon Wyman // Call to analyze will read voltage, trigger clear faults for 0 to 105682affd94SBrandon Wyman // within range. 105782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 105882affd94SBrandon Wyman .Times(1) 105982affd94SBrandon Wyman .WillOnce(Return("123456")); 1060391a0690SBrandon Wyman psu.analyze(); 10611d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return("")); 10623f1242f3SBrandon Wyman psu.updateInventory(); 10631d7a7df8SBrandon Wyman 10643c530fbdSBrandon Wyman #if IBM_VPD 10651d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)) 10661d7a7df8SBrandon Wyman .WillOnce(Return("CCIN")) 10671d7a7df8SBrandon Wyman .WillOnce(Return("PN3456")) 10681d7a7df8SBrandon Wyman .WillOnce(Return("FN3456")) 10691d7a7df8SBrandon Wyman .WillOnce(Return("HEADER")) 10701d7a7df8SBrandon Wyman .WillOnce(Return("SN3456")) 10711d7a7df8SBrandon Wyman .WillOnce(Return("FW3456")); 10723c530fbdSBrandon Wyman #endif 10731d7a7df8SBrandon Wyman psu.updateInventory(); 10741d7a7df8SBrandon Wyman // TODO: D-Bus mocking to verify values stored on D-Bus (???) 10751d7a7df8SBrandon Wyman } 10761d7a7df8SBrandon Wyman catch (...) 10771d7a7df8SBrandon Wyman { 10781d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 10791d7a7df8SBrandon Wyman } 10803f1242f3SBrandon Wyman } 10813f1242f3SBrandon Wyman 10823f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent) 10833f1242f3SBrandon Wyman { 10843f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1085681b2a36SB. J. Wyman 1086*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 1087*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 10883ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10893ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 10903f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 10913f1242f3SBrandon Wyman 1092681b2a36SB. J. Wyman // Change GPIO read to return 1 to indicate present. 1093681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 1094391a0690SBrandon Wyman // Call to analyze() will update to present, that will trigger updating 1095391a0690SBrandon Wyman // to the correct/latest HWMON directory, in case it changes. 1096391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1097391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1098ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1099ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1100ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1101ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1102ae35ac5dSBrandon Wyman .Times(1) 1103ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1104391a0690SBrandon Wyman // Call to analyze things will trigger read of STATUS_WORD and READ_VIN. 1105391a0690SBrandon Wyman // Default expectations will be on, no faults. 1106391a0690SBrandon Wyman PMBusExpectations expectations; 1107391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 110882affd94SBrandon Wyman // Give it an input voltage in the 100-volt range. 110982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 111082affd94SBrandon Wyman .Times(1) 111182affd94SBrandon Wyman .WillOnce(Return("123456")); 11120975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1113681b2a36SB. J. Wyman psu.analyze(); 1114681b2a36SB. J. Wyman EXPECT_EQ(psu.isPresent(), true); 11153f1242f3SBrandon Wyman } 11163f1242f3SBrandon Wyman 11173f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted) 11183f1242f3SBrandon Wyman { 11193f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1120681b2a36SB. J. Wyman 1121*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, 1122*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 11233ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 11243ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1125681b2a36SB. J. Wyman // Always return 1 to indicate present. 1126681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1127391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1128391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1129ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1130ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1131ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1132ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1133ae35ac5dSBrandon Wyman .Times(1) 1134ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1135391a0690SBrandon Wyman // Call to analyze things will trigger read of STATUS_WORD and READ_VIN. 1136391a0690SBrandon Wyman // Default expectations will be on, no faults. 1137391a0690SBrandon Wyman PMBusExpectations expectations; 1138391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 113982affd94SBrandon Wyman // Give it an input voltage in the 100-volt range. 114082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 114182affd94SBrandon Wyman .Times(1) 114282affd94SBrandon Wyman .WillOnce(Return("124680")); 1143681b2a36SB. J. Wyman psu.analyze(); 11443f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 1145f07bc797SBrandon Wyman // STATUS_WORD with fault bits on. 1146b654c619SBrandon Wyman expectations.statusWordValue = 0xFFFF; 1147f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 1148b654c619SBrandon Wyman expectations.statusInputValue = 0xFF; 1149f07bc797SBrandon Wyman // STATUS_MFR_SPECIFIC with faults bits on. 1150b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 115185c7bf41SBrandon Wyman // STATUS_CML with faults bits on. 1152b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 11536710ba2cSBrandon Wyman // STATUS_VOUT with fault bits on. 1154b654c619SBrandon Wyman expectations.statusVOUTValue = 0xFF; 1155b10b3be0SBrandon Wyman // STATUS_IOUT with fault bits on. 1156b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0xFF; 11577ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with bits on. 11587ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xFF; 115996893a46SBrandon Wyman // STATUS_TEMPERATURE with fault bits on. 116096893a46SBrandon Wyman expectations.statusTempValue = 0xFF; 1161c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1162c2906f47SBrandon Wyman { 1163b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 11644fc191f0SBrandon Wyman // Also get another read of READ_VIN, faulted, so not in 100-volt range 116582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 116682affd94SBrandon Wyman .Times(1) 11674fc191f0SBrandon Wyman .WillOnce(Return("19000")); 11680975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 11690975eaf4SMatt Spinler { 11700975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 11710975eaf4SMatt Spinler } 11723f1242f3SBrandon Wyman psu.analyze(); 1173c2906f47SBrandon Wyman EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT); 1174c2906f47SBrandon Wyman } 11753f1242f3SBrandon Wyman } 11763f1242f3SBrandon Wyman 11773f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasInputFault) 11783f1242f3SBrandon Wyman { 11793f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1180681b2a36SB. J. Wyman 1181*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 1182*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 11833ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 11843ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1185681b2a36SB. J. Wyman // Always return 1 to indicate present. 1186681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 11873f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1188391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1189ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1190ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1191ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1192ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1193ae35ac5dSBrandon Wyman .Times(1) 1194ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 11958da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1196b654c619SBrandon Wyman PMBusExpectations expectations; 1197b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 119882affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 119982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 120082affd94SBrandon Wyman .Times(1) 120182affd94SBrandon Wyman .WillOnce(Return("201100")); 12023f1242f3SBrandon Wyman psu.analyze(); 12033f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 1204f07bc797SBrandon Wyman // STATUS_WORD with input fault/warn on. 1205b654c619SBrandon Wyman expectations.statusWordValue = (status_word::INPUT_FAULT_WARN); 1206f07bc797SBrandon Wyman // STATUS_INPUT with an input fault bit on. 1207b654c619SBrandon Wyman expectations.statusInputValue = 0x80; 1208c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1209c2906f47SBrandon Wyman { 1210b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 121182affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 121282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 121382affd94SBrandon Wyman .Times(1) 121482affd94SBrandon Wyman .WillOnce(Return("201200")); 12150975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 12160975eaf4SMatt Spinler { 12170975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 12180975eaf4SMatt Spinler } 12193f1242f3SBrandon Wyman psu.analyze(); 1220c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 1221c2906f47SBrandon Wyman } 1222f07bc797SBrandon Wyman // STATUS_WORD with no bits on. 1223b654c619SBrandon Wyman expectations.statusWordValue = 0; 1224b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 122582affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 122682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 122782affd94SBrandon Wyman .Times(1) 122882affd94SBrandon Wyman .WillOnce(Return("201300")); 12290975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 12303f1242f3SBrandon Wyman psu.analyze(); 12313f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 12323f1242f3SBrandon Wyman } 12333f1242f3SBrandon Wyman 12343f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault) 12353f1242f3SBrandon Wyman { 12363f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1237681b2a36SB. J. Wyman 1238*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 1239*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 12403ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 12413ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1242681b2a36SB. J. Wyman // Always return 1 to indicate present. 1243681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 12443f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1245391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1246ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1247ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1248ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1249ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1250ae35ac5dSBrandon Wyman .Times(1) 1251ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1252f07bc797SBrandon Wyman // First return STATUS_WORD with no bits on. 12538da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1254b654c619SBrandon Wyman PMBusExpectations expectations; 1255b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 125682affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 125782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 125882affd94SBrandon Wyman .Times(1) 125982affd94SBrandon Wyman .WillOnce(Return("202100")); 12603f1242f3SBrandon Wyman psu.analyze(); 12613f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 1262f07bc797SBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 1263b654c619SBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 1264f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 1265b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 1266c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1267c2906f47SBrandon Wyman { 1268b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 126982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 127082affd94SBrandon Wyman .Times(1) 127182affd94SBrandon Wyman .WillOnce(Return("202200")); 12723f1242f3SBrandon Wyman psu.analyze(); 1273c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 1274c2906f47SBrandon Wyman } 1275f07bc797SBrandon Wyman // Back to no bits on in STATUS_WORD 1276b654c619SBrandon Wyman expectations.statusWordValue = 0; 1277b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 127882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 127982affd94SBrandon Wyman .Times(1) 128082affd94SBrandon Wyman .WillOnce(Return("202300")); 12813f1242f3SBrandon Wyman psu.analyze(); 12823f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 12833f1242f3SBrandon Wyman } 12843f1242f3SBrandon Wyman 12853f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault) 12863f1242f3SBrandon Wyman { 12873f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1288681b2a36SB. J. Wyman 1289*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 1290*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 12913ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 12923ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1293681b2a36SB. J. Wyman // Always return 1 to indicate present. 1294681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 12953f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1296391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1297ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1298ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1299ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1300ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1301ae35ac5dSBrandon Wyman .Times(1) 1302ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 130382affd94SBrandon Wyman 130482affd94SBrandon Wyman // Presence change from missing to present will trigger in1_input read in 130582affd94SBrandon Wyman // an attempt to get CLEAR_FAULTS called. Return value ignored. 130682affd94SBrandon Wyman // Zero to non-zero voltage, for missing/present change, triggers clear 130782affd94SBrandon Wyman // faults call again. Return value ignored. 130882affd94SBrandon Wyman // Fault (low voltage) to not faulted (voltage in range) triggers clear 130982affd94SBrandon Wyman // faults call a third time. 131082affd94SBrandon Wyman 13118da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1312b654c619SBrandon Wyman PMBusExpectations expectations; 1313b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 131482affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 131582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 131682affd94SBrandon Wyman .Times(1) 131782affd94SBrandon Wyman .WillOnce(Return("201100")); 13183f1242f3SBrandon Wyman psu.analyze(); 13193f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 1320f07bc797SBrandon Wyman // Turn fault on. 1321b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VIN_UV_FAULT); 132285c7bf41SBrandon Wyman // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by 132385c7bf41SBrandon Wyman // Figure 16, and assume bits on in STATUS_INPUT. 1324b654c619SBrandon Wyman expectations.statusInputValue = 0x18; 1325c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1326c2906f47SBrandon Wyman { 1327b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 132882affd94SBrandon Wyman // If there is a VIN_UV fault, fake reading voltage of less than 20V 132982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 133082affd94SBrandon Wyman .Times(1) 133182affd94SBrandon Wyman .WillOnce(Return("19876")); 13320975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 13330975eaf4SMatt Spinler { 13340975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 13350975eaf4SMatt Spinler } 13363f1242f3SBrandon Wyman psu.analyze(); 1337c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 1338c2906f47SBrandon Wyman } 1339f07bc797SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1340b654c619SBrandon Wyman expectations.statusWordValue = 0; 1341b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 134282affd94SBrandon Wyman // Updates now result in clearing faults if read voltage goes from below the 134382affd94SBrandon Wyman // minimum, to within a valid range. 134482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 134582affd94SBrandon Wyman .Times(1) 134682affd94SBrandon Wyman .WillOnce(Return("201300")); 13473225a45cSBrandon Wyman // Went from below minimum to within range, expect clearVinUVFault(). 13483225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 13493225a45cSBrandon Wyman .Times(1) 13503225a45cSBrandon Wyman .WillOnce(Return(1)); 13510975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 13523f1242f3SBrandon Wyman psu.analyze(); 13533f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 13543f1242f3SBrandon Wyman } 13556710ba2cSBrandon Wyman 13566710ba2cSBrandon Wyman TEST_F(PowerSupplyTests, HasVoutOVFault) 13576710ba2cSBrandon Wyman { 13586710ba2cSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 13596710ba2cSBrandon Wyman 1360*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x69, 1361*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 13626710ba2cSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 13636710ba2cSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 13646710ba2cSBrandon Wyman // Always return 1 to indicate present. 13656710ba2cSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 13666710ba2cSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1367391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1368ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1369ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1370ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1371ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1372ae35ac5dSBrandon Wyman .Times(1) 1373ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 13746710ba2cSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1375b654c619SBrandon Wyman PMBusExpectations expectations; 1376b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 137782affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 137882affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 137982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 138082affd94SBrandon Wyman .Times(1) 138182affd94SBrandon Wyman .WillOnce(Return("202100")); 13826710ba2cSBrandon Wyman psu.analyze(); 13836710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 13846710ba2cSBrandon Wyman // Turn fault on. 1385b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_OV_FAULT); 13866710ba2cSBrandon Wyman // STATUS_VOUT fault bit(s) 1387b654c619SBrandon Wyman expectations.statusVOUTValue = 0x80; 1388c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1389c2906f47SBrandon Wyman { 1390b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 139182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 139282affd94SBrandon Wyman .Times(1) 139382affd94SBrandon Wyman .WillOnce(Return("202200")); 13946710ba2cSBrandon Wyman psu.analyze(); 1395c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 1396c2906f47SBrandon Wyman } 13976710ba2cSBrandon Wyman // Back to no fault bits on in STATUS_WORD 1398b654c619SBrandon Wyman expectations.statusWordValue = 0; 1399b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 140082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 140182affd94SBrandon Wyman .Times(1) 140282affd94SBrandon Wyman .WillOnce(Return("202300")); 14036710ba2cSBrandon Wyman psu.analyze(); 14046710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 14056710ba2cSBrandon Wyman } 140696893a46SBrandon Wyman 1407b10b3be0SBrandon Wyman TEST_F(PowerSupplyTests, HasIoutOCFault) 1408b10b3be0SBrandon Wyman { 1409b10b3be0SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1410b10b3be0SBrandon Wyman 1411*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, 1412*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 1413b10b3be0SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1414b10b3be0SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1415b10b3be0SBrandon Wyman // Always return 1 to indicate present. 1416b10b3be0SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1417b10b3be0SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1418391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1419ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1420ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1421ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1422ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1423ae35ac5dSBrandon Wyman .Times(1) 1424ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1425b10b3be0SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1426b10b3be0SBrandon Wyman PMBusExpectations expectations; 1427b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 142882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 142982affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 143082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 143182affd94SBrandon Wyman .Times(1) 143282affd94SBrandon Wyman .WillOnce(Return("203100")); 1433b10b3be0SBrandon Wyman psu.analyze(); 1434b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1435b10b3be0SBrandon Wyman // Turn fault on. 1436b10b3be0SBrandon Wyman expectations.statusWordValue = status_word::IOUT_OC_FAULT; 1437b10b3be0SBrandon Wyman // STATUS_IOUT fault bit(s) 1438b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0x88; 1439c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1440c2906f47SBrandon Wyman { 1441b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 144282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 144382affd94SBrandon Wyman .Times(1) 144482affd94SBrandon Wyman .WillOnce(Return("203200")); 14450975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 14460975eaf4SMatt Spinler { 14470975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 14480975eaf4SMatt Spinler } 1449b10b3be0SBrandon Wyman psu.analyze(); 1450c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 1451c2906f47SBrandon Wyman } 1452b10b3be0SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1453b10b3be0SBrandon Wyman expectations.statusWordValue = 0; 1454b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 145582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 145682affd94SBrandon Wyman .Times(1) 145782affd94SBrandon Wyman .WillOnce(Return("203300")); 14580975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1459b10b3be0SBrandon Wyman psu.analyze(); 1460b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1461b10b3be0SBrandon Wyman } 1462b10b3be0SBrandon Wyman 14632cf46945SBrandon Wyman TEST_F(PowerSupplyTests, HasVoutUVFault) 14642cf46945SBrandon Wyman { 14652cf46945SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 14662cf46945SBrandon Wyman 1467*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, 1468*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 14692cf46945SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 14702cf46945SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 14712cf46945SBrandon Wyman // Always return 1 to indicate present. 14722cf46945SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 14732cf46945SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1474391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1475ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1476ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1477ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1478ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1479ae35ac5dSBrandon Wyman .Times(1) 1480ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1481391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 14822cf46945SBrandon Wyman PMBusExpectations expectations; 14832cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 148482affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 148582affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 148682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 148782affd94SBrandon Wyman .Times(1) 148882affd94SBrandon Wyman .WillOnce(Return("204100")); 14892cf46945SBrandon Wyman psu.analyze(); 14902cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 14912cf46945SBrandon Wyman // Turn fault on. 14922cf46945SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_FAULT); 14932cf46945SBrandon Wyman // STATUS_VOUT fault bit(s) 14942cf46945SBrandon Wyman expectations.statusVOUTValue = 0x30; 1495c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1496c2906f47SBrandon Wyman { 14972cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 149882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 149982affd94SBrandon Wyman .Times(1) 150082affd94SBrandon Wyman .WillOnce(Return("204200")); 15012cf46945SBrandon Wyman psu.analyze(); 1502c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), x >= DEGLITCH_LIMIT); 1503c2906f47SBrandon Wyman } 15042cf46945SBrandon Wyman // Back to no fault bits on in STATUS_WORD 15052cf46945SBrandon Wyman expectations.statusWordValue = 0; 15062cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 150782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 150882affd94SBrandon Wyman .Times(1) 150982affd94SBrandon Wyman .WillOnce(Return("204300")); 15102cf46945SBrandon Wyman psu.analyze(); 15112cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 15122cf46945SBrandon Wyman } 15132cf46945SBrandon Wyman 15147ee4d7e4SBrandon Wyman TEST_F(PowerSupplyTests, HasFanFault) 15157ee4d7e4SBrandon Wyman { 15167ee4d7e4SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 15177ee4d7e4SBrandon Wyman 15180975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1); 15190975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0); 15200975eaf4SMatt Spinler 1521*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, 1522*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 15237ee4d7e4SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 15247ee4d7e4SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 15257ee4d7e4SBrandon Wyman // Always return 1 to indicate present. 15267ee4d7e4SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 15277ee4d7e4SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1528391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1529ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1530ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1531ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1532ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1533ae35ac5dSBrandon Wyman .Times(1) 1534ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 15357ee4d7e4SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 15367ee4d7e4SBrandon Wyman PMBusExpectations expectations; 15377ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 153882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 153982affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 154082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 154182affd94SBrandon Wyman .Times(1) 154282affd94SBrandon Wyman .WillOnce(Return("205100")); 15437ee4d7e4SBrandon Wyman psu.analyze(); 15447ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 15457ee4d7e4SBrandon Wyman // Turn fault on. 15467ee4d7e4SBrandon Wyman expectations.statusWordValue = (status_word::FAN_FAULT); 15477ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 fault bit on (Fan 1 Fault) 15487ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0x80; 1549c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1550c2906f47SBrandon Wyman { 15517ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 155282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 155382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 155482affd94SBrandon Wyman .Times(1) 155582affd94SBrandon Wyman .WillOnce(Return("205200")); 15567ee4d7e4SBrandon Wyman psu.analyze(); 1557c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 1558c2906f47SBrandon Wyman } 15597ee4d7e4SBrandon Wyman // Back to no fault bits on in STATUS_WORD 15607ee4d7e4SBrandon Wyman expectations.statusWordValue = 0; 15617ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 156282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 156382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 156482affd94SBrandon Wyman .Times(1) 156582affd94SBrandon Wyman .WillOnce(Return("205300")); 15667ee4d7e4SBrandon Wyman psu.analyze(); 15677ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 15687ee4d7e4SBrandon Wyman } 15697ee4d7e4SBrandon Wyman 157096893a46SBrandon Wyman TEST_F(PowerSupplyTests, HasTempFault) 157196893a46SBrandon Wyman { 157296893a46SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 157396893a46SBrandon Wyman 15740975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1); 15750975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0); 15760975eaf4SMatt Spinler 1577*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, 1578*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 157996893a46SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 158096893a46SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 158196893a46SBrandon Wyman // Always return 1 to indicate present. 158296893a46SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 158396893a46SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1584391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1585ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1586ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1587ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1588ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1589ae35ac5dSBrandon Wyman .Times(1) 1590ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 159196893a46SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 159296893a46SBrandon Wyman PMBusExpectations expectations; 159396893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 159482affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 159582affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 159682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 159782affd94SBrandon Wyman .Times(1) 159882affd94SBrandon Wyman .WillOnce(Return("206100")); 159996893a46SBrandon Wyman psu.analyze(); 160096893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 160196893a46SBrandon Wyman // Turn fault on. 160296893a46SBrandon Wyman expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 160396893a46SBrandon Wyman // STATUS_TEMPERATURE fault bit on (OT Fault) 160496893a46SBrandon Wyman expectations.statusTempValue = 0x80; 1605c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1606c2906f47SBrandon Wyman { 160796893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 160882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 160982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 161082affd94SBrandon Wyman .Times(1) 161182affd94SBrandon Wyman .WillOnce(Return("206200")); 161296893a46SBrandon Wyman psu.analyze(); 1613c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 1614c2906f47SBrandon Wyman } 161596893a46SBrandon Wyman // Back to no fault bits on in STATUS_WORD 161696893a46SBrandon Wyman expectations.statusWordValue = 0; 161796893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 161882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 161982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 162082affd94SBrandon Wyman .Times(1) 162182affd94SBrandon Wyman .WillOnce(Return("206300")); 162296893a46SBrandon Wyman psu.analyze(); 162396893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 162496893a46SBrandon Wyman } 16252916ea52SBrandon Wyman 16262916ea52SBrandon Wyman TEST_F(PowerSupplyTests, HasPgoodFault) 16272916ea52SBrandon Wyman { 16282916ea52SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 16292916ea52SBrandon Wyman 1630*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x6b, 1631*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 16322916ea52SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 16332916ea52SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 16342916ea52SBrandon Wyman // Always return 1 to indicate present. 16352916ea52SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 16362916ea52SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1637391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1638ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1639ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1640ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1641ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1642ae35ac5dSBrandon Wyman .Times(1) 1643ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 16442916ea52SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 16452916ea52SBrandon Wyman PMBusExpectations expectations; 16462916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 164782affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 164882affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 164982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 165082affd94SBrandon Wyman .Times(1) 165182affd94SBrandon Wyman .WillOnce(Return("207100")); 16522916ea52SBrandon Wyman psu.analyze(); 16532916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 1654391a0690SBrandon Wyman // Setup another expectation of no faults. 1655391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 165682affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 165782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 165882affd94SBrandon Wyman .Times(1) 165982affd94SBrandon Wyman .WillOnce(Return("207200")); 166082affd94SBrandon Wyman psu.analyze(); 166182affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 166282affd94SBrandon Wyman // Setup another expectation of no faults. 166382affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 166482affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 166582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 166682affd94SBrandon Wyman .Times(1) 166782affd94SBrandon Wyman .WillOnce(Return("207300")); 1668391a0690SBrandon Wyman psu.analyze(); 1669391a0690SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 16702916ea52SBrandon Wyman // Turn PGOOD# off (fault on). 16712916ea52SBrandon Wyman expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED); 16722916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 167382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 167482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 167582affd94SBrandon Wyman .Times(1) 167682affd94SBrandon Wyman .WillOnce(Return("207400")); 16772916ea52SBrandon Wyman psu.analyze(); 16786d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 1 167906ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 168006ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 168182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 168282affd94SBrandon Wyman .Times(1) 168382affd94SBrandon Wyman .WillOnce(Return("207500")); 168406ca4590SBrandon Wyman psu.analyze(); 16856d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 2 168606ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 168706ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 168882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 168982affd94SBrandon Wyman .Times(1) 169082affd94SBrandon Wyman .WillOnce(Return("207600")); 169106ca4590SBrandon Wyman psu.analyze(); 16926d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 3 16936d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 16946d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 16956d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 16966d469fd4SBrandon Wyman .Times(1) 16976d469fd4SBrandon Wyman .WillOnce(Return("207700")); 16986d469fd4SBrandon Wyman psu.analyze(); 16996d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 4 17006d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 17016d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 17026d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 17036d469fd4SBrandon Wyman .Times(1) 17046d469fd4SBrandon Wyman .WillOnce(Return("207800")); 17056d469fd4SBrandon Wyman psu.analyze(); 17066d469fd4SBrandon Wyman // Expect true. PGOOD_DEGLITCH_LIMIT @ 5 17072916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 17082916ea52SBrandon Wyman // Back to no fault bits on in STATUS_WORD 17092916ea52SBrandon Wyman expectations.statusWordValue = 0; 17102916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 171182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 171282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 171382affd94SBrandon Wyman .Times(1) 171482affd94SBrandon Wyman .WillOnce(Return("207700")); 17152916ea52SBrandon Wyman psu.analyze(); 17162916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 171782affd94SBrandon Wyman 17182916ea52SBrandon Wyman // Turn OFF bit on 17192916ea52SBrandon Wyman expectations.statusWordValue = (status_word::UNIT_IS_OFF); 17202916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 172182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 172282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 172382affd94SBrandon Wyman .Times(1) 172482affd94SBrandon Wyman .WillOnce(Return("208100")); 17252916ea52SBrandon Wyman psu.analyze(); 172606ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 172706ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 172882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 172982affd94SBrandon Wyman .Times(1) 173082affd94SBrandon Wyman .WillOnce(Return("208200")); 173106ca4590SBrandon Wyman psu.analyze(); 173206ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 173306ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 173482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 173582affd94SBrandon Wyman .Times(1) 173682affd94SBrandon Wyman .WillOnce(Return("208300")); 173706ca4590SBrandon Wyman psu.analyze(); 17386d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 17396d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 17406d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 17416d469fd4SBrandon Wyman .Times(1) 17426d469fd4SBrandon Wyman .WillOnce(Return("208400")); 17436d469fd4SBrandon Wyman psu.analyze(); 17446d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 17456d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 17466d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 17476d469fd4SBrandon Wyman .Times(1) 17486d469fd4SBrandon Wyman .WillOnce(Return("208500")); 17496d469fd4SBrandon Wyman psu.analyze(); 17502916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 17512916ea52SBrandon Wyman // Back to no fault bits on in STATUS_WORD 17522916ea52SBrandon Wyman expectations.statusWordValue = 0; 17532916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 175482affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 175582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 175682affd94SBrandon Wyman .Times(1) 17576d469fd4SBrandon Wyman .WillOnce(Return("208000")); 17582916ea52SBrandon Wyman psu.analyze(); 17592916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 17602916ea52SBrandon Wyman } 176139ea02bcSBrandon Wyman 176239ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSKillFault) 176339ea02bcSBrandon Wyman { 176439ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1765*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 4, 0x6d, 1766*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 176739ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 176839ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 176939ea02bcSBrandon Wyman // Always return 1 to indicate present. 177039ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 177139ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 177282affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1773ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1774ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1775ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1776ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1777ae35ac5dSBrandon Wyman .Times(1) 1778ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 177939ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 178039ea02bcSBrandon Wyman PMBusExpectations expectations; 178139ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 178282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 178382affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 178482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 178582affd94SBrandon Wyman .Times(1) 178682affd94SBrandon Wyman .WillOnce(Return("208100")); 178739ea02bcSBrandon Wyman psu.analyze(); 178839ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 178939ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 179039ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 179139ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 179239ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1793c2906f47SBrandon Wyman 1794c2906f47SBrandon Wyman // Deglitching faults, false until read the fault bits on up to the limit. 1795c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1796c2906f47SBrandon Wyman { 179739ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 179882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 179982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 180082affd94SBrandon Wyman .Times(1) 180182affd94SBrandon Wyman .WillOnce(Return("208200")); 18020975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 18030975eaf4SMatt Spinler { 18040975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 18050975eaf4SMatt Spinler } 180639ea02bcSBrandon Wyman psu.analyze(); 1807c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1808c2906f47SBrandon Wyman } 1809c2906f47SBrandon Wyman 181039ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 181139ea02bcSBrandon Wyman expectations.statusWordValue = 0; 181239ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 181382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 181482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 181582affd94SBrandon Wyman .Times(1) 181682affd94SBrandon Wyman .WillOnce(Return("208300")); 18170975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 181839ea02bcSBrandon Wyman psu.analyze(); 181939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 182039ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 182139ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 182239ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 4 on. 182339ea02bcSBrandon Wyman expectations.statusMFRValue = 0x10; 1824c2906f47SBrandon Wyman 1825c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1826c2906f47SBrandon Wyman { 182739ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 182882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 182982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 183082affd94SBrandon Wyman .Times(1) 183182affd94SBrandon Wyman .WillOnce(Return("208400")); 18320975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 18330975eaf4SMatt Spinler { 18340975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 18350975eaf4SMatt Spinler } 183639ea02bcSBrandon Wyman psu.analyze(); 1837c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1838c2906f47SBrandon Wyman } 1839c2906f47SBrandon Wyman 184039ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 184139ea02bcSBrandon Wyman expectations.statusWordValue = 0; 184239ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 184382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 184482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 184582affd94SBrandon Wyman .Times(1) 184682affd94SBrandon Wyman .WillOnce(Return("208500")); 18470975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 184839ea02bcSBrandon Wyman psu.analyze(); 184939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 185039ea02bcSBrandon Wyman } 185139ea02bcSBrandon Wyman 185239ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPS12VcsFault) 185339ea02bcSBrandon Wyman { 185439ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1855*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 5, 0x6e, 1856*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 185739ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 185839ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 185939ea02bcSBrandon Wyman // Always return 1 to indicate present. 186039ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 186139ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 186282affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1863ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1864ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1865ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1866ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1867ae35ac5dSBrandon Wyman .Times(1) 1868ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 186939ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 187039ea02bcSBrandon Wyman PMBusExpectations expectations; 187139ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 187282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 187382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 187482affd94SBrandon Wyman .Times(1) 187582affd94SBrandon Wyman .WillOnce(Return("209100")); 187639ea02bcSBrandon Wyman psu.analyze(); 187739ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 187839ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 187939ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 188039ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 188139ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1882c2906f47SBrandon Wyman 1883c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1884c2906f47SBrandon Wyman { 188539ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 188682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 188782affd94SBrandon Wyman .Times(1) 188882affd94SBrandon Wyman .WillOnce(Return("209200")); 188939ea02bcSBrandon Wyman psu.analyze(); 1890c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1891c2906f47SBrandon Wyman } 1892c2906f47SBrandon Wyman 189339ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 189439ea02bcSBrandon Wyman expectations.statusWordValue = 0; 189539ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 189682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 189782affd94SBrandon Wyman .Times(1) 189882affd94SBrandon Wyman .WillOnce(Return("209300")); 189939ea02bcSBrandon Wyman psu.analyze(); 190039ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 190139ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 190239ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 190339ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 6 on. 190439ea02bcSBrandon Wyman expectations.statusMFRValue = 0x40; 1905c2906f47SBrandon Wyman 1906c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1907c2906f47SBrandon Wyman { 190839ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 190982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 191082affd94SBrandon Wyman .Times(1) 191182affd94SBrandon Wyman .WillOnce(Return("209400")); 191239ea02bcSBrandon Wyman psu.analyze(); 1913c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1914c2906f47SBrandon Wyman } 1915c2906f47SBrandon Wyman 191639ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 191739ea02bcSBrandon Wyman expectations.statusWordValue = 0; 191839ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 191982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 192082affd94SBrandon Wyman .Times(1) 192182affd94SBrandon Wyman .WillOnce(Return("209500")); 192239ea02bcSBrandon Wyman psu.analyze(); 192339ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 192439ea02bcSBrandon Wyman } 192539ea02bcSBrandon Wyman 192639ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSCS12VFault) 192739ea02bcSBrandon Wyman { 192839ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1929*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f, 1930*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 193139ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 193239ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 193339ea02bcSBrandon Wyman // Always return 1 to indicate present. 193439ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 193539ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 193682affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1937ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1938ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1939ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1940ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1941ae35ac5dSBrandon Wyman .Times(1) 1942ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 194339ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 194439ea02bcSBrandon Wyman PMBusExpectations expectations; 194539ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 194682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 194782affd94SBrandon Wyman .Times(1) 194882affd94SBrandon Wyman .WillOnce(Return("209100")); 194939ea02bcSBrandon Wyman psu.analyze(); 195039ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 195139ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 195239ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 195339ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 195439ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1955c2906f47SBrandon Wyman 1956c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1957c2906f47SBrandon Wyman { 195839ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 195982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 196082affd94SBrandon Wyman .Times(1) 196182affd94SBrandon Wyman .WillOnce(Return("209200")); 196239ea02bcSBrandon Wyman psu.analyze(); 1963c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1964c2906f47SBrandon Wyman } 1965c2906f47SBrandon Wyman 196639ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 196739ea02bcSBrandon Wyman expectations.statusWordValue = 0; 196839ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 196982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 197082affd94SBrandon Wyman .Times(1) 197182affd94SBrandon Wyman .WillOnce(Return("209300")); 197239ea02bcSBrandon Wyman psu.analyze(); 197339ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 197439ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 197539ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 197639ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 7 on. 197739ea02bcSBrandon Wyman expectations.statusMFRValue = 0x80; 1978c2906f47SBrandon Wyman 1979c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1980c2906f47SBrandon Wyman { 198139ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 198282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 198382affd94SBrandon Wyman .Times(1) 198482affd94SBrandon Wyman .WillOnce(Return("209400")); 198539ea02bcSBrandon Wyman psu.analyze(); 1986c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1987c2906f47SBrandon Wyman } 1988c2906f47SBrandon Wyman 198939ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 199039ea02bcSBrandon Wyman expectations.statusWordValue = 0; 199139ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 199282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 199382affd94SBrandon Wyman .Times(1) 199482affd94SBrandon Wyman .WillOnce(Return("209500")); 199539ea02bcSBrandon Wyman psu.analyze(); 199639ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 199739ea02bcSBrandon Wyman } 1998c3324424SBrandon Wyman 1999c3324424SBrandon Wyman TEST_F(PowerSupplyTests, SetupInputHistory) 2000c3324424SBrandon Wyman { 2001c3324424SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2002c3324424SBrandon Wyman { 2003*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f, 2004*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 2005c3324424SBrandon Wyman // Defaults to not present due to constructor and mock ordering. 2006c3324424SBrandon Wyman psu.setupInputHistory(); 2007c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2008c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 2009c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 2010ae35ac5dSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2011c3324424SBrandon Wyman // Always return 1 to indicate present. 2012c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 2013ae35ac5dSBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2014ae35ac5dSBrandon Wyman PMBusExpectations expectations; 2015ae35ac5dSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2016ae35ac5dSBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 2017ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2018ae35ac5dSBrandon Wyman .Times(1) 2019ae35ac5dSBrandon Wyman .WillOnce(Return("206000")); 2020ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 2021ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 2022ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 2023ae35ac5dSBrandon Wyman /// Also called when I redo setupInputHistory(). 2024ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2025ae35ac5dSBrandon Wyman .Times(2) 2026ae35ac5dSBrandon Wyman .WillRepeatedly(Return("2000")); 2027ae35ac5dSBrandon Wyman // Call to analyze() and above expectations to get missing/present and 2028ae35ac5dSBrandon Wyman // good status. 2029c3324424SBrandon Wyman psu.analyze(); 2030c3324424SBrandon Wyman psu.setupInputHistory(); 2031c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2032c3324424SBrandon Wyman } 2033c3324424SBrandon Wyman { 2034ae35ac5dSBrandon Wyman // Workaround - Disable INPUT_HISTORY collection if 1400W 2035*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 2036*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 2037ae35ac5dSBrandon Wyman // Defaults to not present due to constructor and mock ordering. 2038ae35ac5dSBrandon Wyman psu.setupInputHistory(); 2039ae35ac5dSBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2040ae35ac5dSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 2041ae35ac5dSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 2042ae35ac5dSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2043ae35ac5dSBrandon Wyman // Always return 1 to indicate present. 2044ae35ac5dSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 2045ae35ac5dSBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2046ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 2047ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 2048ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate 1400W IBM value, unsupported. 2049ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2050ae35ac5dSBrandon Wyman .Times(2) 2051ae35ac5dSBrandon Wyman .WillRepeatedly(Return("30725")); 2052ae35ac5dSBrandon Wyman PMBusExpectations expectations; 2053ae35ac5dSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2054ae35ac5dSBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 2055ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2056ae35ac5dSBrandon Wyman .Times(1) 2057ae35ac5dSBrandon Wyman .WillOnce(Return("206000")); 2058ae35ac5dSBrandon Wyman // Call to analyze() and above expectations to get missing/present and 2059ae35ac5dSBrandon Wyman // good status. 2060ae35ac5dSBrandon Wyman psu.analyze(); 2061ae35ac5dSBrandon Wyman psu.setupInputHistory(); 2062ae35ac5dSBrandon Wyman // After updating to present, and retrying setup, expect ibm-cffps with 2063ae35ac5dSBrandon Wyman // 1400W to still not support INPUT_HISTORY. 2064ae35ac5dSBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2065ae35ac5dSBrandon Wyman } 2066ae35ac5dSBrandon Wyman { 2067c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 11, 2068*9464c429SGeorge Liu 0x58, "inspur-ipsps", PSUGPIOLineName, 2069*9464c429SGeorge Liu isPowerOn}; 2070c3324424SBrandon Wyman // Defaults to not present due to constructor and mock ordering. 2071c3324424SBrandon Wyman psu.setupInputHistory(); 2072c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2073c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 2074c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 2075ae35ac5dSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2076c3324424SBrandon Wyman // Always return 1 to indicate present. 2077c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 2078ae35ac5dSBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2079ae35ac5dSBrandon Wyman PMBusExpectations expectations; 2080ae35ac5dSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2081ae35ac5dSBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 2082ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2083ae35ac5dSBrandon Wyman .Times(1) 2084ae35ac5dSBrandon Wyman .WillOnce(Return("206000")); 2085ae35ac5dSBrandon Wyman // Call to analyze() and above expectations to get missing/present and 2086ae35ac5dSBrandon Wyman // good status. 2087c3324424SBrandon Wyman psu.analyze(); 2088c3324424SBrandon Wyman psu.setupInputHistory(); 2089c3324424SBrandon Wyman // After updating to present, and retrying setup, expect inspur-ipsps to 2090c3324424SBrandon Wyman // still not support INPUT_HISTORY. 2091c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2092c3324424SBrandon Wyman } 2093c3324424SBrandon Wyman } 2094c3324424SBrandon Wyman 2095c3324424SBrandon Wyman TEST_F(PowerSupplyTests, UpdateHistory) 2096c3324424SBrandon Wyman { 2097c3324424SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2098*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 7, 0x6e, 2099*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 2100c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2101c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 0); 2102c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 2103c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 2104c3324424SBrandon Wyman // Always return 1 to indicate present. 2105c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 2106c3324424SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2107c3324424SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2108ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 2109ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 2110ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 2111ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2112ae35ac5dSBrandon Wyman .Times(1) 2113ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 2114c3324424SBrandon Wyman PMBusExpectations expectations; 2115c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2116c3324424SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2117c3324424SBrandon Wyman .Times(6) 2118c3324424SBrandon Wyman .WillRepeatedly(Return("205000")); 2119c3324424SBrandon Wyman EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 2120c3324424SBrandon Wyman // First read after missing/present will have no data. 2121c3324424SBrandon Wyman std::vector<uint8_t> emptyHistory{}; 2122c3324424SBrandon Wyman // Second read, after about 30 seconds, should have a record. 5-bytes. 2123c3324424SBrandon Wyman // Sequence Number: 0x00, Average: 0x50 0xf3 (212), Maximum: 0x54 0xf3 (213) 2124c3324424SBrandon Wyman std::vector<uint8_t> firstHistory{0x00, 0x50, 0xf3, 0x54, 0xf3}; 2125c3324424SBrandon Wyman // Third read, after about 60 seconds, should have two records, 10-bytes, 2126c3324424SBrandon Wyman // but only reading 5 bytes, so make sure new/next sequence number 2127c3324424SBrandon Wyman std::vector<uint8_t> secondHistory{0x01, 0x54, 0xf3, 0x58, 0xf3}; 2128c3324424SBrandon Wyman // Fourth read, 3rd sequence number (0x02). 2129c3324424SBrandon Wyman std::vector<uint8_t> thirdHistory{0x02, 0x54, 0xf3, 0x58, 0xf3}; 2130c3324424SBrandon Wyman // Fifth read, out of sequence, clear and insert this one? 2131c3324424SBrandon Wyman std::vector<uint8_t> outseqHistory{0xff, 0x5c, 0xf3, 0x60, 0xf3}; 2132c3324424SBrandon Wyman EXPECT_CALL( 2133c3324424SBrandon Wyman mockPMBus, 2134c3324424SBrandon Wyman readBinary(INPUT_HISTORY, Type::HwmonDeviceDebug, 2135c3324424SBrandon Wyman phosphor::power::history::RecordManager::RAW_RECORD_SIZE)) 2136c3324424SBrandon Wyman .Times(6) 2137c3324424SBrandon Wyman .WillOnce(Return(emptyHistory)) 2138c3324424SBrandon Wyman .WillOnce(Return(firstHistory)) 2139c3324424SBrandon Wyman .WillOnce(Return(secondHistory)) 2140c3324424SBrandon Wyman .WillOnce(Return(thirdHistory)) 2141c3324424SBrandon Wyman .WillOnce(Return(outseqHistory)) 2142c3324424SBrandon Wyman .WillOnce(Return(emptyHistory)); 2143c3324424SBrandon Wyman // Calling analyze will update the presence, which will setup the input 2144c3324424SBrandon Wyman // history if the power supply went from missing to present. 2145c3324424SBrandon Wyman psu.analyze(); 2146c3324424SBrandon Wyman // The ibm-cffps power supply should support input history 2147c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2148c3324424SBrandon Wyman // Usually should have empty buffer right after missing to present. 2149c3324424SBrandon Wyman // Faked that out above with mocked readBinary with emptyHistory data. 2150c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 0); 2151c3324424SBrandon Wyman // Second run through... 2152c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2153c3324424SBrandon Wyman psu.analyze(); 2154c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2155c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 1); 2156c3324424SBrandon Wyman // Third run through 2157c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2158c3324424SBrandon Wyman psu.analyze(); 2159c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2160c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 2); 2161c3324424SBrandon Wyman // Fourth run through. Up to 3 records now? 2162c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2163c3324424SBrandon Wyman psu.analyze(); 2164c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2165c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 3); 2166c3324424SBrandon Wyman // Out of sequencer, reset, insert new one. 2167c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2168c3324424SBrandon Wyman psu.analyze(); 2169c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2170c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 1); 2171c3324424SBrandon Wyman // Empty one after last one good. Reset/clear. 2172c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2173c3324424SBrandon Wyman psu.analyze(); 2174c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2175c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 0); 2176c3324424SBrandon Wyman } 217718a24d92SBrandon Wyman 217818a24d92SBrandon Wyman TEST_F(PowerSupplyTests, IsSyncHistoryRequired) 217918a24d92SBrandon Wyman { 218018a24d92SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2181*9464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 8, 0x6f, 2182*9464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 218318a24d92SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 218418a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), false); 218518a24d92SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 218618a24d92SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 218718a24d92SBrandon Wyman // Always return 1 to indicate present. 218818a24d92SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 218918a24d92SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 219018a24d92SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2191ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 2192ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 2193ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 2194ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2195ae35ac5dSBrandon Wyman .Times(1) 2196ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 219718a24d92SBrandon Wyman PMBusExpectations expectations; 219818a24d92SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 219918a24d92SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 220018a24d92SBrandon Wyman .Times(1) 220118a24d92SBrandon Wyman .WillRepeatedly(Return("205000")); 220218a24d92SBrandon Wyman EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 220318a24d92SBrandon Wyman psu.analyze(); 220418a24d92SBrandon Wyman // The ibm-cffps power supply should support input history 220518a24d92SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 220618a24d92SBrandon Wyman // Missing -> Present requires history sync 220718a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), true); 220818a24d92SBrandon Wyman psu.clearSyncHistoryRequired(); 220918a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), false); 221018a24d92SBrandon Wyman } 2211