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; 19*592bd27cSMatt Spinler using ::testing::IsNan; 2059a35793SBrandon Wyman using ::testing::NotNull; 213f1242f3SBrandon Wyman using ::testing::Return; 223f1242f3SBrandon Wyman using ::testing::StrEq; 233f1242f3SBrandon Wyman 243f1242f3SBrandon Wyman static auto PSUInventoryPath = "/xyz/bmc/inv/sys/chassis/board/powersupply0"; 25681b2a36SB. J. Wyman static auto PSUGPIOLineName = "presence-ps0"; 269464c429SGeorge Liu static auto isPowerOn = []() { return true; }; 273f1242f3SBrandon Wyman 28b654c619SBrandon Wyman struct PMBusExpectations 29b654c619SBrandon Wyman { 30b654c619SBrandon Wyman uint16_t statusWordValue{0x0000}; 31b654c619SBrandon Wyman uint8_t statusInputValue{0x00}; 32b654c619SBrandon Wyman uint8_t statusMFRValue{0x00}; 33b654c619SBrandon Wyman uint8_t statusCMLValue{0x00}; 34b654c619SBrandon Wyman uint8_t statusVOUTValue{0x00}; 35b10b3be0SBrandon Wyman uint8_t statusIOUTValue{0x00}; 367ee4d7e4SBrandon Wyman uint8_t statusFans12Value{0x00}; 3796893a46SBrandon Wyman uint8_t statusTempValue{0x00}; 38b654c619SBrandon Wyman }; 39b654c619SBrandon Wyman 408da35c51SBrandon Wyman // Helper function to setup expectations for various STATUS_* commands 41b654c619SBrandon Wyman void setPMBusExpectations(MockedPMBus& mockPMBus, 42b654c619SBrandon Wyman const PMBusExpectations& expectations) 438da35c51SBrandon Wyman { 4432453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _, _)) 458da35c51SBrandon Wyman .Times(1) 46b654c619SBrandon Wyman .WillOnce(Return(expectations.statusWordValue)); 478da35c51SBrandon Wyman 48b654c619SBrandon Wyman if (expectations.statusWordValue != 0) 498da35c51SBrandon Wyman { 508da35c51SBrandon Wyman // If fault bits are on in STATUS_WORD, there will also be a read of 5196893a46SBrandon Wyman // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT (page 0), and 5296893a46SBrandon Wyman // STATUS_TEMPERATURE. 5332453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _, _)) 548da35c51SBrandon Wyman .Times(1) 55b654c619SBrandon Wyman .WillOnce(Return(expectations.statusInputValue)); 5632453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _, _)) 578da35c51SBrandon Wyman .Times(1) 58b654c619SBrandon Wyman .WillOnce(Return(expectations.statusMFRValue)); 5932453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _, _)) 608da35c51SBrandon Wyman .Times(1) 61b654c619SBrandon Wyman .WillOnce(Return(expectations.statusCMLValue)); 626710ba2cSBrandon Wyman // Page will need to be set to 0 to read STATUS_VOUT. 636710ba2cSBrandon Wyman EXPECT_CALL(mockPMBus, insertPageNum(STATUS_VOUT, 0)) 646710ba2cSBrandon Wyman .Times(1) 656710ba2cSBrandon Wyman .WillOnce(Return("status0_vout")); 6632453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read("status0_vout", _, _)) 676710ba2cSBrandon Wyman .Times(1) 68b654c619SBrandon Wyman .WillOnce(Return(expectations.statusVOUTValue)); 6932453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_IOUT, _, _)) 70b10b3be0SBrandon Wyman .Times(1) 71b10b3be0SBrandon Wyman .WillOnce(Return(expectations.statusIOUTValue)); 7232453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_FANS_1_2, _, _)) 737ee4d7e4SBrandon Wyman .Times(1) 747ee4d7e4SBrandon Wyman .WillOnce(Return(expectations.statusFans12Value)); 7532453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_TEMPERATURE, _, _)) 7696893a46SBrandon Wyman .Times(1) 7796893a46SBrandon Wyman .WillOnce(Return(expectations.statusTempValue)); 788da35c51SBrandon Wyman } 79*592bd27cSMatt Spinler 80*592bd27cSMatt Spinler // Default max/peak is 213W 81*592bd27cSMatt Spinler ON_CALL(mockPMBus, readBinary(INPUT_HISTORY, Type::HwmonDeviceDebug, 5)) 82*592bd27cSMatt Spinler .WillByDefault( 83*592bd27cSMatt Spinler Return(std::vector<uint8_t>{0x01, 0x5c, 0xf3, 0x54, 0xf3})); 848da35c51SBrandon Wyman } 858da35c51SBrandon Wyman 863f1242f3SBrandon Wyman class PowerSupplyTests : public ::testing::Test 873f1242f3SBrandon Wyman { 883f1242f3SBrandon Wyman public: 893f1242f3SBrandon Wyman PowerSupplyTests() : 903f1242f3SBrandon Wyman mockedUtil(reinterpret_cast<const MockedUtil&>(getUtils())) 913f1242f3SBrandon Wyman { 923f1242f3SBrandon Wyman ON_CALL(mockedUtil, getPresence(_, _)).WillByDefault(Return(false)); 933f1242f3SBrandon Wyman } 943f1242f3SBrandon Wyman 953f1242f3SBrandon Wyman ~PowerSupplyTests() override 963f1242f3SBrandon Wyman { 973f1242f3SBrandon Wyman freeUtils(); 983f1242f3SBrandon Wyman } 993f1242f3SBrandon Wyman 1003f1242f3SBrandon Wyman const MockedUtil& mockedUtil; 1013f1242f3SBrandon Wyman }; 1023f1242f3SBrandon Wyman 103391a0690SBrandon Wyman // Helper function for when a power supply goes from missing to present. 104391a0690SBrandon Wyman void setMissingToPresentExpects(MockedPMBus& pmbus, const MockedUtil& util) 105391a0690SBrandon Wyman { 106391a0690SBrandon Wyman // Call to analyze() will update to present, that will trigger updating 107391a0690SBrandon Wyman // to the correct/latest HWMON directory, in case it changes. 108391a0690SBrandon Wyman EXPECT_CALL(pmbus, findHwmonDir()); 109391a0690SBrandon Wyman // Presence change from missing to present will trigger write to 110391a0690SBrandon Wyman // ON_OFF_CONFIG. 111391a0690SBrandon Wyman EXPECT_CALL(pmbus, writeBinary(ON_OFF_CONFIG, _, _)); 112391a0690SBrandon Wyman // Presence change from missing to present will trigger in1_input read 113391a0690SBrandon Wyman // in an attempt to get CLEAR_FAULTS called. 11482affd94SBrandon Wyman // This READ_VIN for CLEAR_FAULTS does not check the returned value. 1153225a45cSBrandon Wyman EXPECT_CALL(pmbus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 1163225a45cSBrandon Wyman // The call for clearing faults includes clearing VIN_UV fault. 1173225a45cSBrandon Wyman // The voltage defaults to 0, the first call to analyze should update the 1183225a45cSBrandon Wyman // voltage to the current reading, triggering clearing VIN_UV fault(s) 1193225a45cSBrandon Wyman // due to below minimum to within range voltage. 1203225a45cSBrandon Wyman EXPECT_CALL(pmbus, read("in1_lcrit_alarm", _, _)) 12182affd94SBrandon Wyman .Times(2) 1223225a45cSBrandon Wyman .WillRepeatedly(Return(1)); 123391a0690SBrandon Wyman // Missing/present call will update Presence in inventory. 124391a0690SBrandon Wyman EXPECT_CALL(util, setPresence(_, _, true, _)); 125391a0690SBrandon Wyman } 126391a0690SBrandon Wyman 1273f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Constructor) 1283f1242f3SBrandon Wyman { 1293f1242f3SBrandon Wyman /** 1303f1242f3SBrandon Wyman * @param[in] invpath - String for inventory path to use 1313f1242f3SBrandon Wyman * @param[in] i2cbus - The bus number this power supply is on 1323f1242f3SBrandon Wyman * @param[in] i2caddr - The 16-bit I2C address of the power supply 133681b2a36SB. J. Wyman * @param[in] gpioLineName - The string for the gpio-line-name to read for 134681b2a36SB. J. Wyman * presence. 135681b2a36SB. J. Wyman * @param[in] bindDelay - Time in milliseconds to delay binding the device 136681b2a36SB. J. Wyman * driver after seeing the presence line go active. 1373f1242f3SBrandon Wyman */ 1383f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1391d7a7df8SBrandon Wyman 1401d7a7df8SBrandon Wyman // Try where inventory path is empty, constructor should fail. 1411d7a7df8SBrandon Wyman try 1421d7a7df8SBrandon Wyman { 143c3324424SBrandon Wyman auto psu = std::make_unique<PowerSupply>(bus, "", 3, 0x68, "ibm-cffps", 1449464c429SGeorge Liu PSUGPIOLineName, isPowerOn); 1451d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have reached this line."; 1461d7a7df8SBrandon Wyman } 1471d7a7df8SBrandon Wyman catch (const std::invalid_argument& e) 1481d7a7df8SBrandon Wyman { 1491d7a7df8SBrandon Wyman EXPECT_STREQ(e.what(), "Invalid empty inventoryPath"); 1501d7a7df8SBrandon Wyman } 1511d7a7df8SBrandon Wyman catch (...) 1521d7a7df8SBrandon Wyman { 1531d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 1541d7a7df8SBrandon Wyman } 1551d7a7df8SBrandon Wyman 156681b2a36SB. J. Wyman // TODO: Try invalid i2c address? 157681b2a36SB. J. Wyman 158681b2a36SB. J. Wyman // Try where gpioLineName is empty. 1591d7a7df8SBrandon Wyman try 1601d7a7df8SBrandon Wyman { 161c3324424SBrandon Wyman auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, 1629464c429SGeorge Liu "ibm-cffps", "", isPowerOn); 163681b2a36SB. J. Wyman ADD_FAILURE() 164681b2a36SB. J. Wyman << "Should not have reached this line. Invalid gpioLineName."; 165681b2a36SB. J. Wyman } 166681b2a36SB. J. Wyman catch (const std::invalid_argument& e) 167681b2a36SB. J. Wyman { 168681b2a36SB. J. Wyman EXPECT_STREQ(e.what(), "Invalid empty gpioLineName"); 169681b2a36SB. J. Wyman } 170681b2a36SB. J. Wyman catch (...) 171681b2a36SB. J. Wyman { 172681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 173681b2a36SB. J. Wyman } 174681b2a36SB. J. Wyman 175681b2a36SB. J. Wyman // Test with valid arguments 176681b2a36SB. J. Wyman // NOT using D-Bus inventory path for presence. 177681b2a36SB. J. Wyman try 178681b2a36SB. J. Wyman { 179681b2a36SB. J. Wyman auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, 1809464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, 1819464c429SGeorge Liu isPowerOn); 1823f1242f3SBrandon Wyman 1833f1242f3SBrandon Wyman EXPECT_EQ(psu->isPresent(), false); 1843f1242f3SBrandon Wyman EXPECT_EQ(psu->isFaulted(), false); 1858da35c51SBrandon Wyman EXPECT_EQ(psu->hasCommFault(), false); 1863f1242f3SBrandon Wyman EXPECT_EQ(psu->hasInputFault(), false); 1873f1242f3SBrandon Wyman EXPECT_EQ(psu->hasMFRFault(), false); 1883f1242f3SBrandon Wyman EXPECT_EQ(psu->hasVINUVFault(), false); 1896710ba2cSBrandon Wyman EXPECT_EQ(psu->hasVoutOVFault(), false); 190b10b3be0SBrandon Wyman EXPECT_EQ(psu->hasIoutOCFault(), false); 1912cf46945SBrandon Wyman EXPECT_EQ(psu->hasVoutUVFault(), false); 1927ee4d7e4SBrandon Wyman EXPECT_EQ(psu->hasFanFault(), false); 19396893a46SBrandon Wyman EXPECT_EQ(psu->hasTempFault(), false); 1942916ea52SBrandon Wyman EXPECT_EQ(psu->hasPgoodFault(), false); 19539ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPSKillFault(), false); 19639ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPS12VcsFault(), false); 19739ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPSCS12VFault(), false); 1983f1242f3SBrandon Wyman } 1991d7a7df8SBrandon Wyman catch (...) 2001d7a7df8SBrandon Wyman { 2011d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 2021d7a7df8SBrandon Wyman } 203681b2a36SB. J. Wyman 204681b2a36SB. J. Wyman // Test with valid arguments 205681b2a36SB. J. Wyman // TODO: Using D-Bus inventory path for presence. 206681b2a36SB. J. Wyman try 207681b2a36SB. J. Wyman { 208681b2a36SB. J. Wyman // FIXME: How do I get that presenceGPIO.read() in the startup to throw 209681b2a36SB. J. Wyman // an exception? 210681b2a36SB. J. Wyman 211681b2a36SB. J. Wyman // EXPECT_CALL(mockedUtil, getPresence(_, 212681b2a36SB. J. Wyman // StrEq(PSUInventoryPath))) 213681b2a36SB. J. Wyman // .Times(1); 214681b2a36SB. J. Wyman } 215681b2a36SB. J. Wyman catch (...) 216681b2a36SB. J. Wyman { 217681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 218681b2a36SB. J. Wyman } 2191d7a7df8SBrandon Wyman } 2203f1242f3SBrandon Wyman 2213f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Analyze) 2223f1242f3SBrandon Wyman { 2233f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2243f1242f3SBrandon Wyman 225b654c619SBrandon Wyman { 226681b2a36SB. J. Wyman // If I default to reading the GPIO, I will NOT expect a call to 227681b2a36SB. J. Wyman // getPresence(). 228681b2a36SB. J. Wyman 2299464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, 2309464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 2313ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 2323ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 233681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0)); 234681b2a36SB. J. Wyman 2353f1242f3SBrandon Wyman psu.analyze(); 2363f1242f3SBrandon Wyman // By default, nothing should change. 2373f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 2383f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 2393f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 2403f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 2413f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 24285c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 2436710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 244b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 2452cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 2467ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 24796893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 2482916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 24939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 25039ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 25139ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 252b654c619SBrandon Wyman } 2533f1242f3SBrandon Wyman 2549464c429SGeorge Liu PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, 2559464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 256681b2a36SB. J. Wyman // In order to get the various faults tested, the power supply needs to 257681b2a36SB. J. Wyman // be present in order to read from the PMBus device(s). 2583ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO2 = 2593ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO()); 26006ca4590SBrandon Wyman // Always return 1 to indicate present. 26106ca4590SBrandon Wyman // Each analyze() call will trigger a read of the presence GPIO. 26206ca4590SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO2, read()).WillRepeatedly(Return(1)); 263681b2a36SB. J. Wyman EXPECT_EQ(psu2.isPresent(), false); 2643f1242f3SBrandon Wyman 2653f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus()); 266391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 267ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 268ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 269ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 270ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 271*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 272b654c619SBrandon Wyman 273b654c619SBrandon Wyman // STATUS_WORD INPUT fault. 274b654c619SBrandon Wyman { 275b654c619SBrandon Wyman // Start with STATUS_WORD 0x0000. Powered on, no faults. 276b654c619SBrandon Wyman // Set expectations for a no fault 277b654c619SBrandon Wyman PMBusExpectations expectations; 278b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 27982affd94SBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 28082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 28182affd94SBrandon Wyman .Times(1) 28282affd94SBrandon Wyman .WillOnce(Return("206000")); 2833f1242f3SBrandon Wyman psu2.analyze(); 2843f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2853f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 2863f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 2873f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 2883f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 28985c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 2906710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 291b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 2922cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 2937ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 29496893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 2952916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 29639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 29739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 29839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 2993f1242f3SBrandon Wyman 300b654c619SBrandon Wyman // Update expectations for STATUS_WORD input fault/warn 30196893a46SBrandon Wyman // STATUS_INPUT fault bits ... on. 302b654c619SBrandon Wyman expectations.statusWordValue = (status_word::INPUT_FAULT_WARN); 3033225a45cSBrandon Wyman // IIN_OC fault. 3043225a45cSBrandon Wyman expectations.statusInputValue = 0x04; 305c2906f47SBrandon Wyman 306c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 307c2906f47SBrandon Wyman { 308b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 30982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 31082affd94SBrandon Wyman .Times(1) 31182affd94SBrandon Wyman .WillOnce(Return("207000")); 3123f1242f3SBrandon Wyman psu2.analyze(); 3133f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 314c2906f47SBrandon Wyman // Should not be faulted until it reaches the deglitch limit. 315c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 316c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT); 3173f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 3183f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 31985c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 3206710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 321b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 3222cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 3237ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 32496893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 3252916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 32639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 32739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 32839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 329b654c619SBrandon Wyman } 330c2906f47SBrandon Wyman } 331c2906f47SBrandon Wyman 33232453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 3333225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 3343225a45cSBrandon Wyman .Times(1) 3353225a45cSBrandon Wyman .WillOnce(Return(1)); 336c2906f47SBrandon Wyman psu2.clearFaults(); 3373f1242f3SBrandon Wyman 3383f1242f3SBrandon Wyman // STATUS_WORD INPUT/UV fault. 339b654c619SBrandon Wyman { 3403f1242f3SBrandon Wyman // First need it to return good status, then the fault 341b654c619SBrandon Wyman PMBusExpectations expectations; 342b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 34382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 34482affd94SBrandon Wyman .Times(1) 34582affd94SBrandon Wyman .WillOnce(Return("208000")); 3463f1242f3SBrandon Wyman psu2.analyze(); 347c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 348c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 3498da35c51SBrandon Wyman // Now set fault bits in STATUS_WORD 350b654c619SBrandon Wyman expectations.statusWordValue = 3518da35c51SBrandon Wyman (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT); 3528da35c51SBrandon Wyman // STATUS_INPUT fault bits ... on. 3533225a45cSBrandon Wyman expectations.statusInputValue = 0x18; 354c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 355c2906f47SBrandon Wyman { 356b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 35782affd94SBrandon Wyman // Input/UV fault, so voltage should read back low. 35882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 35982affd94SBrandon Wyman .Times(1) 36082affd94SBrandon Wyman .WillOnce(Return("19123")); 3613f1242f3SBrandon Wyman psu2.analyze(); 3623f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 363c2906f47SBrandon Wyman // Only faulted if hit deglitch limit 364c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 365c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT); 366c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), x >= DEGLITCH_LIMIT); 3673f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 36885c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 3696710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 370b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 3712cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 3727ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 37396893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 3742916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 37539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 37639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 37739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 378c2906f47SBrandon Wyman } 37982affd94SBrandon Wyman // Turning VIN_UV fault off causes clearing of faults, causing read of 38082affd94SBrandon Wyman // in1_input as an attempt to get CLEAR_FAULTS called. 38182affd94SBrandon Wyman expectations.statusWordValue = 0; 38282affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 38382affd94SBrandon Wyman // The call to read the voltage 38482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 38582affd94SBrandon Wyman .Times(1) 38682affd94SBrandon Wyman .WillOnce(Return("209000")); 3873225a45cSBrandon Wyman // The call to clear VIN_UV/Off fault(s) 3883225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 38932453e9bSBrandon Wyman .Times(1) 3903225a45cSBrandon Wyman .WillOnce(Return(1)); 39182affd94SBrandon Wyman psu2.analyze(); 39282affd94SBrandon Wyman // Should remain present, no longer be faulted, no input fault, no 39382affd94SBrandon Wyman // VIN_UV fault. Nothing else should change. 39482affd94SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 39582affd94SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 39682affd94SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 39782affd94SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 398b654c619SBrandon Wyman } 3993f1242f3SBrandon Wyman 40032453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 4013225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 4023225a45cSBrandon Wyman .Times(1) 4033225a45cSBrandon Wyman .WillOnce(Return(1)); 404c2906f47SBrandon Wyman psu2.clearFaults(); 405c2906f47SBrandon Wyman 4063f1242f3SBrandon Wyman // STATUS_WORD MFR fault. 407b654c619SBrandon Wyman { 408f07bc797SBrandon Wyman // First need it to return good status, then the fault 409b654c619SBrandon Wyman PMBusExpectations expectations; 410b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 41182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 41282affd94SBrandon Wyman .Times(1) 41382affd94SBrandon Wyman .WillOnce(Return("210000")); 4143f1242f3SBrandon Wyman psu2.analyze(); 4158da35c51SBrandon Wyman // Now STATUS_WORD with MFR fault bit on. 416b654c619SBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 4178da35c51SBrandon Wyman // STATUS_MFR bits on. 418b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 419c2906f47SBrandon Wyman 420c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 421c2906f47SBrandon Wyman { 422b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 42382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 42482affd94SBrandon Wyman .Times(1) 42582affd94SBrandon Wyman .WillOnce(Return("211000")); 4263f1242f3SBrandon Wyman psu2.analyze(); 4273f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 428c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 4293f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 430c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), x >= DEGLITCH_LIMIT); 431c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), x >= DEGLITCH_LIMIT); 432c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 433c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 4343f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 43585c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 4366710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 437b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 4382cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 4397ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 44096893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 4412916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 442c2906f47SBrandon Wyman } 443b654c619SBrandon Wyman } 4443f1242f3SBrandon Wyman 44532453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 4463225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 4473225a45cSBrandon Wyman .Times(1) 4483225a45cSBrandon Wyman .WillOnce(Return(1)); 449c2906f47SBrandon Wyman psu2.clearFaults(); 4503225a45cSBrandon Wyman 45196893a46SBrandon Wyman // Temperature fault. 452b654c619SBrandon Wyman { 453f07bc797SBrandon Wyman // First STATUS_WORD with no bits set, then with temperature fault. 454b654c619SBrandon Wyman PMBusExpectations expectations; 455b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 45682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 45782affd94SBrandon Wyman .Times(1) 45882affd94SBrandon Wyman .WillOnce(Return("212000")); 4593f1242f3SBrandon Wyman psu2.analyze(); 4608da35c51SBrandon Wyman // STATUS_WORD with temperature fault bit on. 461b654c619SBrandon Wyman expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 46296893a46SBrandon Wyman // STATUS_TEMPERATURE with fault bit(s) on. 46396893a46SBrandon Wyman expectations.statusTempValue = 0x10; 464c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 465c2906f47SBrandon Wyman { 466b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 46782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 46882affd94SBrandon Wyman .Times(1) 46982affd94SBrandon Wyman .WillOnce(Return("213000")); 4703f1242f3SBrandon Wyman psu2.analyze(); 4713f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 472c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 4733f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 4743f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 4753f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 47685c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 4776710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 478b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 4792cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 4807ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 481c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), x >= DEGLITCH_LIMIT); 4822916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 48339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 48439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 48539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 486b654c619SBrandon Wyman } 487c2906f47SBrandon Wyman } 48885c7bf41SBrandon Wyman 48932453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 4903225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 4913225a45cSBrandon Wyman .Times(1) 4923225a45cSBrandon Wyman .WillOnce(Return(1)); 493c2906f47SBrandon Wyman psu2.clearFaults(); 4943225a45cSBrandon Wyman 49585c7bf41SBrandon Wyman // CML fault 496b654c619SBrandon Wyman { 49785c7bf41SBrandon Wyman // First STATUS_WORD wit no bits set, then with CML fault. 498b654c619SBrandon Wyman PMBusExpectations expectations; 499b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 50082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 50182affd94SBrandon Wyman .Times(1) 50282affd94SBrandon Wyman .WillOnce(Return("214000")); 50385c7bf41SBrandon Wyman psu2.analyze(); 5048da35c51SBrandon Wyman // STATUS_WORD with CML fault bit on. 505b654c619SBrandon Wyman expectations.statusWordValue = (status_word::CML_FAULT); 50685c7bf41SBrandon Wyman // Turn on STATUS_CML fault bit(s) 507b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 508c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 509c2906f47SBrandon Wyman { 510b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 51182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 51282affd94SBrandon Wyman .Times(1) 51382affd94SBrandon Wyman .WillOnce(Return("215000")); 51485c7bf41SBrandon Wyman psu2.analyze(); 51585c7bf41SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 516c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 517c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), x >= DEGLITCH_LIMIT); 51885c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 51985c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 52085c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 5216710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 522b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 5232cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 5247ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 52596893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 5262916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 52739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 52839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 52939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 530b654c619SBrandon Wyman } 531c2906f47SBrandon Wyman } 5326710ba2cSBrandon Wyman 53332453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 5343225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 5353225a45cSBrandon Wyman .Times(1) 5363225a45cSBrandon Wyman .WillOnce(Return(1)); 537c2906f47SBrandon Wyman psu2.clearFaults(); 5383225a45cSBrandon Wyman 5396710ba2cSBrandon Wyman // VOUT_OV_FAULT fault 540b654c619SBrandon Wyman { 5416710ba2cSBrandon Wyman // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault. 542b654c619SBrandon Wyman PMBusExpectations expectations; 543b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 54482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 54582affd94SBrandon Wyman .Times(1) 54682affd94SBrandon Wyman .WillOnce(Return("216000")); 5476710ba2cSBrandon Wyman psu2.analyze(); 5486710ba2cSBrandon Wyman // STATUS_WORD with VOUT/VOUT_OV fault. 549b654c619SBrandon Wyman expectations.statusWordValue = 5506710ba2cSBrandon Wyman ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT)); 5516710ba2cSBrandon Wyman // Turn on STATUS_VOUT fault bit(s) 552b654c619SBrandon Wyman expectations.statusVOUTValue = 0xA0; 553c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 554c2906f47SBrandon Wyman { 55596893a46SBrandon Wyman // STATUS_TEMPERATURE don't care (default) 556b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 55782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 55882affd94SBrandon Wyman .Times(1) 55982affd94SBrandon Wyman .WillOnce(Return("217000")); 5606710ba2cSBrandon Wyman psu2.analyze(); 5616710ba2cSBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 562c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 5636710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 5646710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 5656710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 5666710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 567c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 5682cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 569b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 5707ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 571b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 572b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 57339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 57439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 57539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 576b10b3be0SBrandon Wyman } 577c2906f47SBrandon Wyman } 578b10b3be0SBrandon Wyman 579b10b3be0SBrandon Wyman // IOUT_OC_FAULT fault 580b10b3be0SBrandon Wyman { 581b10b3be0SBrandon Wyman // First STATUS_WORD with no bits set, then with IOUT_OC fault. 582b10b3be0SBrandon Wyman PMBusExpectations expectations; 583b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 58482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 58582affd94SBrandon Wyman .Times(1) 58682affd94SBrandon Wyman .WillOnce(Return("218000")); 587b10b3be0SBrandon Wyman psu2.analyze(); 588b10b3be0SBrandon Wyman // STATUS_WORD with IOUT_OC fault. 589b10b3be0SBrandon Wyman expectations.statusWordValue = status_word::IOUT_OC_FAULT; 590b10b3be0SBrandon Wyman // Turn on STATUS_IOUT fault bit(s) 591b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0x88; 592c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 593c2906f47SBrandon Wyman { 594b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 59582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 59682affd94SBrandon Wyman .Times(1) 59782affd94SBrandon Wyman .WillOnce(Return("219000")); 598b10b3be0SBrandon Wyman psu2.analyze(); 599b10b3be0SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 600c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 601b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 602b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 603b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 604b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 605b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 606c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 6072cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 6087ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 6092cf46945SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6102cf46945SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 61139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 61239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 61339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 6142cf46945SBrandon Wyman } 615c2906f47SBrandon Wyman } 6162cf46945SBrandon Wyman 6172cf46945SBrandon Wyman // VOUT_UV_FAULT 6182cf46945SBrandon Wyman { 6192cf46945SBrandon Wyman // First STATUS_WORD with no bits set, then with VOUT fault. 6202cf46945SBrandon Wyman PMBusExpectations expectations; 6212cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 62282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 62382affd94SBrandon Wyman .Times(1) 62482affd94SBrandon Wyman .WillOnce(Return("220000")); 6252cf46945SBrandon Wyman psu2.analyze(); 6262cf46945SBrandon Wyman // Change STATUS_WORD to indicate VOUT fault. 6272cf46945SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_FAULT); 6282cf46945SBrandon Wyman // Turn on STATUS_VOUT fault bit(s) 6292cf46945SBrandon Wyman expectations.statusVOUTValue = 0x30; 630c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 631c2906f47SBrandon Wyman { 6322cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 63382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 63482affd94SBrandon Wyman .Times(1) 63582affd94SBrandon Wyman .WillOnce(Return("221000")); 6362cf46945SBrandon Wyman psu2.analyze(); 6372cf46945SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 638c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 6392cf46945SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 6402cf46945SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 6412cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 6422cf46945SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 6432cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 6442cf46945SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 645c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), x >= DEGLITCH_LIMIT); 6467ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 64796893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6482916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 64939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 65039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 65139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 652b654c619SBrandon Wyman } 653c2906f47SBrandon Wyman } 6543f1242f3SBrandon Wyman 6557ee4d7e4SBrandon Wyman // Fan fault 656b654c619SBrandon Wyman { 657b654c619SBrandon Wyman // First STATUS_WORD with no bits set, then with fan fault. 658b654c619SBrandon Wyman PMBusExpectations expectations; 659b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 66082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 66182affd94SBrandon Wyman .Times(1) 66282affd94SBrandon Wyman .WillOnce(Return("222000")); 6633f1242f3SBrandon Wyman psu2.analyze(); 664b654c619SBrandon Wyman expectations.statusWordValue = (status_word::FAN_FAULT); 6657ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with fan 1 warning & fault bits on. 6667ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xA0; 667c2906f47SBrandon Wyman 668c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 669c2906f47SBrandon Wyman { 670b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 67182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 67282affd94SBrandon Wyman .Times(1) 67382affd94SBrandon Wyman .WillOnce(Return("223000")); 6743f1242f3SBrandon Wyman psu2.analyze(); 6753f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 676c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 677c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), x >= DEGLITCH_LIMIT); 6783f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 6793f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 6803f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 68185c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 6826710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 683b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 6842cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 68596893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6862916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 68739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 68839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 68939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 690b654c619SBrandon Wyman } 691c2906f47SBrandon Wyman } 6922916ea52SBrandon Wyman 69306ca4590SBrandon Wyman // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT. 6942cf46945SBrandon Wyman { 6952916ea52SBrandon Wyman // First STATUS_WORD with no bits set. 6962916ea52SBrandon Wyman PMBusExpectations expectations; 6972916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 69882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 69982affd94SBrandon Wyman .Times(1) 70082affd94SBrandon Wyman .WillOnce(Return("123000")); 7012916ea52SBrandon Wyman psu2.analyze(); 7022916ea52SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 7032916ea52SBrandon Wyman // POWER_GOOD# inactive, and OFF bit on. 7042916ea52SBrandon Wyman expectations.statusWordValue = 7052916ea52SBrandon Wyman ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF)); 7066d469fd4SBrandon Wyman for (auto x = 1; x <= PGOOD_DEGLITCH_LIMIT; x++) 70706ca4590SBrandon Wyman { 7082916ea52SBrandon Wyman // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and 7092916ea52SBrandon Wyman // STATUS_TEMPERATURE: Don't care if bits set or not (defaults). 7102916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 71182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 71282affd94SBrandon Wyman .Times(1) 71382affd94SBrandon Wyman .WillOnce(Return("124000")); 7142916ea52SBrandon Wyman psu2.analyze(); 7152916ea52SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 7166d469fd4SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= PGOOD_DEGLITCH_LIMIT); 7172916ea52SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 7182916ea52SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 7192916ea52SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 7202916ea52SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 7212916ea52SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 7222cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 723b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 7247ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 7252916ea52SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 7266d469fd4SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), x >= PGOOD_DEGLITCH_LIMIT); 72706ca4590SBrandon Wyman } 72806ca4590SBrandon Wyman } 7292916ea52SBrandon Wyman 7303f1242f3SBrandon Wyman // TODO: ReadFailure 7313f1242f3SBrandon Wyman } 7323f1242f3SBrandon Wyman 73359a35793SBrandon Wyman TEST_F(PowerSupplyTests, OnOffConfig) 73459a35793SBrandon Wyman { 73559a35793SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 73659a35793SBrandon Wyman uint8_t data = 0x15; 73759a35793SBrandon Wyman 73859a35793SBrandon Wyman // Test where PSU is NOT present 73959a35793SBrandon Wyman try 74059a35793SBrandon Wyman { 741681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 7420975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, _)).Times(0); 7439464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, 7449464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 745681b2a36SB. J. Wyman 7463ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7473ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 748681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0)); 74959a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 750681b2a36SB. J. Wyman // Constructor should set initial presence, default read returns 0. 75159a35793SBrandon Wyman // If it is not present, I should not be trying to write to it. 75259a35793SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0); 75359a35793SBrandon Wyman psu.onOffConfig(data); 75459a35793SBrandon Wyman } 75559a35793SBrandon Wyman catch (...) 7560c9a33d6SAdriana Kobylak {} 75759a35793SBrandon Wyman 75859a35793SBrandon Wyman // Test where PSU is present 75959a35793SBrandon Wyman try 76059a35793SBrandon Wyman { 761681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 7620975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 7639464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, 7649464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 7653ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7663ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 767391a0690SBrandon Wyman // There will potentially be multiple calls, we want it to continue 768391a0690SBrandon Wyman // returning 1 for the GPIO read to keep the power supply present. 769391a0690SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 77059a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 771391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 772ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 773ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 774ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 775ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 776*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 777391a0690SBrandon Wyman // If I am calling analyze(), I should probably give it good data. 778391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 779391a0690SBrandon Wyman PMBusExpectations expectations; 780391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 78182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 78282affd94SBrandon Wyman .Times(1) 78382affd94SBrandon Wyman .WillOnce(Return("205000")); 784681b2a36SB. J. Wyman psu.analyze(); 785391a0690SBrandon Wyman // I definitely should be writting ON_OFF_CONFIG if I call the function 786391a0690SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, ElementsAre(0x15), 787391a0690SBrandon Wyman Type::HwmonDeviceDebug)) 78859a35793SBrandon Wyman .Times(1); 78959a35793SBrandon Wyman psu.onOffConfig(data); 79059a35793SBrandon Wyman } 79159a35793SBrandon Wyman catch (...) 7920c9a33d6SAdriana Kobylak {} 79359a35793SBrandon Wyman } 79459a35793SBrandon Wyman 7953f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, ClearFaults) 7963f1242f3SBrandon Wyman { 7973f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 7989464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, 7999464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 8003ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 8013ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 80206ca4590SBrandon Wyman // Always return 1 to indicate present. 80306ca4590SBrandon Wyman // Each analyze() call will trigger a read of the presence GPIO. 80406ca4590SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 805681b2a36SB. J. Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 806391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 807ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 808ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 809ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 810ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 811*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 8128da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 813b654c619SBrandon Wyman PMBusExpectations expectations; 814b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 81582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 81682affd94SBrandon Wyman .Times(1) 81782affd94SBrandon Wyman .WillOnce(Return("207000")); 818681b2a36SB. J. Wyman psu.analyze(); 8193f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8203f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 8213f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 8223f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 8233f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 82485c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 8256710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 826b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 8272cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 8287ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 82996893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 8302916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 83139ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 83239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 83339ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 834b654c619SBrandon Wyman 835f07bc797SBrandon Wyman // STATUS_WORD with fault bits galore! 836b654c619SBrandon Wyman expectations.statusWordValue = 0xFFFF; 837f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 838b654c619SBrandon Wyman expectations.statusInputValue = 0xFF; 839f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 840b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 84185c7bf41SBrandon Wyman // STATUS_CML with bits on. 842b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 8436710ba2cSBrandon Wyman // STATUS_VOUT with bits on. 844b654c619SBrandon Wyman expectations.statusVOUTValue = 0xFF; 845b10b3be0SBrandon Wyman // STATUS_IOUT with bits on. 846b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0xFF; 8477ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with bits on. 8487ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xFF; 84996893a46SBrandon Wyman // STATUS_TEMPERATURE with bits on. 85096893a46SBrandon Wyman expectations.statusTempValue = 0xFF; 851c2906f47SBrandon Wyman 8526d469fd4SBrandon Wyman for (auto x = 1; x <= PGOOD_DEGLITCH_LIMIT; x++) 853c2906f47SBrandon Wyman { 854b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 85582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 85682affd94SBrandon Wyman .Times(1) 85782affd94SBrandon Wyman .WillOnce(Return("0")); 8580975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 8590975eaf4SMatt Spinler { 8600975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 8610975eaf4SMatt Spinler } 8623f1242f3SBrandon Wyman psu.analyze(); 8633f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8642cf46945SBrandon Wyman // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT. 8652cf46945SBrandon Wyman // Rely on HasVoutUVFault() to verify this sets and clears. 8662cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 8676d469fd4SBrandon Wyman // pgoodFault at PGOOD_DEGLITCH_LIMIT, all other faults are deglitched 8686d469fd4SBrandon Wyman // up to DEGLITCH_LIMIT 869c2906f47SBrandon Wyman EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT); 870c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 871c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 872c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 873c2906f47SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), x >= DEGLITCH_LIMIT); 874c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 875c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 876c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 877c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 8786d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), x >= PGOOD_DEGLITCH_LIMIT); 879c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 880c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 881c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 882c2906f47SBrandon Wyman } 883c2906f47SBrandon Wyman 88432453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)) 88532453e9bSBrandon Wyman .Times(1) 88632453e9bSBrandon Wyman .WillOnce(Return(207000)); 8873225a45cSBrandon Wyman // Clearing VIN_UV fault via in1_lcrit_alarm 8883225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 8893225a45cSBrandon Wyman .Times(1) 8903225a45cSBrandon Wyman .WillOnce(Return(1)); 8910975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 8923f1242f3SBrandon Wyman psu.clearFaults(); 8933f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8943f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 8953f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 8963f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 8973f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 89885c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 8996710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 900b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 9012cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 9027ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 90396893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 9042916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 90539ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 90639ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 90739ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 908681b2a36SB. J. Wyman 90982affd94SBrandon Wyman // Faults clear on READ_VIN 0 -> !0 91082affd94SBrandon Wyman // STATUS_WORD with fault bits galore! 91182affd94SBrandon Wyman expectations.statusWordValue = 0xFFFF; 91282affd94SBrandon Wyman // STATUS_INPUT with fault bits on. 91382affd94SBrandon Wyman expectations.statusInputValue = 0xFF; 91482affd94SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 91582affd94SBrandon Wyman expectations.statusMFRValue = 0xFF; 91682affd94SBrandon Wyman // STATUS_CML with bits on. 91782affd94SBrandon Wyman expectations.statusCMLValue = 0xFF; 91882affd94SBrandon Wyman // STATUS_VOUT with bits on. 91982affd94SBrandon Wyman expectations.statusVOUTValue = 0xFF; 92082affd94SBrandon Wyman // STATUS_IOUT with bits on. 92182affd94SBrandon Wyman expectations.statusIOUTValue = 0xFF; 92282affd94SBrandon Wyman // STATUS_FANS_1_2 with bits on. 92382affd94SBrandon Wyman expectations.statusFans12Value = 0xFF; 92482affd94SBrandon Wyman // STATUS_TEMPERATURE with bits on. 92582affd94SBrandon Wyman expectations.statusTempValue = 0xFF; 926c2906f47SBrandon Wyman 9276d469fd4SBrandon Wyman // All faults deglitched now. Check for false before limit above. 928c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 929c2906f47SBrandon Wyman { 93082affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 93182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 93282affd94SBrandon Wyman .Times(1) 93382affd94SBrandon Wyman .WillOnce(Return("0")); 9340975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 9350975eaf4SMatt Spinler { 9360975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 9370975eaf4SMatt Spinler } 93882affd94SBrandon Wyman psu.analyze(); 939c2906f47SBrandon Wyman } 940c2906f47SBrandon Wyman 94182affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 94282affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 94382affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 94482affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 94582affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 94682affd94SBrandon Wyman // True due to CML fault bits on 94782affd94SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), true); 94882affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 94982affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), true); 95082affd94SBrandon Wyman // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT. 95182affd94SBrandon Wyman // Rely on HasVoutUVFault() to verify this sets and clears. 95282affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 95382affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), true); 95482affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), true); 9556d469fd4SBrandon Wyman // No PGOOD fault, as less than PGOOD_DEGLITCH_LIMIT 9566d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 95782affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), true); 95882affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), true); 95982affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), true); 96082affd94SBrandon Wyman // STATUS_WORD with INPUT/VIN_UV fault bits off. 96182affd94SBrandon Wyman expectations.statusWordValue = 0xDFF7; 96282affd94SBrandon Wyman // STATUS_INPUT with VIN_UV_WARNING, VIN_UV_FAULT, and Unit Off For 96382affd94SBrandon Wyman // Insufficient Input Voltage bits off. 96482affd94SBrandon Wyman expectations.statusInputValue = 0xC7; 96582affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 96682affd94SBrandon Wyman // READ_VIN back in range. 96782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 96882affd94SBrandon Wyman .Times(1) 96982affd94SBrandon Wyman .WillOnce(Return("206000")); 9703225a45cSBrandon Wyman // VIN_UV cleared via in1_lcrit_alarm when voltage back in range. 9713225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 9723225a45cSBrandon Wyman .Times(1) 9733225a45cSBrandon Wyman .WillOnce(Return(1)); 9743225a45cSBrandon Wyman psu.analyze(); 9753225a45cSBrandon Wyman // We only cleared the VIN_UV and OFF faults. 9763225a45cSBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 9773225a45cSBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 9783225a45cSBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 9793225a45cSBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 9803225a45cSBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 9813225a45cSBrandon Wyman EXPECT_EQ(psu.hasCommFault(), true); 9823225a45cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 9833225a45cSBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), true); 9843225a45cSBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 9853225a45cSBrandon Wyman EXPECT_EQ(psu.hasFanFault(), true); 9863225a45cSBrandon Wyman EXPECT_EQ(psu.hasTempFault(), true); 9876d469fd4SBrandon Wyman // No PGOOD fault, as less than PGOOD_DEGLITCH_LIMIT 9886d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 9893225a45cSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), true); 9903225a45cSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), true); 9913225a45cSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), true); 9923225a45cSBrandon Wyman 9933225a45cSBrandon Wyman // All faults cleared 9943225a45cSBrandon Wyman expectations = {0}; 9953225a45cSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 9963225a45cSBrandon Wyman // READ_VIN back in range. 9973225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 9983225a45cSBrandon Wyman .Times(1) 9993225a45cSBrandon Wyman .WillOnce(Return("206000")); 10000975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 100182affd94SBrandon Wyman psu.analyze(); 100282affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 100382affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 100482affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 100582affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 100682affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 100782affd94SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 100882affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 100982affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 101082affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 101182affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 101282affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 101382affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 101482affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 101582affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 101682affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 101782affd94SBrandon Wyman 1018681b2a36SB. J. Wyman // TODO: Faults clear on missing/present? 10193f1242f3SBrandon Wyman } 10203f1242f3SBrandon Wyman 10213f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory) 10223f1242f3SBrandon Wyman { 10233f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 10241d7a7df8SBrandon Wyman 10251d7a7df8SBrandon Wyman try 10261d7a7df8SBrandon Wyman { 10279464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 10289464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 10291d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 10301d7a7df8SBrandon Wyman // If it is not present, I should not be trying to read a string 10311d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).Times(0); 10321d7a7df8SBrandon Wyman psu.updateInventory(); 10331d7a7df8SBrandon Wyman } 10341d7a7df8SBrandon Wyman catch (...) 10351d7a7df8SBrandon Wyman { 10361d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 10371d7a7df8SBrandon Wyman } 10381d7a7df8SBrandon Wyman 10391d7a7df8SBrandon Wyman try 10401d7a7df8SBrandon Wyman { 10419464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, 10429464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 10433ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10443ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1045681b2a36SB. J. Wyman // GPIO read return 1 to indicate present. 1046681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 10471d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1048391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1049ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1050ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1051ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1052ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1053*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 1054391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1055391a0690SBrandon Wyman PMBusExpectations expectations; 1056391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 105782affd94SBrandon Wyman // Call to analyze will read voltage, trigger clear faults for 0 to 105882affd94SBrandon Wyman // within range. 105982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 106082affd94SBrandon Wyman .Times(1) 106182affd94SBrandon Wyman .WillOnce(Return("123456")); 1062391a0690SBrandon Wyman psu.analyze(); 10631d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return("")); 10643f1242f3SBrandon Wyman psu.updateInventory(); 10651d7a7df8SBrandon Wyman 10663c530fbdSBrandon Wyman #if IBM_VPD 10671d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)) 10681d7a7df8SBrandon Wyman .WillOnce(Return("CCIN")) 10691d7a7df8SBrandon Wyman .WillOnce(Return("PN3456")) 10701d7a7df8SBrandon Wyman .WillOnce(Return("FN3456")) 10711d7a7df8SBrandon Wyman .WillOnce(Return("HEADER")) 10721d7a7df8SBrandon Wyman .WillOnce(Return("SN3456")) 10731d7a7df8SBrandon Wyman .WillOnce(Return("FW3456")); 10743c530fbdSBrandon Wyman #endif 10751d7a7df8SBrandon Wyman psu.updateInventory(); 10761d7a7df8SBrandon Wyman // TODO: D-Bus mocking to verify values stored on D-Bus (???) 10771d7a7df8SBrandon Wyman } 10781d7a7df8SBrandon Wyman catch (...) 10791d7a7df8SBrandon Wyman { 10801d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 10811d7a7df8SBrandon Wyman } 10823f1242f3SBrandon Wyman } 10833f1242f3SBrandon Wyman 10843f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent) 10853f1242f3SBrandon Wyman { 10863f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1087681b2a36SB. J. Wyman 10889464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 10899464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 10903ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10913ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 10923f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 10933f1242f3SBrandon Wyman 1094681b2a36SB. J. Wyman // Change GPIO read to return 1 to indicate present. 1095681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 1096391a0690SBrandon Wyman // Call to analyze() will update to present, that will trigger updating 1097391a0690SBrandon Wyman // to the correct/latest HWMON directory, in case it changes. 1098391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1099391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1100ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1101ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1102ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1103ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1104*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 1105391a0690SBrandon Wyman // Call to analyze things will trigger read of STATUS_WORD and READ_VIN. 1106391a0690SBrandon Wyman // Default expectations will be on, no faults. 1107391a0690SBrandon Wyman PMBusExpectations expectations; 1108391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 110982affd94SBrandon Wyman // Give it an input voltage in the 100-volt range. 111082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 111182affd94SBrandon Wyman .Times(1) 111282affd94SBrandon Wyman .WillOnce(Return("123456")); 11130975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1114681b2a36SB. J. Wyman psu.analyze(); 1115681b2a36SB. J. Wyman EXPECT_EQ(psu.isPresent(), true); 11163f1242f3SBrandon Wyman } 11173f1242f3SBrandon Wyman 11183f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted) 11193f1242f3SBrandon Wyman { 11203f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1121681b2a36SB. J. Wyman 11229464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, 11239464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 11243ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 11253ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1126681b2a36SB. J. Wyman // Always return 1 to indicate present. 1127681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1128391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1129391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1130ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1131ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1132ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1133ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1134*592bd27cSMatt Spinler .WillRepeatedly(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 11819464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 11829464c429SGeorge 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, _)) 1193*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 11948da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1195b654c619SBrandon Wyman PMBusExpectations expectations; 1196b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 119782affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 119882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 119982affd94SBrandon Wyman .Times(1) 120082affd94SBrandon Wyman .WillOnce(Return("201100")); 12013f1242f3SBrandon Wyman psu.analyze(); 12023f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 1203f07bc797SBrandon Wyman // STATUS_WORD with input fault/warn on. 1204b654c619SBrandon Wyman expectations.statusWordValue = (status_word::INPUT_FAULT_WARN); 1205f07bc797SBrandon Wyman // STATUS_INPUT with an input fault bit on. 1206b654c619SBrandon Wyman expectations.statusInputValue = 0x80; 1207c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1208c2906f47SBrandon Wyman { 1209b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 121082affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 121182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 121282affd94SBrandon Wyman .Times(1) 121382affd94SBrandon Wyman .WillOnce(Return("201200")); 12140975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 12150975eaf4SMatt Spinler { 12160975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 12170975eaf4SMatt Spinler } 12183f1242f3SBrandon Wyman psu.analyze(); 1219c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 1220c2906f47SBrandon Wyman } 1221f07bc797SBrandon Wyman // STATUS_WORD with no bits on. 1222b654c619SBrandon Wyman expectations.statusWordValue = 0; 1223b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 122482affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 122582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 122682affd94SBrandon Wyman .Times(1) 122782affd94SBrandon Wyman .WillOnce(Return("201300")); 12280975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 12293f1242f3SBrandon Wyman psu.analyze(); 12303f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 12313f1242f3SBrandon Wyman } 12323f1242f3SBrandon Wyman 12333f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault) 12343f1242f3SBrandon Wyman { 12353f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1236681b2a36SB. J. Wyman 12379464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 12389464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 12393ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 12403ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1241681b2a36SB. J. Wyman // Always return 1 to indicate present. 1242681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 12433f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1244391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1245ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1246ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1247ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1248ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1249*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 1250f07bc797SBrandon Wyman // First return STATUS_WORD with no bits on. 12518da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1252b654c619SBrandon Wyman PMBusExpectations expectations; 1253b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 125482affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 125582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 125682affd94SBrandon Wyman .Times(1) 125782affd94SBrandon Wyman .WillOnce(Return("202100")); 12583f1242f3SBrandon Wyman psu.analyze(); 12593f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 1260f07bc797SBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 1261b654c619SBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 1262f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 1263b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 1264c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1265c2906f47SBrandon Wyman { 1266b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 126782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 126882affd94SBrandon Wyman .Times(1) 126982affd94SBrandon Wyman .WillOnce(Return("202200")); 12703f1242f3SBrandon Wyman psu.analyze(); 1271c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 1272c2906f47SBrandon Wyman } 1273f07bc797SBrandon Wyman // Back to no bits on in STATUS_WORD 1274b654c619SBrandon Wyman expectations.statusWordValue = 0; 1275b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 127682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 127782affd94SBrandon Wyman .Times(1) 127882affd94SBrandon Wyman .WillOnce(Return("202300")); 12793f1242f3SBrandon Wyman psu.analyze(); 12803f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 12813f1242f3SBrandon Wyman } 12823f1242f3SBrandon Wyman 12833f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault) 12843f1242f3SBrandon Wyman { 12853f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1286681b2a36SB. J. Wyman 12879464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 12889464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 12893ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 12903ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1291681b2a36SB. J. Wyman // Always return 1 to indicate present. 1292681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 12933f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1294391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1295ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1296ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1297ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1298ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1299*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 130082affd94SBrandon Wyman 130182affd94SBrandon Wyman // Presence change from missing to present will trigger in1_input read in 130282affd94SBrandon Wyman // an attempt to get CLEAR_FAULTS called. Return value ignored. 130382affd94SBrandon Wyman // Zero to non-zero voltage, for missing/present change, triggers clear 130482affd94SBrandon Wyman // faults call again. Return value ignored. 130582affd94SBrandon Wyman // Fault (low voltage) to not faulted (voltage in range) triggers clear 130682affd94SBrandon Wyman // faults call a third time. 130782affd94SBrandon Wyman 13088da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1309b654c619SBrandon Wyman PMBusExpectations expectations; 1310b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 131182affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 131282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 131382affd94SBrandon Wyman .Times(1) 131482affd94SBrandon Wyman .WillOnce(Return("201100")); 13153f1242f3SBrandon Wyman psu.analyze(); 13163f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 1317f07bc797SBrandon Wyman // Turn fault on. 1318b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VIN_UV_FAULT); 131985c7bf41SBrandon Wyman // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by 132085c7bf41SBrandon Wyman // Figure 16, and assume bits on in STATUS_INPUT. 1321b654c619SBrandon Wyman expectations.statusInputValue = 0x18; 1322c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1323c2906f47SBrandon Wyman { 1324b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 132582affd94SBrandon Wyman // If there is a VIN_UV fault, fake reading voltage of less than 20V 132682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 132782affd94SBrandon Wyman .Times(1) 132882affd94SBrandon Wyman .WillOnce(Return("19876")); 13290975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 13300975eaf4SMatt Spinler { 13310975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 13320975eaf4SMatt Spinler } 13333f1242f3SBrandon Wyman psu.analyze(); 1334c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 1335c2906f47SBrandon Wyman } 1336f07bc797SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1337b654c619SBrandon Wyman expectations.statusWordValue = 0; 1338b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 133982affd94SBrandon Wyman // Updates now result in clearing faults if read voltage goes from below the 134082affd94SBrandon Wyman // minimum, to within a valid range. 134182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 134282affd94SBrandon Wyman .Times(1) 134382affd94SBrandon Wyman .WillOnce(Return("201300")); 13443225a45cSBrandon Wyman // Went from below minimum to within range, expect clearVinUVFault(). 13453225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 13463225a45cSBrandon Wyman .Times(1) 13473225a45cSBrandon Wyman .WillOnce(Return(1)); 13480975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 13493f1242f3SBrandon Wyman psu.analyze(); 13503f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 13513f1242f3SBrandon Wyman } 13526710ba2cSBrandon Wyman 13536710ba2cSBrandon Wyman TEST_F(PowerSupplyTests, HasVoutOVFault) 13546710ba2cSBrandon Wyman { 13556710ba2cSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 13566710ba2cSBrandon Wyman 13579464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x69, 13589464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 13596710ba2cSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 13606710ba2cSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 13616710ba2cSBrandon Wyman // Always return 1 to indicate present. 13626710ba2cSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 13636710ba2cSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1364391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1365ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1366ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1367ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1368ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1369*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 13706710ba2cSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1371b654c619SBrandon Wyman PMBusExpectations expectations; 1372b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 137382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 137482affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 137582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 137682affd94SBrandon Wyman .Times(1) 137782affd94SBrandon Wyman .WillOnce(Return("202100")); 13786710ba2cSBrandon Wyman psu.analyze(); 13796710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 13806710ba2cSBrandon Wyman // Turn fault on. 1381b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_OV_FAULT); 13826710ba2cSBrandon Wyman // STATUS_VOUT fault bit(s) 1383b654c619SBrandon Wyman expectations.statusVOUTValue = 0x80; 1384c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1385c2906f47SBrandon Wyman { 1386b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 138782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 138882affd94SBrandon Wyman .Times(1) 138982affd94SBrandon Wyman .WillOnce(Return("202200")); 13906710ba2cSBrandon Wyman psu.analyze(); 1391c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 1392c2906f47SBrandon Wyman } 13936710ba2cSBrandon Wyman // Back to no fault bits on in STATUS_WORD 1394b654c619SBrandon Wyman expectations.statusWordValue = 0; 1395b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 139682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 139782affd94SBrandon Wyman .Times(1) 139882affd94SBrandon Wyman .WillOnce(Return("202300")); 13996710ba2cSBrandon Wyman psu.analyze(); 14006710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 14016710ba2cSBrandon Wyman } 140296893a46SBrandon Wyman 1403b10b3be0SBrandon Wyman TEST_F(PowerSupplyTests, HasIoutOCFault) 1404b10b3be0SBrandon Wyman { 1405b10b3be0SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1406b10b3be0SBrandon Wyman 14079464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, 14089464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 1409b10b3be0SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1410b10b3be0SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1411b10b3be0SBrandon Wyman // Always return 1 to indicate present. 1412b10b3be0SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1413b10b3be0SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1414391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1415ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1416ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1417ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1418ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1419*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 1420b10b3be0SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1421b10b3be0SBrandon Wyman PMBusExpectations expectations; 1422b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 142382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 142482affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 142582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 142682affd94SBrandon Wyman .Times(1) 142782affd94SBrandon Wyman .WillOnce(Return("203100")); 1428b10b3be0SBrandon Wyman psu.analyze(); 1429b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1430b10b3be0SBrandon Wyman // Turn fault on. 1431b10b3be0SBrandon Wyman expectations.statusWordValue = status_word::IOUT_OC_FAULT; 1432b10b3be0SBrandon Wyman // STATUS_IOUT fault bit(s) 1433b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0x88; 1434c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1435c2906f47SBrandon Wyman { 1436b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 143782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 143882affd94SBrandon Wyman .Times(1) 143982affd94SBrandon Wyman .WillOnce(Return("203200")); 14400975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 14410975eaf4SMatt Spinler { 14420975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 14430975eaf4SMatt Spinler } 1444b10b3be0SBrandon Wyman psu.analyze(); 1445c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 1446c2906f47SBrandon Wyman } 1447b10b3be0SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1448b10b3be0SBrandon Wyman expectations.statusWordValue = 0; 1449b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 145082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 145182affd94SBrandon Wyman .Times(1) 145282affd94SBrandon Wyman .WillOnce(Return("203300")); 14530975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1454b10b3be0SBrandon Wyman psu.analyze(); 1455b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1456b10b3be0SBrandon Wyman } 1457b10b3be0SBrandon Wyman 14582cf46945SBrandon Wyman TEST_F(PowerSupplyTests, HasVoutUVFault) 14592cf46945SBrandon Wyman { 14602cf46945SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 14612cf46945SBrandon Wyman 14629464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, 14639464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 14642cf46945SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 14652cf46945SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 14662cf46945SBrandon Wyman // Always return 1 to indicate present. 14672cf46945SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 14682cf46945SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1469391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1470ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1471ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1472ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1473ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1474*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 1475391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 14762cf46945SBrandon Wyman PMBusExpectations expectations; 14772cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 147882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 147982affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 148082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 148182affd94SBrandon Wyman .Times(1) 148282affd94SBrandon Wyman .WillOnce(Return("204100")); 14832cf46945SBrandon Wyman psu.analyze(); 14842cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 14852cf46945SBrandon Wyman // Turn fault on. 14862cf46945SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_FAULT); 14872cf46945SBrandon Wyman // STATUS_VOUT fault bit(s) 14882cf46945SBrandon Wyman expectations.statusVOUTValue = 0x30; 1489c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1490c2906f47SBrandon Wyman { 14912cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 149282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 149382affd94SBrandon Wyman .Times(1) 149482affd94SBrandon Wyman .WillOnce(Return("204200")); 14952cf46945SBrandon Wyman psu.analyze(); 1496c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), x >= DEGLITCH_LIMIT); 1497c2906f47SBrandon Wyman } 14982cf46945SBrandon Wyman // Back to no fault bits on in STATUS_WORD 14992cf46945SBrandon Wyman expectations.statusWordValue = 0; 15002cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 150182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 150282affd94SBrandon Wyman .Times(1) 150382affd94SBrandon Wyman .WillOnce(Return("204300")); 15042cf46945SBrandon Wyman psu.analyze(); 15052cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 15062cf46945SBrandon Wyman } 15072cf46945SBrandon Wyman 15087ee4d7e4SBrandon Wyman TEST_F(PowerSupplyTests, HasFanFault) 15097ee4d7e4SBrandon Wyman { 15107ee4d7e4SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 15117ee4d7e4SBrandon Wyman 15120975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1); 15130975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0); 15140975eaf4SMatt Spinler 15159464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, 15169464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 15177ee4d7e4SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 15187ee4d7e4SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 15197ee4d7e4SBrandon Wyman // Always return 1 to indicate present. 15207ee4d7e4SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 15217ee4d7e4SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1522391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1523ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1524ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1525ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1526ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1527*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 15287ee4d7e4SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 15297ee4d7e4SBrandon Wyman PMBusExpectations expectations; 15307ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 153182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 153282affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 153382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 153482affd94SBrandon Wyman .Times(1) 153582affd94SBrandon Wyman .WillOnce(Return("205100")); 15367ee4d7e4SBrandon Wyman psu.analyze(); 15377ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 15387ee4d7e4SBrandon Wyman // Turn fault on. 15397ee4d7e4SBrandon Wyman expectations.statusWordValue = (status_word::FAN_FAULT); 15407ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 fault bit on (Fan 1 Fault) 15417ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0x80; 1542c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1543c2906f47SBrandon Wyman { 15447ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 154582affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 154682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 154782affd94SBrandon Wyman .Times(1) 154882affd94SBrandon Wyman .WillOnce(Return("205200")); 15497ee4d7e4SBrandon Wyman psu.analyze(); 1550c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 1551c2906f47SBrandon Wyman } 15527ee4d7e4SBrandon Wyman // Back to no fault bits on in STATUS_WORD 15537ee4d7e4SBrandon Wyman expectations.statusWordValue = 0; 15547ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 155582affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 155682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 155782affd94SBrandon Wyman .Times(1) 155882affd94SBrandon Wyman .WillOnce(Return("205300")); 15597ee4d7e4SBrandon Wyman psu.analyze(); 15607ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 15617ee4d7e4SBrandon Wyman } 15627ee4d7e4SBrandon Wyman 156396893a46SBrandon Wyman TEST_F(PowerSupplyTests, HasTempFault) 156496893a46SBrandon Wyman { 156596893a46SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 156696893a46SBrandon Wyman 15670975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1); 15680975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0); 15690975eaf4SMatt Spinler 15709464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, 15719464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 157296893a46SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 157396893a46SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 157496893a46SBrandon Wyman // Always return 1 to indicate present. 157596893a46SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 157696893a46SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1577391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1578ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1579ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1580ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1581ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1582*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 158396893a46SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 158496893a46SBrandon Wyman PMBusExpectations expectations; 158596893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 158682affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 158782affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 158882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 158982affd94SBrandon Wyman .Times(1) 159082affd94SBrandon Wyman .WillOnce(Return("206100")); 159196893a46SBrandon Wyman psu.analyze(); 159296893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 159396893a46SBrandon Wyman // Turn fault on. 159496893a46SBrandon Wyman expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 159596893a46SBrandon Wyman // STATUS_TEMPERATURE fault bit on (OT Fault) 159696893a46SBrandon Wyman expectations.statusTempValue = 0x80; 1597c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1598c2906f47SBrandon Wyman { 159996893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 160082affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 160182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 160282affd94SBrandon Wyman .Times(1) 160382affd94SBrandon Wyman .WillOnce(Return("206200")); 160496893a46SBrandon Wyman psu.analyze(); 1605c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 1606c2906f47SBrandon Wyman } 160796893a46SBrandon Wyman // Back to no fault bits on in STATUS_WORD 160896893a46SBrandon Wyman expectations.statusWordValue = 0; 160996893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 161082affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 161182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 161282affd94SBrandon Wyman .Times(1) 161382affd94SBrandon Wyman .WillOnce(Return("206300")); 161496893a46SBrandon Wyman psu.analyze(); 161596893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 161696893a46SBrandon Wyman } 16172916ea52SBrandon Wyman 16182916ea52SBrandon Wyman TEST_F(PowerSupplyTests, HasPgoodFault) 16192916ea52SBrandon Wyman { 16202916ea52SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 16212916ea52SBrandon Wyman 16229464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x6b, 16239464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 16242916ea52SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 16252916ea52SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 16262916ea52SBrandon Wyman // Always return 1 to indicate present. 16272916ea52SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 16282916ea52SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1629391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1630ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1631ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1632ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1633ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1634*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 16352916ea52SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 16362916ea52SBrandon Wyman PMBusExpectations expectations; 16372916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 163882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 163982affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 164082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 164182affd94SBrandon Wyman .Times(1) 164282affd94SBrandon Wyman .WillOnce(Return("207100")); 16432916ea52SBrandon Wyman psu.analyze(); 16442916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 1645391a0690SBrandon Wyman // Setup another expectation of no faults. 1646391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 164782affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 164882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 164982affd94SBrandon Wyman .Times(1) 165082affd94SBrandon Wyman .WillOnce(Return("207200")); 165182affd94SBrandon Wyman psu.analyze(); 165282affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 165382affd94SBrandon Wyman // Setup another expectation of no faults. 165482affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 165582affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 165682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 165782affd94SBrandon Wyman .Times(1) 165882affd94SBrandon Wyman .WillOnce(Return("207300")); 1659391a0690SBrandon Wyman psu.analyze(); 1660391a0690SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 16612916ea52SBrandon Wyman // Turn PGOOD# off (fault on). 16622916ea52SBrandon Wyman expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED); 16632916ea52SBrandon 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("207400")); 16682916ea52SBrandon Wyman psu.analyze(); 16696d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 1 167006ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 167106ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 167282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 167382affd94SBrandon Wyman .Times(1) 167482affd94SBrandon Wyman .WillOnce(Return("207500")); 167506ca4590SBrandon Wyman psu.analyze(); 16766d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 2 167706ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 167806ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 167982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 168082affd94SBrandon Wyman .Times(1) 168182affd94SBrandon Wyman .WillOnce(Return("207600")); 168206ca4590SBrandon Wyman psu.analyze(); 16836d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 3 16846d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 16856d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 16866d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 16876d469fd4SBrandon Wyman .Times(1) 16886d469fd4SBrandon Wyman .WillOnce(Return("207700")); 16896d469fd4SBrandon Wyman psu.analyze(); 16906d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 4 16916d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 16926d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 16936d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 16946d469fd4SBrandon Wyman .Times(1) 16956d469fd4SBrandon Wyman .WillOnce(Return("207800")); 16966d469fd4SBrandon Wyman psu.analyze(); 16976d469fd4SBrandon Wyman // Expect true. PGOOD_DEGLITCH_LIMIT @ 5 16982916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 16992916ea52SBrandon Wyman // Back to no fault bits on in STATUS_WORD 17002916ea52SBrandon Wyman expectations.statusWordValue = 0; 17012916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 170282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 170382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 170482affd94SBrandon Wyman .Times(1) 170582affd94SBrandon Wyman .WillOnce(Return("207700")); 17062916ea52SBrandon Wyman psu.analyze(); 17072916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 170882affd94SBrandon Wyman 17092916ea52SBrandon Wyman // Turn OFF bit on 17102916ea52SBrandon Wyman expectations.statusWordValue = (status_word::UNIT_IS_OFF); 17112916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 171282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 171382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 171482affd94SBrandon Wyman .Times(1) 171582affd94SBrandon Wyman .WillOnce(Return("208100")); 17162916ea52SBrandon Wyman psu.analyze(); 171706ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 171806ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 171982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 172082affd94SBrandon Wyman .Times(1) 172182affd94SBrandon Wyman .WillOnce(Return("208200")); 172206ca4590SBrandon Wyman psu.analyze(); 172306ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 172406ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 172582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 172682affd94SBrandon Wyman .Times(1) 172782affd94SBrandon Wyman .WillOnce(Return("208300")); 172806ca4590SBrandon Wyman psu.analyze(); 17296d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 17306d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 17316d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 17326d469fd4SBrandon Wyman .Times(1) 17336d469fd4SBrandon Wyman .WillOnce(Return("208400")); 17346d469fd4SBrandon Wyman psu.analyze(); 17356d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 17366d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 17376d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 17386d469fd4SBrandon Wyman .Times(1) 17396d469fd4SBrandon Wyman .WillOnce(Return("208500")); 17406d469fd4SBrandon Wyman psu.analyze(); 17412916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 17422916ea52SBrandon Wyman // Back to no fault bits on in STATUS_WORD 17432916ea52SBrandon Wyman expectations.statusWordValue = 0; 17442916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 174582affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 174682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 174782affd94SBrandon Wyman .Times(1) 17486d469fd4SBrandon Wyman .WillOnce(Return("208000")); 17492916ea52SBrandon Wyman psu.analyze(); 17502916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 17512916ea52SBrandon Wyman } 175239ea02bcSBrandon Wyman 175339ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSKillFault) 175439ea02bcSBrandon Wyman { 175539ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 17569464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 4, 0x6d, 17579464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 175839ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 175939ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 176039ea02bcSBrandon Wyman // Always return 1 to indicate present. 176139ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 176239ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 176382affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1764ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1765ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1766ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1767ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1768*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 176939ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 177039ea02bcSBrandon Wyman PMBusExpectations expectations; 177139ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 177282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 177382affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 177482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 177582affd94SBrandon Wyman .Times(1) 177682affd94SBrandon Wyman .WillOnce(Return("208100")); 177739ea02bcSBrandon Wyman psu.analyze(); 177839ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 177939ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 178039ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 178139ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 178239ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1783c2906f47SBrandon Wyman 1784c2906f47SBrandon Wyman // Deglitching faults, false until read the fault bits on up to the limit. 1785c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1786c2906f47SBrandon Wyman { 178739ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 178882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 178982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 179082affd94SBrandon Wyman .Times(1) 179182affd94SBrandon Wyman .WillOnce(Return("208200")); 17920975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 17930975eaf4SMatt Spinler { 17940975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 17950975eaf4SMatt Spinler } 179639ea02bcSBrandon Wyman psu.analyze(); 1797c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1798c2906f47SBrandon Wyman } 1799c2906f47SBrandon Wyman 180039ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 180139ea02bcSBrandon Wyman expectations.statusWordValue = 0; 180239ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 180382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 180482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 180582affd94SBrandon Wyman .Times(1) 180682affd94SBrandon Wyman .WillOnce(Return("208300")); 18070975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 180839ea02bcSBrandon Wyman psu.analyze(); 180939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 181039ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 181139ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 181239ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 4 on. 181339ea02bcSBrandon Wyman expectations.statusMFRValue = 0x10; 1814c2906f47SBrandon Wyman 1815c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1816c2906f47SBrandon Wyman { 181739ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 181882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 181982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 182082affd94SBrandon Wyman .Times(1) 182182affd94SBrandon Wyman .WillOnce(Return("208400")); 18220975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 18230975eaf4SMatt Spinler { 18240975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 18250975eaf4SMatt Spinler } 182639ea02bcSBrandon Wyman psu.analyze(); 1827c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1828c2906f47SBrandon Wyman } 1829c2906f47SBrandon Wyman 183039ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 183139ea02bcSBrandon Wyman expectations.statusWordValue = 0; 183239ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 183382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 183482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 183582affd94SBrandon Wyman .Times(1) 183682affd94SBrandon Wyman .WillOnce(Return("208500")); 18370975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 183839ea02bcSBrandon Wyman psu.analyze(); 183939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 184039ea02bcSBrandon Wyman } 184139ea02bcSBrandon Wyman 184239ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPS12VcsFault) 184339ea02bcSBrandon Wyman { 184439ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 18459464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 5, 0x6e, 18469464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 184739ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 184839ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 184939ea02bcSBrandon Wyman // Always return 1 to indicate present. 185039ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 185139ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 185282affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1853ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1854ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1855ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1856ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1857*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 185839ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 185939ea02bcSBrandon Wyman PMBusExpectations expectations; 186039ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 186182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 186282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 186382affd94SBrandon Wyman .Times(1) 186482affd94SBrandon Wyman .WillOnce(Return("209100")); 186539ea02bcSBrandon Wyman psu.analyze(); 186639ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 186739ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 186839ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 186939ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 187039ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1871c2906f47SBrandon Wyman 1872c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1873c2906f47SBrandon Wyman { 187439ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 187582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 187682affd94SBrandon Wyman .Times(1) 187782affd94SBrandon Wyman .WillOnce(Return("209200")); 187839ea02bcSBrandon Wyman psu.analyze(); 1879c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1880c2906f47SBrandon Wyman } 1881c2906f47SBrandon Wyman 188239ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 188339ea02bcSBrandon Wyman expectations.statusWordValue = 0; 188439ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 188582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 188682affd94SBrandon Wyman .Times(1) 188782affd94SBrandon Wyman .WillOnce(Return("209300")); 188839ea02bcSBrandon Wyman psu.analyze(); 188939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 189039ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 189139ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 189239ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 6 on. 189339ea02bcSBrandon Wyman expectations.statusMFRValue = 0x40; 1894c2906f47SBrandon Wyman 1895c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1896c2906f47SBrandon Wyman { 189739ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 189882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 189982affd94SBrandon Wyman .Times(1) 190082affd94SBrandon Wyman .WillOnce(Return("209400")); 190139ea02bcSBrandon Wyman psu.analyze(); 1902c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1903c2906f47SBrandon Wyman } 1904c2906f47SBrandon Wyman 190539ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 190639ea02bcSBrandon Wyman expectations.statusWordValue = 0; 190739ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 190882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 190982affd94SBrandon Wyman .Times(1) 191082affd94SBrandon Wyman .WillOnce(Return("209500")); 191139ea02bcSBrandon Wyman psu.analyze(); 191239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 191339ea02bcSBrandon Wyman } 191439ea02bcSBrandon Wyman 191539ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSCS12VFault) 191639ea02bcSBrandon Wyman { 191739ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 19189464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f, 19199464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 192039ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 192139ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 192239ea02bcSBrandon Wyman // Always return 1 to indicate present. 192339ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 192439ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 192582affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1926ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1927ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1928ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1929ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1930*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 193139ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 193239ea02bcSBrandon Wyman PMBusExpectations expectations; 193339ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 193482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 193582affd94SBrandon Wyman .Times(1) 193682affd94SBrandon Wyman .WillOnce(Return("209100")); 193739ea02bcSBrandon Wyman psu.analyze(); 193839ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 193939ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 194039ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 194139ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 194239ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1943c2906f47SBrandon Wyman 1944c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1945c2906f47SBrandon Wyman { 194639ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 194782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 194882affd94SBrandon Wyman .Times(1) 194982affd94SBrandon Wyman .WillOnce(Return("209200")); 195039ea02bcSBrandon Wyman psu.analyze(); 1951c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1952c2906f47SBrandon Wyman } 1953c2906f47SBrandon Wyman 195439ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 195539ea02bcSBrandon Wyman expectations.statusWordValue = 0; 195639ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 195782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 195882affd94SBrandon Wyman .Times(1) 195982affd94SBrandon Wyman .WillOnce(Return("209300")); 196039ea02bcSBrandon Wyman psu.analyze(); 196139ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 196239ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 196339ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 196439ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 7 on. 196539ea02bcSBrandon Wyman expectations.statusMFRValue = 0x80; 1966c2906f47SBrandon Wyman 1967c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1968c2906f47SBrandon Wyman { 196939ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 197082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 197182affd94SBrandon Wyman .Times(1) 197282affd94SBrandon Wyman .WillOnce(Return("209400")); 197339ea02bcSBrandon Wyman psu.analyze(); 1974c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1975c2906f47SBrandon Wyman } 1976c2906f47SBrandon Wyman 197739ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 197839ea02bcSBrandon Wyman expectations.statusWordValue = 0; 197939ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 198082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 198182affd94SBrandon Wyman .Times(1) 198282affd94SBrandon Wyman .WillOnce(Return("209500")); 198339ea02bcSBrandon Wyman psu.analyze(); 198439ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 198539ea02bcSBrandon Wyman } 1986c3324424SBrandon Wyman 1987*592bd27cSMatt Spinler TEST_F(PowerSupplyTests, PeakInputPowerSensor) 1988c3324424SBrandon Wyman { 1989c3324424SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1990c3324424SBrandon Wyman { 19919464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f, 19929464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 1993*592bd27cSMatt Spinler EXPECT_EQ(psu.getPeakInputPower(), std::nullopt); 1994*592bd27cSMatt Spinler 1995c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1996c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1997ae35ac5dSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1998c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1999*592bd27cSMatt Spinler 2000ae35ac5dSBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2001ae35ac5dSBrandon Wyman PMBusExpectations expectations; 2002ae35ac5dSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2003*592bd27cSMatt Spinler 2004ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2005ae35ac5dSBrandon Wyman .Times(1) 2006ae35ac5dSBrandon Wyman .WillOnce(Return("206000")); 2007ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2008ae35ac5dSBrandon Wyman .WillRepeatedly(Return("2000")); 2009*592bd27cSMatt Spinler 2010c3324424SBrandon Wyman psu.analyze(); 2011*592bd27cSMatt Spinler EXPECT_EQ(psu.getPeakInputPower().value_or(0), 213); 2012c3324424SBrandon Wyman } 2013*592bd27cSMatt Spinler 2014*592bd27cSMatt Spinler // Test that there is no peak power sensor on 1400W PSs 2015c3324424SBrandon Wyman { 20169464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 20179464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 2018ae35ac5dSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 2019ae35ac5dSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 2020ae35ac5dSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2021*592bd27cSMatt Spinler 2022ae35ac5dSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 2023*592bd27cSMatt Spinler 2024ae35ac5dSBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2025*592bd27cSMatt Spinler 2026ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2027ae35ac5dSBrandon Wyman .WillRepeatedly(Return("30725")); 2028*592bd27cSMatt Spinler 2029ae35ac5dSBrandon Wyman PMBusExpectations expectations; 2030ae35ac5dSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2031*592bd27cSMatt Spinler 2032ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2033*592bd27cSMatt Spinler .WillRepeatedly(Return("206000")); 2034ae35ac5dSBrandon Wyman psu.analyze(); 2035*592bd27cSMatt Spinler 2036*592bd27cSMatt Spinler EXPECT_EQ(psu.getPeakInputPower(), std::nullopt); 2037ae35ac5dSBrandon Wyman } 2038*592bd27cSMatt Spinler 2039*592bd27cSMatt Spinler // Test that IPSPS power supplies don't have peak power 2040ae35ac5dSBrandon Wyman { 2041c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 11, 20429464c429SGeorge Liu 0x58, "inspur-ipsps", PSUGPIOLineName, 20439464c429SGeorge Liu isPowerOn}; 2044*592bd27cSMatt Spinler 2045c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 2046c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 2047*592bd27cSMatt Spinler 2048ae35ac5dSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2049*592bd27cSMatt Spinler 2050c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 2051*592bd27cSMatt Spinler 2052ae35ac5dSBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2053ae35ac5dSBrandon Wyman PMBusExpectations expectations; 2054ae35ac5dSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2055*592bd27cSMatt Spinler 2056*592bd27cSMatt Spinler EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2057*592bd27cSMatt Spinler .WillRepeatedly(Return("206000")); 2058*592bd27cSMatt Spinler 2059*592bd27cSMatt Spinler psu.analyze(); 2060*592bd27cSMatt Spinler 2061*592bd27cSMatt Spinler EXPECT_EQ(psu.getPeakInputPower(), std::nullopt); 2062*592bd27cSMatt Spinler } 2063*592bd27cSMatt Spinler 2064*592bd27cSMatt Spinler // Test that a bad response from the input_history command leads 2065*592bd27cSMatt Spinler // to an NaN value. 2066*592bd27cSMatt Spinler { 2067*592bd27cSMatt Spinler PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f, 2068*592bd27cSMatt Spinler "ibm-cffps", PSUGPIOLineName, isPowerOn}; 2069*592bd27cSMatt Spinler 2070*592bd27cSMatt Spinler MockedGPIOInterface* mockPresenceGPIO = 2071*592bd27cSMatt Spinler static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 2072*592bd27cSMatt Spinler MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2073*592bd27cSMatt Spinler 2074*592bd27cSMatt Spinler EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 2075*592bd27cSMatt Spinler 2076*592bd27cSMatt Spinler setMissingToPresentExpects(mockPMBus, mockedUtil); 2077*592bd27cSMatt Spinler PMBusExpectations expectations; 2078*592bd27cSMatt Spinler setPMBusExpectations(mockPMBus, expectations); 2079*592bd27cSMatt Spinler 2080ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2081ae35ac5dSBrandon Wyman .Times(1) 2082ae35ac5dSBrandon Wyman .WillOnce(Return("206000")); 2083ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2084*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 2085*592bd27cSMatt Spinler 2086*592bd27cSMatt Spinler // Don't return the full 5 bytes. 2087*592bd27cSMatt Spinler EXPECT_CALL(mockPMBus, 2088*592bd27cSMatt Spinler readBinary(INPUT_HISTORY, Type::HwmonDeviceDebug, 5)) 2089*592bd27cSMatt Spinler .WillRepeatedly(Return(std::vector<uint8_t>{0x01, 0x5c})); 2090*592bd27cSMatt Spinler 2091c3324424SBrandon Wyman psu.analyze(); 2092*592bd27cSMatt Spinler EXPECT_THAT(psu.getPeakInputPower().value_or(0), IsNan()); 2093*592bd27cSMatt Spinler } 2094c3324424SBrandon Wyman } 209518a24d92SBrandon Wyman 209618a24d92SBrandon Wyman TEST_F(PowerSupplyTests, IsSyncHistoryRequired) 209718a24d92SBrandon Wyman { 209818a24d92SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 20999464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 8, 0x6f, 21009464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 210118a24d92SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 210218a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), false); 210318a24d92SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 210418a24d92SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 210518a24d92SBrandon Wyman // Always return 1 to indicate present. 210618a24d92SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 210718a24d92SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 210818a24d92SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2109ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 2110ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 2111ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 2112ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2113*592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 211418a24d92SBrandon Wyman PMBusExpectations expectations; 211518a24d92SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 211618a24d92SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 211718a24d92SBrandon Wyman .Times(1) 211818a24d92SBrandon Wyman .WillRepeatedly(Return("205000")); 211918a24d92SBrandon Wyman EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 212018a24d92SBrandon Wyman psu.analyze(); 212118a24d92SBrandon Wyman // The ibm-cffps power supply should support input history 212218a24d92SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 212318a24d92SBrandon Wyman // Missing -> Present requires history sync 212418a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), true); 212518a24d92SBrandon Wyman psu.clearSyncHistoryRequired(); 212618a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), false); 212718a24d92SBrandon Wyman } 2128*592bd27cSMatt Spinler 2129*592bd27cSMatt Spinler TEST_F(PowerSupplyTests, TestLinearConversions) 2130*592bd27cSMatt Spinler { 2131*592bd27cSMatt Spinler // Mantissa > 0, exponent = 0 2132*592bd27cSMatt Spinler EXPECT_EQ(0, PowerSupply::linearToInteger(0)); 2133*592bd27cSMatt Spinler EXPECT_EQ(1, PowerSupply::linearToInteger(1)); 2134*592bd27cSMatt Spinler EXPECT_EQ(38, PowerSupply::linearToInteger(0x26)); 2135*592bd27cSMatt Spinler EXPECT_EQ(1023, PowerSupply::linearToInteger(0x3FF)); 2136*592bd27cSMatt Spinler 2137*592bd27cSMatt Spinler // Mantissa < 0, exponent = 0 2138*592bd27cSMatt Spinler EXPECT_EQ(-1, PowerSupply::linearToInteger(0x7FF)); 2139*592bd27cSMatt Spinler EXPECT_EQ(-20, PowerSupply::linearToInteger(0x7EC)); 2140*592bd27cSMatt Spinler EXPECT_EQ(-769, PowerSupply::linearToInteger(0x4FF)); 2141*592bd27cSMatt Spinler EXPECT_EQ(-989, PowerSupply::linearToInteger(0x423)); 2142*592bd27cSMatt Spinler EXPECT_EQ(-1024, PowerSupply::linearToInteger(0x400)); 2143*592bd27cSMatt Spinler 2144*592bd27cSMatt Spinler // Mantissa >= 0, exponent > 0 2145*592bd27cSMatt Spinler // M = 1, E = 2 2146*592bd27cSMatt Spinler EXPECT_EQ(4, PowerSupply::linearToInteger(0x1001)); 2147*592bd27cSMatt Spinler 2148*592bd27cSMatt Spinler // M = 1000, E = 10 2149*592bd27cSMatt Spinler EXPECT_EQ(1024000, PowerSupply::linearToInteger(0x53E8)); 2150*592bd27cSMatt Spinler 2151*592bd27cSMatt Spinler // M = 10, E = 15 2152*592bd27cSMatt Spinler EXPECT_EQ(327680, PowerSupply::linearToInteger(0x780A)); 2153*592bd27cSMatt Spinler 2154*592bd27cSMatt Spinler // Mantissa >= 0, exponent < 0 2155*592bd27cSMatt Spinler // M = 0, E = -1 2156*592bd27cSMatt Spinler EXPECT_EQ(0, PowerSupply::linearToInteger(0xF800)); 2157*592bd27cSMatt Spinler 2158*592bd27cSMatt Spinler // M = 100, E = -2 2159*592bd27cSMatt Spinler EXPECT_EQ(25, PowerSupply::linearToInteger(0xF064)); 2160*592bd27cSMatt Spinler 2161*592bd27cSMatt Spinler // Mantissa < 0, exponent < 0 2162*592bd27cSMatt Spinler // M = -100, E = -1 2163*592bd27cSMatt Spinler EXPECT_EQ(-50, PowerSupply::linearToInteger(0xFF9C)); 2164*592bd27cSMatt Spinler 2165*592bd27cSMatt Spinler // M = -1024, E = -7 2166*592bd27cSMatt Spinler EXPECT_EQ(-8, PowerSupply::linearToInteger(0xCC00)); 2167*592bd27cSMatt Spinler } 2168