13f1242f3SBrandon Wyman #include "../power_supply.hpp" 23f1242f3SBrandon Wyman #include "mock.hpp" 33f1242f3SBrandon Wyman 43f1242f3SBrandon Wyman #include <xyz/openbmc_project/Common/Device/error.hpp> 53f1242f3SBrandon Wyman #include <xyz/openbmc_project/Common/error.hpp> 63f1242f3SBrandon Wyman 73f1242f3SBrandon Wyman #include <gmock/gmock.h> 83f1242f3SBrandon Wyman #include <gtest/gtest.h> 93f1242f3SBrandon Wyman 103f1242f3SBrandon Wyman using namespace phosphor::power::psu; 113f1242f3SBrandon Wyman using namespace phosphor::pmbus; 123f1242f3SBrandon Wyman 133f1242f3SBrandon Wyman using ::testing::_; 1459a35793SBrandon Wyman using ::testing::Args; 153f1242f3SBrandon Wyman using ::testing::Assign; 163f1242f3SBrandon Wyman using ::testing::DoAll; 1759a35793SBrandon Wyman using ::testing::ElementsAre; 18592bd27cSMatt Spinler using ::testing::IsNan; 1959a35793SBrandon Wyman using ::testing::NotNull; 203f1242f3SBrandon Wyman using ::testing::Return; 213f1242f3SBrandon Wyman using ::testing::StrEq; 223f1242f3SBrandon Wyman 233f1242f3SBrandon Wyman static auto PSUInventoryPath = "/xyz/bmc/inv/sys/chassis/board/powersupply0"; 24681b2a36SB. J. Wyman static auto PSUGPIOLineName = "presence-ps0"; 259464c429SGeorge Liu static auto isPowerOn = []() { return true; }; 263f1242f3SBrandon Wyman 27b654c619SBrandon Wyman struct PMBusExpectations 28b654c619SBrandon Wyman { 29b654c619SBrandon Wyman uint16_t statusWordValue{0x0000}; 30b654c619SBrandon Wyman uint8_t statusInputValue{0x00}; 31b654c619SBrandon Wyman uint8_t statusMFRValue{0x00}; 32b654c619SBrandon Wyman uint8_t statusCMLValue{0x00}; 33b654c619SBrandon Wyman uint8_t statusVOUTValue{0x00}; 34b10b3be0SBrandon Wyman uint8_t statusIOUTValue{0x00}; 357ee4d7e4SBrandon Wyman uint8_t statusFans12Value{0x00}; 3696893a46SBrandon Wyman uint8_t statusTempValue{0x00}; 37b654c619SBrandon Wyman }; 38b654c619SBrandon Wyman 398da35c51SBrandon Wyman // Helper function to setup expectations for various STATUS_* commands 40b654c619SBrandon Wyman void setPMBusExpectations(MockedPMBus& mockPMBus, 41b654c619SBrandon Wyman const PMBusExpectations& expectations) 428da35c51SBrandon Wyman { 4332453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _, _)) 448da35c51SBrandon Wyman .Times(1) 45b654c619SBrandon Wyman .WillOnce(Return(expectations.statusWordValue)); 468da35c51SBrandon Wyman 47b654c619SBrandon Wyman if (expectations.statusWordValue != 0) 488da35c51SBrandon Wyman { 498da35c51SBrandon Wyman // If fault bits are on in STATUS_WORD, there will also be a read of 5096893a46SBrandon Wyman // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT (page 0), and 5196893a46SBrandon Wyman // STATUS_TEMPERATURE. 5232453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _, _)) 538da35c51SBrandon Wyman .Times(1) 54b654c619SBrandon Wyman .WillOnce(Return(expectations.statusInputValue)); 5532453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _, _)) 568da35c51SBrandon Wyman .Times(1) 57b654c619SBrandon Wyman .WillOnce(Return(expectations.statusMFRValue)); 5832453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _, _)) 598da35c51SBrandon Wyman .Times(1) 60b654c619SBrandon Wyman .WillOnce(Return(expectations.statusCMLValue)); 616710ba2cSBrandon Wyman // Page will need to be set to 0 to read STATUS_VOUT. 626710ba2cSBrandon Wyman EXPECT_CALL(mockPMBus, insertPageNum(STATUS_VOUT, 0)) 636710ba2cSBrandon Wyman .Times(1) 646710ba2cSBrandon Wyman .WillOnce(Return("status0_vout")); 6532453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read("status0_vout", _, _)) 666710ba2cSBrandon Wyman .Times(1) 67b654c619SBrandon Wyman .WillOnce(Return(expectations.statusVOUTValue)); 6832453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_IOUT, _, _)) 69b10b3be0SBrandon Wyman .Times(1) 70b10b3be0SBrandon Wyman .WillOnce(Return(expectations.statusIOUTValue)); 7132453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_FANS_1_2, _, _)) 727ee4d7e4SBrandon Wyman .Times(1) 737ee4d7e4SBrandon Wyman .WillOnce(Return(expectations.statusFans12Value)); 7432453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_TEMPERATURE, _, _)) 7596893a46SBrandon Wyman .Times(1) 7696893a46SBrandon Wyman .WillOnce(Return(expectations.statusTempValue)); 778da35c51SBrandon Wyman } 78592bd27cSMatt Spinler 79592bd27cSMatt Spinler // Default max/peak is 213W 80592bd27cSMatt Spinler ON_CALL(mockPMBus, readBinary(INPUT_HISTORY, Type::HwmonDeviceDebug, 5)) 81592bd27cSMatt Spinler .WillByDefault( 82592bd27cSMatt Spinler Return(std::vector<uint8_t>{0x01, 0x5c, 0xf3, 0x54, 0xf3})); 838da35c51SBrandon Wyman } 848da35c51SBrandon Wyman 853f1242f3SBrandon Wyman class PowerSupplyTests : public ::testing::Test 863f1242f3SBrandon Wyman { 873f1242f3SBrandon Wyman public: 883f1242f3SBrandon Wyman PowerSupplyTests() : 893f1242f3SBrandon Wyman mockedUtil(reinterpret_cast<const MockedUtil&>(getUtils())) 903f1242f3SBrandon Wyman { 913f1242f3SBrandon Wyman ON_CALL(mockedUtil, getPresence(_, _)).WillByDefault(Return(false)); 923f1242f3SBrandon Wyman } 933f1242f3SBrandon Wyman 943f1242f3SBrandon Wyman ~PowerSupplyTests() override 953f1242f3SBrandon Wyman { 963f1242f3SBrandon Wyman freeUtils(); 973f1242f3SBrandon Wyman } 983f1242f3SBrandon Wyman 993f1242f3SBrandon Wyman const MockedUtil& mockedUtil; 1003f1242f3SBrandon Wyman }; 1013f1242f3SBrandon Wyman 102391a0690SBrandon Wyman // Helper function for when a power supply goes from missing to present. 103391a0690SBrandon Wyman void setMissingToPresentExpects(MockedPMBus& pmbus, const MockedUtil& util) 104391a0690SBrandon Wyman { 105391a0690SBrandon Wyman // Call to analyze() will update to present, that will trigger updating 106391a0690SBrandon Wyman // to the correct/latest HWMON directory, in case it changes. 107391a0690SBrandon Wyman EXPECT_CALL(pmbus, findHwmonDir()); 108391a0690SBrandon Wyman // Presence change from missing to present will trigger write to 109391a0690SBrandon Wyman // ON_OFF_CONFIG. 110391a0690SBrandon Wyman EXPECT_CALL(pmbus, writeBinary(ON_OFF_CONFIG, _, _)); 111391a0690SBrandon Wyman // Presence change from missing to present will trigger in1_input read 112391a0690SBrandon Wyman // in an attempt to get CLEAR_FAULTS called. 11382affd94SBrandon Wyman // This READ_VIN for CLEAR_FAULTS does not check the returned value. 1143225a45cSBrandon Wyman EXPECT_CALL(pmbus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 1153225a45cSBrandon Wyman // The call for clearing faults includes clearing VIN_UV fault. 1163225a45cSBrandon Wyman // The voltage defaults to 0, the first call to analyze should update the 1173225a45cSBrandon Wyman // voltage to the current reading, triggering clearing VIN_UV fault(s) 1183225a45cSBrandon Wyman // due to below minimum to within range voltage. 1193225a45cSBrandon Wyman EXPECT_CALL(pmbus, read("in1_lcrit_alarm", _, _)) 12082affd94SBrandon Wyman .Times(2) 1213225a45cSBrandon Wyman .WillRepeatedly(Return(1)); 122391a0690SBrandon Wyman // Missing/present call will update Presence in inventory. 123391a0690SBrandon Wyman EXPECT_CALL(util, setPresence(_, _, true, _)); 124391a0690SBrandon Wyman } 125391a0690SBrandon Wyman 1263f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Constructor) 1273f1242f3SBrandon Wyman { 1283f1242f3SBrandon Wyman /** 1293f1242f3SBrandon Wyman * @param[in] invpath - String for inventory path to use 1303f1242f3SBrandon Wyman * @param[in] i2cbus - The bus number this power supply is on 1313f1242f3SBrandon Wyman * @param[in] i2caddr - The 16-bit I2C address of the power supply 132681b2a36SB. J. Wyman * @param[in] gpioLineName - The string for the gpio-line-name to read for 133681b2a36SB. J. Wyman * presence. 134681b2a36SB. J. Wyman * @param[in] bindDelay - Time in milliseconds to delay binding the device 135681b2a36SB. J. Wyman * driver after seeing the presence line go active. 1363f1242f3SBrandon Wyman */ 1373f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1381d7a7df8SBrandon Wyman 1391d7a7df8SBrandon Wyman // Try where inventory path is empty, constructor should fail. 1401d7a7df8SBrandon Wyman try 1411d7a7df8SBrandon Wyman { 142c3324424SBrandon Wyman auto psu = std::make_unique<PowerSupply>(bus, "", 3, 0x68, "ibm-cffps", 1439464c429SGeorge Liu PSUGPIOLineName, isPowerOn); 1441d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have reached this line."; 1451d7a7df8SBrandon Wyman } 1461d7a7df8SBrandon Wyman catch (const std::invalid_argument& e) 1471d7a7df8SBrandon Wyman { 1481d7a7df8SBrandon Wyman EXPECT_STREQ(e.what(), "Invalid empty inventoryPath"); 1491d7a7df8SBrandon Wyman } 1501d7a7df8SBrandon Wyman catch (...) 1511d7a7df8SBrandon Wyman { 1521d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 1531d7a7df8SBrandon Wyman } 1541d7a7df8SBrandon Wyman 155681b2a36SB. J. Wyman // TODO: Try invalid i2c address? 156681b2a36SB. J. Wyman 157681b2a36SB. J. Wyman // Try where gpioLineName is empty. 1581d7a7df8SBrandon Wyman try 1591d7a7df8SBrandon Wyman { 160c3324424SBrandon Wyman auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, 1619464c429SGeorge Liu "ibm-cffps", "", isPowerOn); 162681b2a36SB. J. Wyman ADD_FAILURE() 163681b2a36SB. J. Wyman << "Should not have reached this line. Invalid gpioLineName."; 164681b2a36SB. J. Wyman } 165681b2a36SB. J. Wyman catch (const std::invalid_argument& e) 166681b2a36SB. J. Wyman { 167681b2a36SB. J. Wyman EXPECT_STREQ(e.what(), "Invalid empty gpioLineName"); 168681b2a36SB. J. Wyman } 169681b2a36SB. J. Wyman catch (...) 170681b2a36SB. J. Wyman { 171681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 172681b2a36SB. J. Wyman } 173681b2a36SB. J. Wyman 174681b2a36SB. J. Wyman // Test with valid arguments 175681b2a36SB. J. Wyman // NOT using D-Bus inventory path for presence. 176681b2a36SB. J. Wyman try 177681b2a36SB. J. Wyman { 178681b2a36SB. J. Wyman auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, 1799464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, 1809464c429SGeorge Liu isPowerOn); 1813f1242f3SBrandon Wyman 1823f1242f3SBrandon Wyman EXPECT_EQ(psu->isPresent(), false); 1833f1242f3SBrandon Wyman EXPECT_EQ(psu->isFaulted(), false); 1848da35c51SBrandon Wyman EXPECT_EQ(psu->hasCommFault(), false); 1853f1242f3SBrandon Wyman EXPECT_EQ(psu->hasInputFault(), false); 1863f1242f3SBrandon Wyman EXPECT_EQ(psu->hasMFRFault(), false); 1873f1242f3SBrandon Wyman EXPECT_EQ(psu->hasVINUVFault(), false); 1886710ba2cSBrandon Wyman EXPECT_EQ(psu->hasVoutOVFault(), false); 189b10b3be0SBrandon Wyman EXPECT_EQ(psu->hasIoutOCFault(), false); 1902cf46945SBrandon Wyman EXPECT_EQ(psu->hasVoutUVFault(), false); 1917ee4d7e4SBrandon Wyman EXPECT_EQ(psu->hasFanFault(), false); 19296893a46SBrandon Wyman EXPECT_EQ(psu->hasTempFault(), false); 1932916ea52SBrandon Wyman EXPECT_EQ(psu->hasPgoodFault(), false); 19439ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPSKillFault(), false); 19539ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPS12VcsFault(), false); 19639ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPSCS12VFault(), false); 1973f1242f3SBrandon Wyman } 1981d7a7df8SBrandon Wyman catch (...) 1991d7a7df8SBrandon Wyman { 2001d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 2011d7a7df8SBrandon Wyman } 202681b2a36SB. J. Wyman 203681b2a36SB. J. Wyman // Test with valid arguments 204681b2a36SB. J. Wyman // TODO: Using D-Bus inventory path for presence. 205681b2a36SB. J. Wyman try 206681b2a36SB. J. Wyman { 207681b2a36SB. J. Wyman // FIXME: How do I get that presenceGPIO.read() in the startup to throw 208681b2a36SB. J. Wyman // an exception? 209681b2a36SB. J. Wyman 210681b2a36SB. J. Wyman // EXPECT_CALL(mockedUtil, getPresence(_, 211681b2a36SB. J. Wyman // StrEq(PSUInventoryPath))) 212681b2a36SB. J. Wyman // .Times(1); 213681b2a36SB. J. Wyman } 214681b2a36SB. J. Wyman catch (...) 215681b2a36SB. J. Wyman { 216681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 217681b2a36SB. J. Wyman } 2181d7a7df8SBrandon Wyman } 2193f1242f3SBrandon Wyman 2203f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Analyze) 2213f1242f3SBrandon Wyman { 2223f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2233f1242f3SBrandon Wyman 224b654c619SBrandon Wyman { 225681b2a36SB. J. Wyman // If I default to reading the GPIO, I will NOT expect a call to 226681b2a36SB. J. Wyman // getPresence(). 227681b2a36SB. J. Wyman 2289464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, 2299464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 2303ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 2313ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 232681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0)); 233681b2a36SB. J. Wyman 2343f1242f3SBrandon Wyman psu.analyze(); 2353f1242f3SBrandon Wyman // By default, nothing should change. 2363f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 2373f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 2383f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 2393f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 2403f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 24185c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 2426710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 243b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 2442cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 2457ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 24696893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 2472916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 24839ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 24939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 25039ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 251b654c619SBrandon Wyman } 2523f1242f3SBrandon Wyman 2539464c429SGeorge Liu PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, 2549464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 255681b2a36SB. J. Wyman // In order to get the various faults tested, the power supply needs to 256681b2a36SB. J. Wyman // be present in order to read from the PMBus device(s). 2573ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO2 = 2583ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO()); 25906ca4590SBrandon Wyman // Always return 1 to indicate present. 26006ca4590SBrandon Wyman // Each analyze() call will trigger a read of the presence GPIO. 26106ca4590SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO2, read()).WillRepeatedly(Return(1)); 262681b2a36SB. J. Wyman EXPECT_EQ(psu2.isPresent(), false); 2633f1242f3SBrandon Wyman 2643f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus()); 265391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 266ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 267ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 268ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 269ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 270592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 271b654c619SBrandon Wyman 272b654c619SBrandon Wyman // STATUS_WORD INPUT fault. 273b654c619SBrandon Wyman { 274b654c619SBrandon Wyman // Start with STATUS_WORD 0x0000. Powered on, no faults. 275b654c619SBrandon Wyman // Set expectations for a no fault 276b654c619SBrandon Wyman PMBusExpectations expectations; 277b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 27882affd94SBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 27982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 28082affd94SBrandon Wyman .Times(1) 28182affd94SBrandon Wyman .WillOnce(Return("206000")); 2823f1242f3SBrandon Wyman psu2.analyze(); 2833f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2843f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 2853f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 2863f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 2873f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 28885c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 2896710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 290b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 2912cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 2927ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 29396893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 2942916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 29539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 29639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 29739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 2983f1242f3SBrandon Wyman 299b654c619SBrandon Wyman // Update expectations for STATUS_WORD input fault/warn 30096893a46SBrandon Wyman // STATUS_INPUT fault bits ... on. 301b654c619SBrandon Wyman expectations.statusWordValue = (status_word::INPUT_FAULT_WARN); 3023225a45cSBrandon Wyman // IIN_OC fault. 3033225a45cSBrandon Wyman expectations.statusInputValue = 0x04; 304c2906f47SBrandon Wyman 305c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 306c2906f47SBrandon Wyman { 307b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 30882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 30982affd94SBrandon Wyman .Times(1) 31082affd94SBrandon Wyman .WillOnce(Return("207000")); 3113f1242f3SBrandon Wyman psu2.analyze(); 3123f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 313c2906f47SBrandon Wyman // Should not be faulted until it reaches the deglitch limit. 314c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 315c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT); 3163f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 3173f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 31885c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 3196710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 320b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 3212cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 3227ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 32396893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 3242916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 32539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 32639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 32739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 328b654c619SBrandon Wyman } 329c2906f47SBrandon Wyman } 330c2906f47SBrandon Wyman 33132453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 3323225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 3333225a45cSBrandon Wyman .Times(1) 3343225a45cSBrandon Wyman .WillOnce(Return(1)); 335c2906f47SBrandon Wyman psu2.clearFaults(); 3363f1242f3SBrandon Wyman 3373f1242f3SBrandon Wyman // STATUS_WORD INPUT/UV fault. 338b654c619SBrandon Wyman { 3393f1242f3SBrandon Wyman // First need it to return good status, then the fault 340b654c619SBrandon Wyman PMBusExpectations expectations; 341b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 34282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 34382affd94SBrandon Wyman .Times(1) 34482affd94SBrandon Wyman .WillOnce(Return("208000")); 3453f1242f3SBrandon Wyman psu2.analyze(); 346c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 347c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 3488da35c51SBrandon Wyman // Now set fault bits in STATUS_WORD 349b654c619SBrandon Wyman expectations.statusWordValue = 3508da35c51SBrandon Wyman (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT); 3518da35c51SBrandon Wyman // STATUS_INPUT fault bits ... on. 3523225a45cSBrandon Wyman expectations.statusInputValue = 0x18; 353c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 354c2906f47SBrandon Wyman { 355b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 35682affd94SBrandon Wyman // Input/UV fault, so voltage should read back low. 35782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 35882affd94SBrandon Wyman .Times(1) 35982affd94SBrandon Wyman .WillOnce(Return("19123")); 3603f1242f3SBrandon Wyman psu2.analyze(); 3613f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 362c2906f47SBrandon Wyman // Only faulted if hit deglitch limit 363c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 364c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT); 365c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), x >= DEGLITCH_LIMIT); 3663f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 36785c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 3686710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 369b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 3702cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 3717ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 37296893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 3732916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 37439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 37539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 37639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 377c2906f47SBrandon Wyman } 37882affd94SBrandon Wyman // Turning VIN_UV fault off causes clearing of faults, causing read of 37982affd94SBrandon Wyman // in1_input as an attempt to get CLEAR_FAULTS called. 38082affd94SBrandon Wyman expectations.statusWordValue = 0; 38182affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 38282affd94SBrandon Wyman // The call to read the voltage 38382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 38482affd94SBrandon Wyman .Times(1) 38582affd94SBrandon Wyman .WillOnce(Return("209000")); 3863225a45cSBrandon Wyman // The call to clear VIN_UV/Off fault(s) 3873225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 38832453e9bSBrandon Wyman .Times(1) 3893225a45cSBrandon Wyman .WillOnce(Return(1)); 39082affd94SBrandon Wyman psu2.analyze(); 39182affd94SBrandon Wyman // Should remain present, no longer be faulted, no input fault, no 39282affd94SBrandon Wyman // VIN_UV fault. Nothing else should change. 39382affd94SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 39482affd94SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 39582affd94SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 39682affd94SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 397b654c619SBrandon Wyman } 3983f1242f3SBrandon Wyman 39932453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 4003225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 4013225a45cSBrandon Wyman .Times(1) 4023225a45cSBrandon Wyman .WillOnce(Return(1)); 403c2906f47SBrandon Wyman psu2.clearFaults(); 404c2906f47SBrandon Wyman 4053f1242f3SBrandon Wyman // STATUS_WORD MFR fault. 406b654c619SBrandon Wyman { 407f07bc797SBrandon Wyman // First need it to return good status, then the fault 408b654c619SBrandon Wyman PMBusExpectations expectations; 409b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 41082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 41182affd94SBrandon Wyman .Times(1) 41282affd94SBrandon Wyman .WillOnce(Return("210000")); 4133f1242f3SBrandon Wyman psu2.analyze(); 4148da35c51SBrandon Wyman // Now STATUS_WORD with MFR fault bit on. 415b654c619SBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 4168da35c51SBrandon Wyman // STATUS_MFR bits on. 417b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 418c2906f47SBrandon Wyman 419c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 420c2906f47SBrandon Wyman { 421b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 42282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 42382affd94SBrandon Wyman .Times(1) 42482affd94SBrandon Wyman .WillOnce(Return("211000")); 4253f1242f3SBrandon Wyman psu2.analyze(); 4263f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 427c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 4283f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 429c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), x >= DEGLITCH_LIMIT); 430c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), x >= DEGLITCH_LIMIT); 431c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 432c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 4333f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 43485c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 4356710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 436b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 4372cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 4387ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 43996893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 4402916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 441c2906f47SBrandon Wyman } 442b654c619SBrandon Wyman } 4433f1242f3SBrandon Wyman 44432453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 4453225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 4463225a45cSBrandon Wyman .Times(1) 4473225a45cSBrandon Wyman .WillOnce(Return(1)); 448c2906f47SBrandon Wyman psu2.clearFaults(); 4493225a45cSBrandon Wyman 45096893a46SBrandon Wyman // Temperature fault. 451b654c619SBrandon Wyman { 452f07bc797SBrandon Wyman // First STATUS_WORD with no bits set, then with temperature fault. 453b654c619SBrandon Wyman PMBusExpectations expectations; 454b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 45582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 45682affd94SBrandon Wyman .Times(1) 45782affd94SBrandon Wyman .WillOnce(Return("212000")); 4583f1242f3SBrandon Wyman psu2.analyze(); 4598da35c51SBrandon Wyman // STATUS_WORD with temperature fault bit on. 460b654c619SBrandon Wyman expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 46196893a46SBrandon Wyman // STATUS_TEMPERATURE with fault bit(s) on. 46296893a46SBrandon Wyman expectations.statusTempValue = 0x10; 463c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 464c2906f47SBrandon Wyman { 465b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 46682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 46782affd94SBrandon Wyman .Times(1) 46882affd94SBrandon Wyman .WillOnce(Return("213000")); 4693f1242f3SBrandon Wyman psu2.analyze(); 4703f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 471c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 4723f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 4733f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 4743f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 47585c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 4766710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 477b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 4782cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 4797ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 480c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), x >= DEGLITCH_LIMIT); 4812916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 48239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 48339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 48439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 485b654c619SBrandon Wyman } 486c2906f47SBrandon Wyman } 48785c7bf41SBrandon Wyman 4886710ba2cSBrandon Wyman // VOUT_OV_FAULT fault 489b654c619SBrandon Wyman { 4906710ba2cSBrandon Wyman // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault. 491b654c619SBrandon Wyman PMBusExpectations expectations; 492b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 49382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 49482affd94SBrandon Wyman .Times(1) 49582affd94SBrandon Wyman .WillOnce(Return("216000")); 4966710ba2cSBrandon Wyman psu2.analyze(); 4976710ba2cSBrandon Wyman // STATUS_WORD with VOUT/VOUT_OV fault. 498b654c619SBrandon Wyman expectations.statusWordValue = 4996710ba2cSBrandon Wyman ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT)); 5006710ba2cSBrandon Wyman // Turn on STATUS_VOUT fault bit(s) 501b654c619SBrandon Wyman expectations.statusVOUTValue = 0xA0; 502c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 503c2906f47SBrandon Wyman { 50496893a46SBrandon Wyman // STATUS_TEMPERATURE don't care (default) 505b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 50682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 50782affd94SBrandon Wyman .Times(1) 50882affd94SBrandon Wyman .WillOnce(Return("217000")); 5096710ba2cSBrandon Wyman psu2.analyze(); 5106710ba2cSBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 511c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 5126710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 5136710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 5146710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 5156710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 516c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 5172cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 518b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 5197ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 520b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 521b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 52239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 52339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 52439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 525b10b3be0SBrandon Wyman } 526c2906f47SBrandon Wyman } 527b10b3be0SBrandon Wyman 528b10b3be0SBrandon Wyman // IOUT_OC_FAULT fault 529b10b3be0SBrandon Wyman { 530b10b3be0SBrandon Wyman // First STATUS_WORD with no bits set, then with IOUT_OC fault. 531b10b3be0SBrandon Wyman PMBusExpectations expectations; 532b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 53382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 53482affd94SBrandon Wyman .Times(1) 53582affd94SBrandon Wyman .WillOnce(Return("218000")); 536b10b3be0SBrandon Wyman psu2.analyze(); 537b10b3be0SBrandon Wyman // STATUS_WORD with IOUT_OC fault. 538b10b3be0SBrandon Wyman expectations.statusWordValue = status_word::IOUT_OC_FAULT; 539b10b3be0SBrandon Wyman // Turn on STATUS_IOUT fault bit(s) 540b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0x88; 541c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 542c2906f47SBrandon Wyman { 543b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 54482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 54582affd94SBrandon Wyman .Times(1) 54682affd94SBrandon Wyman .WillOnce(Return("219000")); 547b10b3be0SBrandon Wyman psu2.analyze(); 548b10b3be0SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 549c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 550b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 551b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 552b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 553b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 554b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 555c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 5562cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 5577ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 5582cf46945SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 5592cf46945SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 56039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 56139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 56239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 5632cf46945SBrandon Wyman } 564c2906f47SBrandon Wyman } 5652cf46945SBrandon Wyman 5662cf46945SBrandon Wyman // VOUT_UV_FAULT 5672cf46945SBrandon Wyman { 5682cf46945SBrandon Wyman // First STATUS_WORD with no bits set, then with VOUT fault. 5692cf46945SBrandon Wyman PMBusExpectations expectations; 5702cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 57182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 57282affd94SBrandon Wyman .Times(1) 57382affd94SBrandon Wyman .WillOnce(Return("220000")); 5742cf46945SBrandon Wyman psu2.analyze(); 5752cf46945SBrandon Wyman // Change STATUS_WORD to indicate VOUT fault. 5762cf46945SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_FAULT); 5772cf46945SBrandon Wyman // Turn on STATUS_VOUT fault bit(s) 5782cf46945SBrandon Wyman expectations.statusVOUTValue = 0x30; 579c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 580c2906f47SBrandon Wyman { 5812cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 58282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 58382affd94SBrandon Wyman .Times(1) 58482affd94SBrandon Wyman .WillOnce(Return("221000")); 5852cf46945SBrandon Wyman psu2.analyze(); 5862cf46945SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 587c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 5882cf46945SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 5892cf46945SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 5902cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 5912cf46945SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 5922cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 5932cf46945SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 594c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), x >= DEGLITCH_LIMIT); 5957ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 59696893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 5972916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 59839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 59939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 60039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 601b654c619SBrandon Wyman } 602c2906f47SBrandon Wyman } 6033f1242f3SBrandon Wyman 6047ee4d7e4SBrandon Wyman // Fan fault 605b654c619SBrandon Wyman { 606b654c619SBrandon Wyman // First STATUS_WORD with no bits set, then with fan fault. 607b654c619SBrandon Wyman PMBusExpectations expectations; 608b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 60982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 61082affd94SBrandon Wyman .Times(1) 61182affd94SBrandon Wyman .WillOnce(Return("222000")); 6123f1242f3SBrandon Wyman psu2.analyze(); 613b654c619SBrandon Wyman expectations.statusWordValue = (status_word::FAN_FAULT); 6147ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with fan 1 warning & fault bits on. 6157ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xA0; 616c2906f47SBrandon Wyman 617c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 618c2906f47SBrandon Wyman { 619b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 62082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 62182affd94SBrandon Wyman .Times(1) 62282affd94SBrandon Wyman .WillOnce(Return("223000")); 6233f1242f3SBrandon Wyman psu2.analyze(); 6243f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 625c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 626c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), x >= DEGLITCH_LIMIT); 6273f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 6283f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 6293f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 63085c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 6316710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 632b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 6332cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 63496893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6352916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 63639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 63739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 63839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 639b654c619SBrandon Wyman } 640c2906f47SBrandon Wyman } 6412916ea52SBrandon Wyman 64206ca4590SBrandon Wyman // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT. 6432cf46945SBrandon Wyman { 6442916ea52SBrandon Wyman // First STATUS_WORD with no bits set. 6452916ea52SBrandon Wyman PMBusExpectations expectations; 6462916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 64782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 64882affd94SBrandon Wyman .Times(1) 64982affd94SBrandon Wyman .WillOnce(Return("123000")); 6502916ea52SBrandon Wyman psu2.analyze(); 6512916ea52SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 6522916ea52SBrandon Wyman // POWER_GOOD# inactive, and OFF bit on. 6532916ea52SBrandon Wyman expectations.statusWordValue = 6542916ea52SBrandon Wyman ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF)); 6556d469fd4SBrandon Wyman for (auto x = 1; x <= PGOOD_DEGLITCH_LIMIT; x++) 65606ca4590SBrandon Wyman { 6572916ea52SBrandon Wyman // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and 6582916ea52SBrandon Wyman // STATUS_TEMPERATURE: Don't care if bits set or not (defaults). 6592916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 66082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 66182affd94SBrandon Wyman .Times(1) 66282affd94SBrandon Wyman .WillOnce(Return("124000")); 6632916ea52SBrandon Wyman psu2.analyze(); 6642916ea52SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 6656d469fd4SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= PGOOD_DEGLITCH_LIMIT); 6662916ea52SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 6672916ea52SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 6682916ea52SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 6692916ea52SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 6702916ea52SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 6712cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 672b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 6737ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 6742916ea52SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6756d469fd4SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), x >= PGOOD_DEGLITCH_LIMIT); 67606ca4590SBrandon Wyman } 67706ca4590SBrandon Wyman } 6782916ea52SBrandon Wyman 6793f1242f3SBrandon Wyman // TODO: ReadFailure 6803f1242f3SBrandon Wyman } 6813f1242f3SBrandon Wyman 68259a35793SBrandon Wyman TEST_F(PowerSupplyTests, OnOffConfig) 68359a35793SBrandon Wyman { 68459a35793SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 68559a35793SBrandon Wyman uint8_t data = 0x15; 68659a35793SBrandon Wyman 68759a35793SBrandon Wyman // Test where PSU is NOT present 68859a35793SBrandon Wyman try 68959a35793SBrandon Wyman { 690681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 6910975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, _)).Times(0); 6929464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, 6939464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 694681b2a36SB. J. Wyman 6953ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 6963ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 697681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0)); 69859a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 699681b2a36SB. J. Wyman // Constructor should set initial presence, default read returns 0. 70059a35793SBrandon Wyman // If it is not present, I should not be trying to write to it. 70159a35793SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0); 70259a35793SBrandon Wyman psu.onOffConfig(data); 70359a35793SBrandon Wyman } 70459a35793SBrandon Wyman catch (...) 7050c9a33d6SAdriana Kobylak {} 70659a35793SBrandon Wyman 70759a35793SBrandon Wyman // Test where PSU is present 70859a35793SBrandon Wyman try 70959a35793SBrandon Wyman { 710681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 7110975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 7129464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, 7139464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 7143ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7153ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 716391a0690SBrandon Wyman // There will potentially be multiple calls, we want it to continue 717391a0690SBrandon Wyman // returning 1 for the GPIO read to keep the power supply present. 718391a0690SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 71959a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 720391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 721ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 722ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 723ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 724ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 725592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 726391a0690SBrandon Wyman // If I am calling analyze(), I should probably give it good data. 727391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 728391a0690SBrandon Wyman PMBusExpectations expectations; 729391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 73082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 73182affd94SBrandon Wyman .Times(1) 73282affd94SBrandon Wyman .WillOnce(Return("205000")); 733681b2a36SB. J. Wyman psu.analyze(); 734391a0690SBrandon Wyman // I definitely should be writting ON_OFF_CONFIG if I call the function 735391a0690SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, ElementsAre(0x15), 736391a0690SBrandon Wyman Type::HwmonDeviceDebug)) 73759a35793SBrandon Wyman .Times(1); 73859a35793SBrandon Wyman psu.onOffConfig(data); 73959a35793SBrandon Wyman } 74059a35793SBrandon Wyman catch (...) 7410c9a33d6SAdriana Kobylak {} 74259a35793SBrandon Wyman } 74359a35793SBrandon Wyman 7443f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, ClearFaults) 7453f1242f3SBrandon Wyman { 7463f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 7479464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, 7489464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 7493ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7503ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 75106ca4590SBrandon Wyman // Always return 1 to indicate present. 75206ca4590SBrandon Wyman // Each analyze() call will trigger a read of the presence GPIO. 75306ca4590SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 754681b2a36SB. J. Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 755391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 756ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 757ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 758ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 759ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 760592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 7618da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 762b654c619SBrandon Wyman PMBusExpectations expectations; 763b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 76482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 76582affd94SBrandon Wyman .Times(1) 76682affd94SBrandon Wyman .WillOnce(Return("207000")); 767681b2a36SB. J. Wyman psu.analyze(); 7683f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 7693f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 7703f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 7713f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 7723f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 77385c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 7746710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 775b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 7762cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 7777ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 77896893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 7792916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 78039ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 78139ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 78239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 783b654c619SBrandon Wyman 784f07bc797SBrandon Wyman // STATUS_WORD with fault bits galore! 785b654c619SBrandon Wyman expectations.statusWordValue = 0xFFFF; 786f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 787b654c619SBrandon Wyman expectations.statusInputValue = 0xFF; 788f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 789b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 79085c7bf41SBrandon Wyman // STATUS_CML with bits on. 791b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 7926710ba2cSBrandon Wyman // STATUS_VOUT with bits on. 793b654c619SBrandon Wyman expectations.statusVOUTValue = 0xFF; 794b10b3be0SBrandon Wyman // STATUS_IOUT with bits on. 795b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0xFF; 7967ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with bits on. 7977ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xFF; 79896893a46SBrandon Wyman // STATUS_TEMPERATURE with bits on. 79996893a46SBrandon Wyman expectations.statusTempValue = 0xFF; 800c2906f47SBrandon Wyman 8016d469fd4SBrandon Wyman for (auto x = 1; x <= PGOOD_DEGLITCH_LIMIT; x++) 802c2906f47SBrandon Wyman { 803b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 80482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 80582affd94SBrandon Wyman .Times(1) 80682affd94SBrandon Wyman .WillOnce(Return("0")); 8070975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 8080975eaf4SMatt Spinler { 8090975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 8100975eaf4SMatt Spinler } 8113f1242f3SBrandon Wyman psu.analyze(); 8123f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8132cf46945SBrandon Wyman // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT. 8142cf46945SBrandon Wyman // Rely on HasVoutUVFault() to verify this sets and clears. 8152cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 8166d469fd4SBrandon Wyman // pgoodFault at PGOOD_DEGLITCH_LIMIT, all other faults are deglitched 8176d469fd4SBrandon Wyman // up to DEGLITCH_LIMIT 818c2906f47SBrandon Wyman EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT); 819c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 820c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 821c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 822c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 823c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 824c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 825c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 8266d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), x >= PGOOD_DEGLITCH_LIMIT); 827c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 828c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 829c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 830c2906f47SBrandon Wyman } 831c2906f47SBrandon Wyman 83232453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)) 83332453e9bSBrandon Wyman .Times(1) 83432453e9bSBrandon Wyman .WillOnce(Return(207000)); 8353225a45cSBrandon Wyman // Clearing VIN_UV fault via in1_lcrit_alarm 8363225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 8373225a45cSBrandon Wyman .Times(1) 8383225a45cSBrandon Wyman .WillOnce(Return(1)); 8390975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 8403f1242f3SBrandon Wyman psu.clearFaults(); 8413f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8423f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 8433f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 8443f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 8453f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 84685c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 8476710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 848b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 8492cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 8507ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 85196893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 8522916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 85339ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 85439ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 85539ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 856681b2a36SB. J. Wyman 85782affd94SBrandon Wyman // Faults clear on READ_VIN 0 -> !0 85882affd94SBrandon Wyman // STATUS_WORD with fault bits galore! 85982affd94SBrandon Wyman expectations.statusWordValue = 0xFFFF; 86082affd94SBrandon Wyman // STATUS_INPUT with fault bits on. 86182affd94SBrandon Wyman expectations.statusInputValue = 0xFF; 86282affd94SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 86382affd94SBrandon Wyman expectations.statusMFRValue = 0xFF; 86482affd94SBrandon Wyman // STATUS_CML with bits on. 86582affd94SBrandon Wyman expectations.statusCMLValue = 0xFF; 86682affd94SBrandon Wyman // STATUS_VOUT with bits on. 86782affd94SBrandon Wyman expectations.statusVOUTValue = 0xFF; 86882affd94SBrandon Wyman // STATUS_IOUT with bits on. 86982affd94SBrandon Wyman expectations.statusIOUTValue = 0xFF; 87082affd94SBrandon Wyman // STATUS_FANS_1_2 with bits on. 87182affd94SBrandon Wyman expectations.statusFans12Value = 0xFF; 87282affd94SBrandon Wyman // STATUS_TEMPERATURE with bits on. 87382affd94SBrandon Wyman expectations.statusTempValue = 0xFF; 874c2906f47SBrandon Wyman 8756d469fd4SBrandon Wyman // All faults deglitched now. Check for false before limit above. 876c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 877c2906f47SBrandon Wyman { 87882affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 87982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 88082affd94SBrandon Wyman .Times(1) 88182affd94SBrandon Wyman .WillOnce(Return("0")); 8820975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 8830975eaf4SMatt Spinler { 8840975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 8850975eaf4SMatt Spinler } 88682affd94SBrandon Wyman psu.analyze(); 887c2906f47SBrandon Wyman } 888c2906f47SBrandon Wyman 88982affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 89082affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 89182affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 89282affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 89382affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 894*6869acb3SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 89582affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 89682affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), true); 89782affd94SBrandon Wyman // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT. 89882affd94SBrandon Wyman // Rely on HasVoutUVFault() to verify this sets and clears. 89982affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 90082affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), true); 90182affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), true); 9026d469fd4SBrandon Wyman // No PGOOD fault, as less than PGOOD_DEGLITCH_LIMIT 9036d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 90482affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), true); 90582affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), true); 90682affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), true); 90782affd94SBrandon Wyman // STATUS_WORD with INPUT/VIN_UV fault bits off. 90882affd94SBrandon Wyman expectations.statusWordValue = 0xDFF7; 90982affd94SBrandon Wyman // STATUS_INPUT with VIN_UV_WARNING, VIN_UV_FAULT, and Unit Off For 91082affd94SBrandon Wyman // Insufficient Input Voltage bits off. 91182affd94SBrandon Wyman expectations.statusInputValue = 0xC7; 91282affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 91382affd94SBrandon Wyman // READ_VIN back in range. 91482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 91582affd94SBrandon Wyman .Times(1) 91682affd94SBrandon Wyman .WillOnce(Return("206000")); 9173225a45cSBrandon Wyman // VIN_UV cleared via in1_lcrit_alarm when voltage back in range. 9183225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 9193225a45cSBrandon Wyman .Times(1) 9203225a45cSBrandon Wyman .WillOnce(Return(1)); 9213225a45cSBrandon Wyman psu.analyze(); 9223225a45cSBrandon Wyman // We only cleared the VIN_UV and OFF faults. 9233225a45cSBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 9243225a45cSBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 9253225a45cSBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 9263225a45cSBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 9273225a45cSBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 928*6869acb3SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 9293225a45cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 9303225a45cSBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), true); 9313225a45cSBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 9323225a45cSBrandon Wyman EXPECT_EQ(psu.hasFanFault(), true); 9333225a45cSBrandon Wyman EXPECT_EQ(psu.hasTempFault(), true); 9346d469fd4SBrandon Wyman // No PGOOD fault, as less than PGOOD_DEGLITCH_LIMIT 9356d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 9363225a45cSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), true); 9373225a45cSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), true); 9383225a45cSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), true); 9393225a45cSBrandon Wyman 9403225a45cSBrandon Wyman // All faults cleared 9413225a45cSBrandon Wyman expectations = {0}; 9423225a45cSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 9433225a45cSBrandon Wyman // READ_VIN back in range. 9443225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 9453225a45cSBrandon Wyman .Times(1) 9463225a45cSBrandon Wyman .WillOnce(Return("206000")); 9470975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 94882affd94SBrandon Wyman psu.analyze(); 94982affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 95082affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 95182affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 95282affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 95382affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 95482affd94SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 95582affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 95682affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 95782affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 95882affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 95982affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 96082affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 96182affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 96282affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 96382affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 96482affd94SBrandon Wyman 965681b2a36SB. J. Wyman // TODO: Faults clear on missing/present? 9663f1242f3SBrandon Wyman } 9673f1242f3SBrandon Wyman 9683f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory) 9693f1242f3SBrandon Wyman { 9703f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 9711d7a7df8SBrandon Wyman 9721d7a7df8SBrandon Wyman try 9731d7a7df8SBrandon Wyman { 9749464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 9759464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 9761d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 9771d7a7df8SBrandon Wyman // If it is not present, I should not be trying to read a string 9781d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).Times(0); 9791d7a7df8SBrandon Wyman psu.updateInventory(); 9801d7a7df8SBrandon Wyman } 9811d7a7df8SBrandon Wyman catch (...) 9821d7a7df8SBrandon Wyman { 9831d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 9841d7a7df8SBrandon Wyman } 9851d7a7df8SBrandon Wyman 9861d7a7df8SBrandon Wyman try 9871d7a7df8SBrandon Wyman { 9889464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, 9899464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 9903ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 9913ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 992681b2a36SB. J. Wyman // GPIO read return 1 to indicate present. 993681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 9941d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 995391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 996ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 997ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 998ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 999ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1000592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 1001391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1002391a0690SBrandon Wyman PMBusExpectations expectations; 1003391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 100482affd94SBrandon Wyman // Call to analyze will read voltage, trigger clear faults for 0 to 100582affd94SBrandon Wyman // within range. 100682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 100782affd94SBrandon Wyman .Times(1) 100882affd94SBrandon Wyman .WillOnce(Return("123456")); 1009391a0690SBrandon Wyman psu.analyze(); 10101d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return("")); 10113f1242f3SBrandon Wyman psu.updateInventory(); 10121d7a7df8SBrandon Wyman 10133c530fbdSBrandon Wyman #if IBM_VPD 10141d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)) 10151d7a7df8SBrandon Wyman .WillOnce(Return("CCIN")) 10161d7a7df8SBrandon Wyman .WillOnce(Return("PN3456")) 10171d7a7df8SBrandon Wyman .WillOnce(Return("FN3456")) 10181d7a7df8SBrandon Wyman .WillOnce(Return("HEADER")) 10191d7a7df8SBrandon Wyman .WillOnce(Return("SN3456")) 10201d7a7df8SBrandon Wyman .WillOnce(Return("FW3456")); 10213c530fbdSBrandon Wyman #endif 10221d7a7df8SBrandon Wyman psu.updateInventory(); 10231d7a7df8SBrandon Wyman // TODO: D-Bus mocking to verify values stored on D-Bus (???) 10241d7a7df8SBrandon Wyman } 10251d7a7df8SBrandon Wyman catch (...) 10261d7a7df8SBrandon Wyman { 10271d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 10281d7a7df8SBrandon Wyman } 10293f1242f3SBrandon Wyman } 10303f1242f3SBrandon Wyman 10313f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent) 10323f1242f3SBrandon Wyman { 10333f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1034681b2a36SB. J. Wyman 10359464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 10369464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 10373ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10383ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 10393f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 10403f1242f3SBrandon Wyman 1041681b2a36SB. J. Wyman // Change GPIO read to return 1 to indicate present. 1042681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 1043391a0690SBrandon Wyman // Call to analyze() will update to present, that will trigger updating 1044391a0690SBrandon Wyman // to the correct/latest HWMON directory, in case it changes. 1045391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1046391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1047ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1048ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1049ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1050ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1051592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 1052391a0690SBrandon Wyman // Call to analyze things will trigger read of STATUS_WORD and READ_VIN. 1053391a0690SBrandon Wyman // Default expectations will be on, no faults. 1054391a0690SBrandon Wyman PMBusExpectations expectations; 1055391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 105682affd94SBrandon Wyman // Give it an input voltage in the 100-volt range. 105782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 105882affd94SBrandon Wyman .Times(1) 105982affd94SBrandon Wyman .WillOnce(Return("123456")); 10600975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1061681b2a36SB. J. Wyman psu.analyze(); 1062681b2a36SB. J. Wyman EXPECT_EQ(psu.isPresent(), true); 10633f1242f3SBrandon Wyman } 10643f1242f3SBrandon Wyman 10653f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted) 10663f1242f3SBrandon Wyman { 10673f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1068681b2a36SB. J. Wyman 10699464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, 10709464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 10713ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10723ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1073681b2a36SB. J. Wyman // Always return 1 to indicate present. 1074681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1075391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1076391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1077ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1078ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1079ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1080ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1081592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 1082391a0690SBrandon Wyman // Call to analyze things will trigger read of STATUS_WORD and READ_VIN. 1083391a0690SBrandon Wyman // Default expectations will be on, no faults. 1084391a0690SBrandon Wyman PMBusExpectations expectations; 1085391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 108682affd94SBrandon Wyman // Give it an input voltage in the 100-volt range. 108782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 108882affd94SBrandon Wyman .Times(1) 108982affd94SBrandon Wyman .WillOnce(Return("124680")); 1090681b2a36SB. J. Wyman psu.analyze(); 10913f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 1092f07bc797SBrandon Wyman // STATUS_WORD with fault bits on. 1093b654c619SBrandon Wyman expectations.statusWordValue = 0xFFFF; 1094f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 1095b654c619SBrandon Wyman expectations.statusInputValue = 0xFF; 1096f07bc797SBrandon Wyman // STATUS_MFR_SPECIFIC with faults bits on. 1097b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 109885c7bf41SBrandon Wyman // STATUS_CML with faults bits on. 1099b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 11006710ba2cSBrandon Wyman // STATUS_VOUT with fault bits on. 1101b654c619SBrandon Wyman expectations.statusVOUTValue = 0xFF; 1102b10b3be0SBrandon Wyman // STATUS_IOUT with fault bits on. 1103b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0xFF; 11047ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with bits on. 11057ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xFF; 110696893a46SBrandon Wyman // STATUS_TEMPERATURE with fault bits on. 110796893a46SBrandon Wyman expectations.statusTempValue = 0xFF; 1108c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1109c2906f47SBrandon Wyman { 1110b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 11114fc191f0SBrandon Wyman // Also get another read of READ_VIN, faulted, so not in 100-volt range 111282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 111382affd94SBrandon Wyman .Times(1) 11144fc191f0SBrandon Wyman .WillOnce(Return("19000")); 11150975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 11160975eaf4SMatt Spinler { 11170975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 11180975eaf4SMatt Spinler } 11193f1242f3SBrandon Wyman psu.analyze(); 1120c2906f47SBrandon Wyman EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT); 1121c2906f47SBrandon Wyman } 11223f1242f3SBrandon Wyman } 11233f1242f3SBrandon Wyman 11243f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasInputFault) 11253f1242f3SBrandon Wyman { 11263f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1127681b2a36SB. J. Wyman 11289464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 11299464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 11303ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 11313ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1132681b2a36SB. J. Wyman // Always return 1 to indicate present. 1133681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 11343f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1135391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1136ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1137ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1138ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1139ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1140592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 11418da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1142b654c619SBrandon Wyman PMBusExpectations expectations; 1143b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 114482affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 114582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 114682affd94SBrandon Wyman .Times(1) 114782affd94SBrandon Wyman .WillOnce(Return("201100")); 11483f1242f3SBrandon Wyman psu.analyze(); 11493f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 1150f07bc797SBrandon Wyman // STATUS_WORD with input fault/warn on. 1151b654c619SBrandon Wyman expectations.statusWordValue = (status_word::INPUT_FAULT_WARN); 1152f07bc797SBrandon Wyman // STATUS_INPUT with an input fault bit on. 1153b654c619SBrandon Wyman expectations.statusInputValue = 0x80; 1154c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1155c2906f47SBrandon Wyman { 1156b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 115782affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 115882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 115982affd94SBrandon Wyman .Times(1) 116082affd94SBrandon Wyman .WillOnce(Return("201200")); 11610975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 11620975eaf4SMatt Spinler { 11630975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 11640975eaf4SMatt Spinler } 11653f1242f3SBrandon Wyman psu.analyze(); 1166c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 1167c2906f47SBrandon Wyman } 1168f07bc797SBrandon Wyman // STATUS_WORD with no bits on. 1169b654c619SBrandon Wyman expectations.statusWordValue = 0; 1170b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 117182affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 117282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 117382affd94SBrandon Wyman .Times(1) 117482affd94SBrandon Wyman .WillOnce(Return("201300")); 11750975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 11763f1242f3SBrandon Wyman psu.analyze(); 11773f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 11783f1242f3SBrandon Wyman } 11793f1242f3SBrandon Wyman 11803f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault) 11813f1242f3SBrandon Wyman { 11823f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1183681b2a36SB. J. Wyman 11849464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 11859464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 11863ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 11873ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1188681b2a36SB. J. Wyman // Always return 1 to indicate present. 1189681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 11903f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1191391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1192ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1193ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1194ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1195ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1196592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 1197f07bc797SBrandon Wyman // First return STATUS_WORD with no bits on. 11988da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1199b654c619SBrandon Wyman PMBusExpectations expectations; 1200b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 120182affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 120282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 120382affd94SBrandon Wyman .Times(1) 120482affd94SBrandon Wyman .WillOnce(Return("202100")); 12053f1242f3SBrandon Wyman psu.analyze(); 12063f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 1207f07bc797SBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 1208b654c619SBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 1209f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 1210b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 1211c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1212c2906f47SBrandon Wyman { 1213b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 121482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 121582affd94SBrandon Wyman .Times(1) 121682affd94SBrandon Wyman .WillOnce(Return("202200")); 12173f1242f3SBrandon Wyman psu.analyze(); 1218c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 1219c2906f47SBrandon Wyman } 1220f07bc797SBrandon Wyman // Back to no bits on in STATUS_WORD 1221b654c619SBrandon Wyman expectations.statusWordValue = 0; 1222b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 122382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 122482affd94SBrandon Wyman .Times(1) 122582affd94SBrandon Wyman .WillOnce(Return("202300")); 12263f1242f3SBrandon Wyman psu.analyze(); 12273f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 12283f1242f3SBrandon Wyman } 12293f1242f3SBrandon Wyman 12303f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault) 12313f1242f3SBrandon Wyman { 12323f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1233681b2a36SB. J. Wyman 12349464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 12359464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 12363ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 12373ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1238681b2a36SB. J. Wyman // Always return 1 to indicate present. 1239681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 12403f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1241391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1242ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1243ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1244ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1245ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1246592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 124782affd94SBrandon Wyman 124882affd94SBrandon Wyman // Presence change from missing to present will trigger in1_input read in 124982affd94SBrandon Wyman // an attempt to get CLEAR_FAULTS called. Return value ignored. 125082affd94SBrandon Wyman // Zero to non-zero voltage, for missing/present change, triggers clear 125182affd94SBrandon Wyman // faults call again. Return value ignored. 125282affd94SBrandon Wyman // Fault (low voltage) to not faulted (voltage in range) triggers clear 125382affd94SBrandon Wyman // faults call a third time. 125482affd94SBrandon Wyman 12558da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1256b654c619SBrandon Wyman PMBusExpectations expectations; 1257b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 125882affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 125982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 126082affd94SBrandon Wyman .Times(1) 126182affd94SBrandon Wyman .WillOnce(Return("201100")); 12623f1242f3SBrandon Wyman psu.analyze(); 12633f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 1264f07bc797SBrandon Wyman // Turn fault on. 1265b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VIN_UV_FAULT); 126685c7bf41SBrandon Wyman // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by 126785c7bf41SBrandon Wyman // Figure 16, and assume bits on in STATUS_INPUT. 1268b654c619SBrandon Wyman expectations.statusInputValue = 0x18; 1269c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1270c2906f47SBrandon Wyman { 1271b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 127282affd94SBrandon Wyman // If there is a VIN_UV fault, fake reading voltage of less than 20V 127382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 127482affd94SBrandon Wyman .Times(1) 127582affd94SBrandon Wyman .WillOnce(Return("19876")); 12760975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 12770975eaf4SMatt Spinler { 12780975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 12790975eaf4SMatt Spinler } 12803f1242f3SBrandon Wyman psu.analyze(); 1281c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 1282c2906f47SBrandon Wyman } 1283f07bc797SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1284b654c619SBrandon Wyman expectations.statusWordValue = 0; 1285b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 128682affd94SBrandon Wyman // Updates now result in clearing faults if read voltage goes from below the 128782affd94SBrandon Wyman // minimum, to within a valid range. 128882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 128982affd94SBrandon Wyman .Times(1) 129082affd94SBrandon Wyman .WillOnce(Return("201300")); 12913225a45cSBrandon Wyman // Went from below minimum to within range, expect clearVinUVFault(). 12923225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 12933225a45cSBrandon Wyman .Times(1) 12943225a45cSBrandon Wyman .WillOnce(Return(1)); 12950975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 12963f1242f3SBrandon Wyman psu.analyze(); 12973f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 12983f1242f3SBrandon Wyman } 12996710ba2cSBrandon Wyman 13006710ba2cSBrandon Wyman TEST_F(PowerSupplyTests, HasVoutOVFault) 13016710ba2cSBrandon Wyman { 13026710ba2cSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 13036710ba2cSBrandon Wyman 13049464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x69, 13059464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 13066710ba2cSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 13076710ba2cSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 13086710ba2cSBrandon Wyman // Always return 1 to indicate present. 13096710ba2cSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 13106710ba2cSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1311391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1312ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1313ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1314ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1315ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1316592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 13176710ba2cSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1318b654c619SBrandon Wyman PMBusExpectations expectations; 1319b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 132082affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 132182affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 132282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 132382affd94SBrandon Wyman .Times(1) 132482affd94SBrandon Wyman .WillOnce(Return("202100")); 13256710ba2cSBrandon Wyman psu.analyze(); 13266710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 13276710ba2cSBrandon Wyman // Turn fault on. 1328b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_OV_FAULT); 13296710ba2cSBrandon Wyman // STATUS_VOUT fault bit(s) 1330b654c619SBrandon Wyman expectations.statusVOUTValue = 0x80; 1331c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1332c2906f47SBrandon Wyman { 1333b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 133482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 133582affd94SBrandon Wyman .Times(1) 133682affd94SBrandon Wyman .WillOnce(Return("202200")); 13376710ba2cSBrandon Wyman psu.analyze(); 1338c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 1339c2906f47SBrandon Wyman } 13406710ba2cSBrandon Wyman // Back to no fault bits on in STATUS_WORD 1341b654c619SBrandon Wyman expectations.statusWordValue = 0; 1342b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 134382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 134482affd94SBrandon Wyman .Times(1) 134582affd94SBrandon Wyman .WillOnce(Return("202300")); 13466710ba2cSBrandon Wyman psu.analyze(); 13476710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 13486710ba2cSBrandon Wyman } 134996893a46SBrandon Wyman 1350b10b3be0SBrandon Wyman TEST_F(PowerSupplyTests, HasIoutOCFault) 1351b10b3be0SBrandon Wyman { 1352b10b3be0SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1353b10b3be0SBrandon Wyman 13549464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, 13559464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 1356b10b3be0SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1357b10b3be0SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1358b10b3be0SBrandon Wyman // Always return 1 to indicate present. 1359b10b3be0SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1360b10b3be0SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1361391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1362ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1363ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1364ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1365ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1366592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 1367b10b3be0SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1368b10b3be0SBrandon Wyman PMBusExpectations expectations; 1369b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 137082affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 137182affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 137282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 137382affd94SBrandon Wyman .Times(1) 137482affd94SBrandon Wyman .WillOnce(Return("203100")); 1375b10b3be0SBrandon Wyman psu.analyze(); 1376b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1377b10b3be0SBrandon Wyman // Turn fault on. 1378b10b3be0SBrandon Wyman expectations.statusWordValue = status_word::IOUT_OC_FAULT; 1379b10b3be0SBrandon Wyman // STATUS_IOUT fault bit(s) 1380b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0x88; 1381c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1382c2906f47SBrandon Wyman { 1383b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 138482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 138582affd94SBrandon Wyman .Times(1) 138682affd94SBrandon Wyman .WillOnce(Return("203200")); 13870975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 13880975eaf4SMatt Spinler { 13890975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 13900975eaf4SMatt Spinler } 1391b10b3be0SBrandon Wyman psu.analyze(); 1392c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 1393c2906f47SBrandon Wyman } 1394b10b3be0SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1395b10b3be0SBrandon Wyman expectations.statusWordValue = 0; 1396b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 139782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 139882affd94SBrandon Wyman .Times(1) 139982affd94SBrandon Wyman .WillOnce(Return("203300")); 14000975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1401b10b3be0SBrandon Wyman psu.analyze(); 1402b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1403b10b3be0SBrandon Wyman } 1404b10b3be0SBrandon Wyman 14052cf46945SBrandon Wyman TEST_F(PowerSupplyTests, HasVoutUVFault) 14062cf46945SBrandon Wyman { 14072cf46945SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 14082cf46945SBrandon Wyman 14099464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, 14109464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 14112cf46945SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 14122cf46945SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 14132cf46945SBrandon Wyman // Always return 1 to indicate present. 14142cf46945SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 14152cf46945SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1416391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1417ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1418ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1419ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1420ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1421592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 1422391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 14232cf46945SBrandon Wyman PMBusExpectations expectations; 14242cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 142582affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 142682affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 142782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 142882affd94SBrandon Wyman .Times(1) 142982affd94SBrandon Wyman .WillOnce(Return("204100")); 14302cf46945SBrandon Wyman psu.analyze(); 14312cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 14322cf46945SBrandon Wyman // Turn fault on. 14332cf46945SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_FAULT); 14342cf46945SBrandon Wyman // STATUS_VOUT fault bit(s) 14352cf46945SBrandon Wyman expectations.statusVOUTValue = 0x30; 1436c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1437c2906f47SBrandon Wyman { 14382cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 143982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 144082affd94SBrandon Wyman .Times(1) 144182affd94SBrandon Wyman .WillOnce(Return("204200")); 14422cf46945SBrandon Wyman psu.analyze(); 1443c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), x >= DEGLITCH_LIMIT); 1444c2906f47SBrandon Wyman } 14452cf46945SBrandon Wyman // Back to no fault bits on in STATUS_WORD 14462cf46945SBrandon Wyman expectations.statusWordValue = 0; 14472cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 144882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 144982affd94SBrandon Wyman .Times(1) 145082affd94SBrandon Wyman .WillOnce(Return("204300")); 14512cf46945SBrandon Wyman psu.analyze(); 14522cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 14532cf46945SBrandon Wyman } 14542cf46945SBrandon Wyman 14557ee4d7e4SBrandon Wyman TEST_F(PowerSupplyTests, HasFanFault) 14567ee4d7e4SBrandon Wyman { 14577ee4d7e4SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 14587ee4d7e4SBrandon Wyman 14590975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1); 14600975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0); 14610975eaf4SMatt Spinler 14629464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, 14639464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 14647ee4d7e4SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 14657ee4d7e4SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 14667ee4d7e4SBrandon Wyman // Always return 1 to indicate present. 14677ee4d7e4SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 14687ee4d7e4SBrandon 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, _)) 1474592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 14757ee4d7e4SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 14767ee4d7e4SBrandon Wyman PMBusExpectations expectations; 14777ee4d7e4SBrandon 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("205100")); 14837ee4d7e4SBrandon Wyman psu.analyze(); 14847ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 14857ee4d7e4SBrandon Wyman // Turn fault on. 14867ee4d7e4SBrandon Wyman expectations.statusWordValue = (status_word::FAN_FAULT); 14877ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 fault bit on (Fan 1 Fault) 14887ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0x80; 1489c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1490c2906f47SBrandon Wyman { 14917ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 149282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 149382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 149482affd94SBrandon Wyman .Times(1) 149582affd94SBrandon Wyman .WillOnce(Return("205200")); 14967ee4d7e4SBrandon Wyman psu.analyze(); 1497c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 1498c2906f47SBrandon Wyman } 14997ee4d7e4SBrandon Wyman // Back to no fault bits on in STATUS_WORD 15007ee4d7e4SBrandon Wyman expectations.statusWordValue = 0; 15017ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 150282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 150382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 150482affd94SBrandon Wyman .Times(1) 150582affd94SBrandon Wyman .WillOnce(Return("205300")); 15067ee4d7e4SBrandon Wyman psu.analyze(); 15077ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 15087ee4d7e4SBrandon Wyman } 15097ee4d7e4SBrandon Wyman 151096893a46SBrandon Wyman TEST_F(PowerSupplyTests, HasTempFault) 151196893a46SBrandon Wyman { 151296893a46SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 151396893a46SBrandon Wyman 15140975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1); 15150975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0); 15160975eaf4SMatt Spinler 15179464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, 15189464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 151996893a46SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 152096893a46SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 152196893a46SBrandon Wyman // Always return 1 to indicate present. 152296893a46SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 152396893a46SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1524391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1525ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1526ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1527ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1528ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1529592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 153096893a46SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 153196893a46SBrandon Wyman PMBusExpectations expectations; 153296893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 153382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 153482affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 153582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 153682affd94SBrandon Wyman .Times(1) 153782affd94SBrandon Wyman .WillOnce(Return("206100")); 153896893a46SBrandon Wyman psu.analyze(); 153996893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 154096893a46SBrandon Wyman // Turn fault on. 154196893a46SBrandon Wyman expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 154296893a46SBrandon Wyman // STATUS_TEMPERATURE fault bit on (OT Fault) 154396893a46SBrandon Wyman expectations.statusTempValue = 0x80; 1544c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1545c2906f47SBrandon Wyman { 154696893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 154782affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 154882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 154982affd94SBrandon Wyman .Times(1) 155082affd94SBrandon Wyman .WillOnce(Return("206200")); 155196893a46SBrandon Wyman psu.analyze(); 1552c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 1553c2906f47SBrandon Wyman } 155496893a46SBrandon Wyman // Back to no fault bits on in STATUS_WORD 155596893a46SBrandon Wyman expectations.statusWordValue = 0; 155696893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 155782affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 155882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 155982affd94SBrandon Wyman .Times(1) 156082affd94SBrandon Wyman .WillOnce(Return("206300")); 156196893a46SBrandon Wyman psu.analyze(); 156296893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 156396893a46SBrandon Wyman } 15642916ea52SBrandon Wyman 15652916ea52SBrandon Wyman TEST_F(PowerSupplyTests, HasPgoodFault) 15662916ea52SBrandon Wyman { 15672916ea52SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 15682916ea52SBrandon Wyman 15699464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x6b, 15709464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 15712916ea52SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 15722916ea52SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 15732916ea52SBrandon Wyman // Always return 1 to indicate present. 15742916ea52SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 15752916ea52SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1576391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1577ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1578ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1579ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1580ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1581592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 15822916ea52SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 15832916ea52SBrandon Wyman PMBusExpectations expectations; 15842916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 158582affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 158682affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 158782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 158882affd94SBrandon Wyman .Times(1) 158982affd94SBrandon Wyman .WillOnce(Return("207100")); 15902916ea52SBrandon Wyman psu.analyze(); 15912916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 1592391a0690SBrandon Wyman // Setup another expectation of no faults. 1593391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 159482affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 159582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 159682affd94SBrandon Wyman .Times(1) 159782affd94SBrandon Wyman .WillOnce(Return("207200")); 159882affd94SBrandon Wyman psu.analyze(); 159982affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 160082affd94SBrandon Wyman // Setup another expectation of no faults. 160182affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 160282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 160382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 160482affd94SBrandon Wyman .Times(1) 160582affd94SBrandon Wyman .WillOnce(Return("207300")); 1606391a0690SBrandon Wyman psu.analyze(); 1607391a0690SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 16082916ea52SBrandon Wyman // Turn PGOOD# off (fault on). 16092916ea52SBrandon Wyman expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED); 16102916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 161182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 161282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 161382affd94SBrandon Wyman .Times(1) 161482affd94SBrandon Wyman .WillOnce(Return("207400")); 16152916ea52SBrandon Wyman psu.analyze(); 16166d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 1 161706ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 161806ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 161982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 162082affd94SBrandon Wyman .Times(1) 162182affd94SBrandon Wyman .WillOnce(Return("207500")); 162206ca4590SBrandon Wyman psu.analyze(); 16236d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 2 162406ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 162506ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 162682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 162782affd94SBrandon Wyman .Times(1) 162882affd94SBrandon Wyman .WillOnce(Return("207600")); 162906ca4590SBrandon Wyman psu.analyze(); 16306d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 3 16316d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 16326d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 16336d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 16346d469fd4SBrandon Wyman .Times(1) 16356d469fd4SBrandon Wyman .WillOnce(Return("207700")); 16366d469fd4SBrandon Wyman psu.analyze(); 16376d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 4 16386d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 16396d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 16406d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 16416d469fd4SBrandon Wyman .Times(1) 16426d469fd4SBrandon Wyman .WillOnce(Return("207800")); 16436d469fd4SBrandon Wyman psu.analyze(); 16446d469fd4SBrandon Wyman // Expect true. PGOOD_DEGLITCH_LIMIT @ 5 16452916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 16462916ea52SBrandon Wyman // Back to no fault bits on in STATUS_WORD 16472916ea52SBrandon Wyman expectations.statusWordValue = 0; 16482916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 164982affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 165082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 165182affd94SBrandon Wyman .Times(1) 165282affd94SBrandon Wyman .WillOnce(Return("207700")); 16532916ea52SBrandon Wyman psu.analyze(); 16542916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 165582affd94SBrandon Wyman 16562916ea52SBrandon Wyman // Turn OFF bit on 16572916ea52SBrandon Wyman expectations.statusWordValue = (status_word::UNIT_IS_OFF); 16582916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 165982affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 166082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 166182affd94SBrandon Wyman .Times(1) 166282affd94SBrandon Wyman .WillOnce(Return("208100")); 16632916ea52SBrandon Wyman psu.analyze(); 166406ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 166506ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 166682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 166782affd94SBrandon Wyman .Times(1) 166882affd94SBrandon Wyman .WillOnce(Return("208200")); 166906ca4590SBrandon Wyman psu.analyze(); 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("208300")); 167506ca4590SBrandon Wyman psu.analyze(); 16766d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 16776d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 16786d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 16796d469fd4SBrandon Wyman .Times(1) 16806d469fd4SBrandon Wyman .WillOnce(Return("208400")); 16816d469fd4SBrandon Wyman psu.analyze(); 16826d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 16836d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 16846d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 16856d469fd4SBrandon Wyman .Times(1) 16866d469fd4SBrandon Wyman .WillOnce(Return("208500")); 16876d469fd4SBrandon Wyman psu.analyze(); 16882916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 16892916ea52SBrandon Wyman // Back to no fault bits on in STATUS_WORD 16902916ea52SBrandon Wyman expectations.statusWordValue = 0; 16912916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 169282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 169382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 169482affd94SBrandon Wyman .Times(1) 16956d469fd4SBrandon Wyman .WillOnce(Return("208000")); 16962916ea52SBrandon Wyman psu.analyze(); 16972916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 16982916ea52SBrandon Wyman } 169939ea02bcSBrandon Wyman 170039ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSKillFault) 170139ea02bcSBrandon Wyman { 170239ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 17039464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 4, 0x6d, 17049464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 170539ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 170639ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 170739ea02bcSBrandon Wyman // Always return 1 to indicate present. 170839ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 170939ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 171082affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1711ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1712ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1713ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1714ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1715592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 171639ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 171739ea02bcSBrandon Wyman PMBusExpectations expectations; 171839ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 171982affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 172082affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 172182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 172282affd94SBrandon Wyman .Times(1) 172382affd94SBrandon Wyman .WillOnce(Return("208100")); 172439ea02bcSBrandon Wyman psu.analyze(); 172539ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 172639ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 172739ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 172839ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 172939ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1730c2906f47SBrandon Wyman 1731c2906f47SBrandon Wyman // Deglitching faults, false until read the fault bits on up to the limit. 1732c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1733c2906f47SBrandon Wyman { 173439ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 173582affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 173682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 173782affd94SBrandon Wyman .Times(1) 173882affd94SBrandon Wyman .WillOnce(Return("208200")); 17390975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 17400975eaf4SMatt Spinler { 17410975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 17420975eaf4SMatt Spinler } 174339ea02bcSBrandon Wyman psu.analyze(); 1744c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1745c2906f47SBrandon Wyman } 1746c2906f47SBrandon Wyman 174739ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 174839ea02bcSBrandon Wyman expectations.statusWordValue = 0; 174939ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 175082affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 175182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 175282affd94SBrandon Wyman .Times(1) 175382affd94SBrandon Wyman .WillOnce(Return("208300")); 17540975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 175539ea02bcSBrandon Wyman psu.analyze(); 175639ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 175739ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 175839ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 175939ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 4 on. 176039ea02bcSBrandon Wyman expectations.statusMFRValue = 0x10; 1761c2906f47SBrandon Wyman 1762c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1763c2906f47SBrandon Wyman { 176439ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 176582affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 176682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 176782affd94SBrandon Wyman .Times(1) 176882affd94SBrandon Wyman .WillOnce(Return("208400")); 17690975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 17700975eaf4SMatt Spinler { 17710975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 17720975eaf4SMatt Spinler } 177339ea02bcSBrandon Wyman psu.analyze(); 1774c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1775c2906f47SBrandon Wyman } 1776c2906f47SBrandon Wyman 177739ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 177839ea02bcSBrandon Wyman expectations.statusWordValue = 0; 177939ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 178082affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 178182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 178282affd94SBrandon Wyman .Times(1) 178382affd94SBrandon Wyman .WillOnce(Return("208500")); 17840975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 178539ea02bcSBrandon Wyman psu.analyze(); 178639ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 178739ea02bcSBrandon Wyman } 178839ea02bcSBrandon Wyman 178939ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPS12VcsFault) 179039ea02bcSBrandon Wyman { 179139ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 17929464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 5, 0x6e, 17939464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 179439ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 179539ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 179639ea02bcSBrandon Wyman // Always return 1 to indicate present. 179739ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 179839ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 179982affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1800ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1801ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1802ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1803ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1804592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 180539ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 180639ea02bcSBrandon Wyman PMBusExpectations expectations; 180739ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 180882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 180982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 181082affd94SBrandon Wyman .Times(1) 181182affd94SBrandon Wyman .WillOnce(Return("209100")); 181239ea02bcSBrandon Wyman psu.analyze(); 181339ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 181439ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 181539ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 181639ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 181739ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1818c2906f47SBrandon Wyman 1819c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1820c2906f47SBrandon Wyman { 182139ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 182282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 182382affd94SBrandon Wyman .Times(1) 182482affd94SBrandon Wyman .WillOnce(Return("209200")); 182539ea02bcSBrandon Wyman psu.analyze(); 1826c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1827c2906f47SBrandon Wyman } 1828c2906f47SBrandon Wyman 182939ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 183039ea02bcSBrandon Wyman expectations.statusWordValue = 0; 183139ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 183282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 183382affd94SBrandon Wyman .Times(1) 183482affd94SBrandon Wyman .WillOnce(Return("209300")); 183539ea02bcSBrandon Wyman psu.analyze(); 183639ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 183739ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 183839ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 183939ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 6 on. 184039ea02bcSBrandon Wyman expectations.statusMFRValue = 0x40; 1841c2906f47SBrandon Wyman 1842c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1843c2906f47SBrandon Wyman { 184439ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 184582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 184682affd94SBrandon Wyman .Times(1) 184782affd94SBrandon Wyman .WillOnce(Return("209400")); 184839ea02bcSBrandon Wyman psu.analyze(); 1849c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1850c2906f47SBrandon Wyman } 1851c2906f47SBrandon Wyman 185239ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 185339ea02bcSBrandon Wyman expectations.statusWordValue = 0; 185439ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 185582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 185682affd94SBrandon Wyman .Times(1) 185782affd94SBrandon Wyman .WillOnce(Return("209500")); 185839ea02bcSBrandon Wyman psu.analyze(); 185939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 186039ea02bcSBrandon Wyman } 186139ea02bcSBrandon Wyman 186239ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSCS12VFault) 186339ea02bcSBrandon Wyman { 186439ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 18659464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f, 18669464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 186739ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 186839ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 186939ea02bcSBrandon Wyman // Always return 1 to indicate present. 187039ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 187139ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 187282affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1873ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1874ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1875ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1876ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1877592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 187839ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 187939ea02bcSBrandon Wyman PMBusExpectations expectations; 188039ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 188182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 188282affd94SBrandon Wyman .Times(1) 188382affd94SBrandon Wyman .WillOnce(Return("209100")); 188439ea02bcSBrandon Wyman psu.analyze(); 188539ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 188639ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 188739ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 188839ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 188939ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1890c2906f47SBrandon Wyman 1891c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1892c2906f47SBrandon Wyman { 189339ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 189482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 189582affd94SBrandon Wyman .Times(1) 189682affd94SBrandon Wyman .WillOnce(Return("209200")); 189739ea02bcSBrandon Wyman psu.analyze(); 1898c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1899c2906f47SBrandon Wyman } 1900c2906f47SBrandon Wyman 190139ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 190239ea02bcSBrandon Wyman expectations.statusWordValue = 0; 190339ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 190482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 190582affd94SBrandon Wyman .Times(1) 190682affd94SBrandon Wyman .WillOnce(Return("209300")); 190739ea02bcSBrandon Wyman psu.analyze(); 190839ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 190939ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 191039ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 191139ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 7 on. 191239ea02bcSBrandon Wyman expectations.statusMFRValue = 0x80; 1913c2906f47SBrandon Wyman 1914c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1915c2906f47SBrandon Wyman { 191639ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 191782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 191882affd94SBrandon Wyman .Times(1) 191982affd94SBrandon Wyman .WillOnce(Return("209400")); 192039ea02bcSBrandon Wyman psu.analyze(); 1921c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1922c2906f47SBrandon Wyman } 1923c2906f47SBrandon Wyman 192439ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 192539ea02bcSBrandon Wyman expectations.statusWordValue = 0; 192639ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 192782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 192882affd94SBrandon Wyman .Times(1) 192982affd94SBrandon Wyman .WillOnce(Return("209500")); 193039ea02bcSBrandon Wyman psu.analyze(); 193139ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 193239ea02bcSBrandon Wyman } 1933c3324424SBrandon Wyman 1934592bd27cSMatt Spinler TEST_F(PowerSupplyTests, PeakInputPowerSensor) 1935c3324424SBrandon Wyman { 1936c3324424SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1937c3324424SBrandon Wyman { 19389464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f, 19399464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 1940592bd27cSMatt Spinler EXPECT_EQ(psu.getPeakInputPower(), std::nullopt); 1941592bd27cSMatt Spinler 1942c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1943c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1944ae35ac5dSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1945c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1946592bd27cSMatt Spinler 1947ae35ac5dSBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1948ae35ac5dSBrandon Wyman PMBusExpectations expectations; 1949ae35ac5dSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 1950592bd27cSMatt Spinler 1951ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 1952ae35ac5dSBrandon Wyman .Times(1) 1953ae35ac5dSBrandon Wyman .WillOnce(Return("206000")); 1954ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1955ae35ac5dSBrandon Wyman .WillRepeatedly(Return("2000")); 1956592bd27cSMatt Spinler 1957c3324424SBrandon Wyman psu.analyze(); 1958592bd27cSMatt Spinler EXPECT_EQ(psu.getPeakInputPower().value_or(0), 213); 1959c3324424SBrandon Wyman } 1960592bd27cSMatt Spinler 1961592bd27cSMatt Spinler // Test that there is no peak power sensor on 1400W PSs 1962c3324424SBrandon Wyman { 19639464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, 19649464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 1965ae35ac5dSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1966ae35ac5dSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1967ae35ac5dSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1968592bd27cSMatt Spinler 1969ae35ac5dSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1970592bd27cSMatt Spinler 1971ae35ac5dSBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1972592bd27cSMatt Spinler 1973ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1974ae35ac5dSBrandon Wyman .WillRepeatedly(Return("30725")); 1975592bd27cSMatt Spinler 1976ae35ac5dSBrandon Wyman PMBusExpectations expectations; 1977ae35ac5dSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 1978592bd27cSMatt Spinler 1979ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 1980592bd27cSMatt Spinler .WillRepeatedly(Return("206000")); 1981ae35ac5dSBrandon Wyman psu.analyze(); 1982592bd27cSMatt Spinler 1983592bd27cSMatt Spinler EXPECT_EQ(psu.getPeakInputPower(), std::nullopt); 1984ae35ac5dSBrandon Wyman } 1985592bd27cSMatt Spinler 1986592bd27cSMatt Spinler // Test that IPSPS power supplies don't have peak power 1987ae35ac5dSBrandon Wyman { 1988c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 11, 19899464c429SGeorge Liu 0x58, "inspur-ipsps", PSUGPIOLineName, 19909464c429SGeorge Liu isPowerOn}; 1991592bd27cSMatt Spinler 1992c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1993c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1994592bd27cSMatt Spinler 1995ae35ac5dSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1996592bd27cSMatt Spinler 1997c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1998592bd27cSMatt Spinler 1999ae35ac5dSBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2000ae35ac5dSBrandon Wyman PMBusExpectations expectations; 2001ae35ac5dSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2002592bd27cSMatt Spinler 2003592bd27cSMatt Spinler EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2004592bd27cSMatt Spinler .WillRepeatedly(Return("206000")); 2005592bd27cSMatt Spinler 2006592bd27cSMatt Spinler psu.analyze(); 2007592bd27cSMatt Spinler 2008592bd27cSMatt Spinler EXPECT_EQ(psu.getPeakInputPower(), std::nullopt); 2009592bd27cSMatt Spinler } 2010592bd27cSMatt Spinler 2011592bd27cSMatt Spinler // Test that a bad response from the input_history command leads 2012592bd27cSMatt Spinler // to an NaN value. 2013592bd27cSMatt Spinler { 2014592bd27cSMatt Spinler PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f, 2015592bd27cSMatt Spinler "ibm-cffps", PSUGPIOLineName, isPowerOn}; 2016592bd27cSMatt Spinler 2017592bd27cSMatt Spinler MockedGPIOInterface* mockPresenceGPIO = 2018592bd27cSMatt Spinler static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 2019592bd27cSMatt Spinler MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2020592bd27cSMatt Spinler 2021592bd27cSMatt Spinler EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 2022592bd27cSMatt Spinler 2023592bd27cSMatt Spinler setMissingToPresentExpects(mockPMBus, mockedUtil); 2024592bd27cSMatt Spinler PMBusExpectations expectations; 2025592bd27cSMatt Spinler setPMBusExpectations(mockPMBus, expectations); 2026592bd27cSMatt Spinler 2027ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2028ae35ac5dSBrandon Wyman .Times(1) 2029ae35ac5dSBrandon Wyman .WillOnce(Return("206000")); 2030ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2031592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 2032592bd27cSMatt Spinler 2033592bd27cSMatt Spinler // Don't return the full 5 bytes. 2034592bd27cSMatt Spinler EXPECT_CALL(mockPMBus, 2035592bd27cSMatt Spinler readBinary(INPUT_HISTORY, Type::HwmonDeviceDebug, 5)) 2036592bd27cSMatt Spinler .WillRepeatedly(Return(std::vector<uint8_t>{0x01, 0x5c})); 2037592bd27cSMatt Spinler 2038c3324424SBrandon Wyman psu.analyze(); 2039592bd27cSMatt Spinler EXPECT_THAT(psu.getPeakInputPower().value_or(0), IsNan()); 2040592bd27cSMatt Spinler } 2041c3324424SBrandon Wyman } 204218a24d92SBrandon Wyman 204318a24d92SBrandon Wyman TEST_F(PowerSupplyTests, IsSyncHistoryRequired) 204418a24d92SBrandon Wyman { 204518a24d92SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 20469464c429SGeorge Liu PowerSupply psu{bus, PSUInventoryPath, 8, 0x6f, 20479464c429SGeorge Liu "ibm-cffps", PSUGPIOLineName, isPowerOn}; 204818a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), false); 204918a24d92SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 205018a24d92SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 205118a24d92SBrandon Wyman // Always return 1 to indicate present. 205218a24d92SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 205318a24d92SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 205418a24d92SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2055ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 2056ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 2057ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 2058ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2059592bd27cSMatt Spinler .WillRepeatedly(Return("2000")); 206018a24d92SBrandon Wyman PMBusExpectations expectations; 206118a24d92SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 206218a24d92SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 206318a24d92SBrandon Wyman .Times(1) 206418a24d92SBrandon Wyman .WillRepeatedly(Return("205000")); 206518a24d92SBrandon Wyman EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 206618a24d92SBrandon Wyman psu.analyze(); 206718a24d92SBrandon Wyman // Missing -> Present requires history sync 206818a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), true); 206918a24d92SBrandon Wyman psu.clearSyncHistoryRequired(); 207018a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), false); 207118a24d92SBrandon Wyman } 2072592bd27cSMatt Spinler 2073592bd27cSMatt Spinler TEST_F(PowerSupplyTests, TestLinearConversions) 2074592bd27cSMatt Spinler { 2075592bd27cSMatt Spinler // Mantissa > 0, exponent = 0 2076592bd27cSMatt Spinler EXPECT_EQ(0, PowerSupply::linearToInteger(0)); 2077592bd27cSMatt Spinler EXPECT_EQ(1, PowerSupply::linearToInteger(1)); 2078592bd27cSMatt Spinler EXPECT_EQ(38, PowerSupply::linearToInteger(0x26)); 2079592bd27cSMatt Spinler EXPECT_EQ(1023, PowerSupply::linearToInteger(0x3FF)); 2080592bd27cSMatt Spinler 2081592bd27cSMatt Spinler // Mantissa < 0, exponent = 0 2082592bd27cSMatt Spinler EXPECT_EQ(-1, PowerSupply::linearToInteger(0x7FF)); 2083592bd27cSMatt Spinler EXPECT_EQ(-20, PowerSupply::linearToInteger(0x7EC)); 2084592bd27cSMatt Spinler EXPECT_EQ(-769, PowerSupply::linearToInteger(0x4FF)); 2085592bd27cSMatt Spinler EXPECT_EQ(-989, PowerSupply::linearToInteger(0x423)); 2086592bd27cSMatt Spinler EXPECT_EQ(-1024, PowerSupply::linearToInteger(0x400)); 2087592bd27cSMatt Spinler 2088592bd27cSMatt Spinler // Mantissa >= 0, exponent > 0 2089592bd27cSMatt Spinler // M = 1, E = 2 2090592bd27cSMatt Spinler EXPECT_EQ(4, PowerSupply::linearToInteger(0x1001)); 2091592bd27cSMatt Spinler 2092592bd27cSMatt Spinler // M = 1000, E = 10 2093592bd27cSMatt Spinler EXPECT_EQ(1024000, PowerSupply::linearToInteger(0x53E8)); 2094592bd27cSMatt Spinler 2095592bd27cSMatt Spinler // M = 10, E = 15 2096592bd27cSMatt Spinler EXPECT_EQ(327680, PowerSupply::linearToInteger(0x780A)); 2097592bd27cSMatt Spinler 2098592bd27cSMatt Spinler // Mantissa >= 0, exponent < 0 2099592bd27cSMatt Spinler // M = 0, E = -1 2100592bd27cSMatt Spinler EXPECT_EQ(0, PowerSupply::linearToInteger(0xF800)); 2101592bd27cSMatt Spinler 2102592bd27cSMatt Spinler // M = 100, E = -2 2103592bd27cSMatt Spinler EXPECT_EQ(25, PowerSupply::linearToInteger(0xF064)); 2104592bd27cSMatt Spinler 2105592bd27cSMatt Spinler // Mantissa < 0, exponent < 0 2106592bd27cSMatt Spinler // M = -100, E = -1 2107592bd27cSMatt Spinler EXPECT_EQ(-50, PowerSupply::linearToInteger(0xFF9C)); 2108592bd27cSMatt Spinler 2109592bd27cSMatt Spinler // M = -1024, E = -7 2110592bd27cSMatt Spinler EXPECT_EQ(-8, PowerSupply::linearToInteger(0xCC00)); 2111592bd27cSMatt Spinler } 2112