13f1242f3SBrandon Wyman #include "../power_supply.hpp" 2c3324424SBrandon Wyman #include "../record_manager.hpp" 33f1242f3SBrandon Wyman #include "mock.hpp" 43f1242f3SBrandon Wyman 53f1242f3SBrandon Wyman #include <xyz/openbmc_project/Common/Device/error.hpp> 63f1242f3SBrandon Wyman #include <xyz/openbmc_project/Common/error.hpp> 73f1242f3SBrandon Wyman 83f1242f3SBrandon Wyman #include <gmock/gmock.h> 93f1242f3SBrandon Wyman #include <gtest/gtest.h> 103f1242f3SBrandon Wyman 113f1242f3SBrandon Wyman using namespace phosphor::power::psu; 123f1242f3SBrandon Wyman using namespace phosphor::pmbus; 133f1242f3SBrandon Wyman 143f1242f3SBrandon Wyman using ::testing::_; 1559a35793SBrandon Wyman using ::testing::Args; 163f1242f3SBrandon Wyman using ::testing::Assign; 173f1242f3SBrandon Wyman using ::testing::DoAll; 1859a35793SBrandon Wyman using ::testing::ElementsAre; 1959a35793SBrandon Wyman using ::testing::NotNull; 203f1242f3SBrandon Wyman using ::testing::Return; 213f1242f3SBrandon Wyman using ::testing::StrEq; 223f1242f3SBrandon Wyman 233f1242f3SBrandon Wyman static auto PSUInventoryPath = "/xyz/bmc/inv/sys/chassis/board/powersupply0"; 24681b2a36SB. J. Wyman static auto PSUGPIOLineName = "presence-ps0"; 253f1242f3SBrandon Wyman 26b654c619SBrandon Wyman struct PMBusExpectations 27b654c619SBrandon Wyman { 28b654c619SBrandon Wyman uint16_t statusWordValue{0x0000}; 29b654c619SBrandon Wyman uint8_t statusInputValue{0x00}; 30b654c619SBrandon Wyman uint8_t statusMFRValue{0x00}; 31b654c619SBrandon Wyman uint8_t statusCMLValue{0x00}; 32b654c619SBrandon Wyman uint8_t statusVOUTValue{0x00}; 33b10b3be0SBrandon Wyman uint8_t statusIOUTValue{0x00}; 347ee4d7e4SBrandon Wyman uint8_t statusFans12Value{0x00}; 3596893a46SBrandon Wyman uint8_t statusTempValue{0x00}; 36b654c619SBrandon Wyman }; 37b654c619SBrandon Wyman 388da35c51SBrandon Wyman // Helper function to setup expectations for various STATUS_* commands 39b654c619SBrandon Wyman void setPMBusExpectations(MockedPMBus& mockPMBus, 40b654c619SBrandon Wyman const PMBusExpectations& expectations) 418da35c51SBrandon Wyman { 4232453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _, _)) 438da35c51SBrandon Wyman .Times(1) 44b654c619SBrandon Wyman .WillOnce(Return(expectations.statusWordValue)); 458da35c51SBrandon Wyman 46b654c619SBrandon Wyman if (expectations.statusWordValue != 0) 478da35c51SBrandon Wyman { 488da35c51SBrandon Wyman // If fault bits are on in STATUS_WORD, there will also be a read of 4996893a46SBrandon Wyman // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT (page 0), and 5096893a46SBrandon Wyman // STATUS_TEMPERATURE. 5132453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _, _)) 528da35c51SBrandon Wyman .Times(1) 53b654c619SBrandon Wyman .WillOnce(Return(expectations.statusInputValue)); 5432453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _, _)) 558da35c51SBrandon Wyman .Times(1) 56b654c619SBrandon Wyman .WillOnce(Return(expectations.statusMFRValue)); 5732453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _, _)) 588da35c51SBrandon Wyman .Times(1) 59b654c619SBrandon Wyman .WillOnce(Return(expectations.statusCMLValue)); 606710ba2cSBrandon Wyman // Page will need to be set to 0 to read STATUS_VOUT. 616710ba2cSBrandon Wyman EXPECT_CALL(mockPMBus, insertPageNum(STATUS_VOUT, 0)) 626710ba2cSBrandon Wyman .Times(1) 636710ba2cSBrandon Wyman .WillOnce(Return("status0_vout")); 6432453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read("status0_vout", _, _)) 656710ba2cSBrandon Wyman .Times(1) 66b654c619SBrandon Wyman .WillOnce(Return(expectations.statusVOUTValue)); 6732453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_IOUT, _, _)) 68b10b3be0SBrandon Wyman .Times(1) 69b10b3be0SBrandon Wyman .WillOnce(Return(expectations.statusIOUTValue)); 7032453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_FANS_1_2, _, _)) 717ee4d7e4SBrandon Wyman .Times(1) 727ee4d7e4SBrandon Wyman .WillOnce(Return(expectations.statusFans12Value)); 7332453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_TEMPERATURE, _, _)) 7496893a46SBrandon Wyman .Times(1) 7596893a46SBrandon Wyman .WillOnce(Return(expectations.statusTempValue)); 768da35c51SBrandon Wyman } 778da35c51SBrandon Wyman } 788da35c51SBrandon Wyman 793f1242f3SBrandon Wyman class PowerSupplyTests : public ::testing::Test 803f1242f3SBrandon Wyman { 813f1242f3SBrandon Wyman public: 823f1242f3SBrandon Wyman PowerSupplyTests() : 833f1242f3SBrandon Wyman mockedUtil(reinterpret_cast<const MockedUtil&>(getUtils())) 843f1242f3SBrandon Wyman { 853f1242f3SBrandon Wyman ON_CALL(mockedUtil, getPresence(_, _)).WillByDefault(Return(false)); 863f1242f3SBrandon Wyman } 873f1242f3SBrandon Wyman 883f1242f3SBrandon Wyman ~PowerSupplyTests() override 893f1242f3SBrandon Wyman { 903f1242f3SBrandon Wyman freeUtils(); 913f1242f3SBrandon Wyman } 923f1242f3SBrandon Wyman 933f1242f3SBrandon Wyman const MockedUtil& mockedUtil; 943f1242f3SBrandon Wyman }; 953f1242f3SBrandon Wyman 96391a0690SBrandon Wyman // Helper function for when a power supply goes from missing to present. 97391a0690SBrandon Wyman void setMissingToPresentExpects(MockedPMBus& pmbus, const MockedUtil& util) 98391a0690SBrandon Wyman { 99391a0690SBrandon Wyman // Call to analyze() will update to present, that will trigger updating 100391a0690SBrandon Wyman // to the correct/latest HWMON directory, in case it changes. 101391a0690SBrandon Wyman EXPECT_CALL(pmbus, findHwmonDir()); 102391a0690SBrandon Wyman // Presence change from missing to present will trigger write to 103391a0690SBrandon Wyman // ON_OFF_CONFIG. 104391a0690SBrandon Wyman EXPECT_CALL(pmbus, writeBinary(ON_OFF_CONFIG, _, _)); 105391a0690SBrandon Wyman // Presence change from missing to present will trigger in1_input read 106391a0690SBrandon Wyman // in an attempt to get CLEAR_FAULTS called. 10782affd94SBrandon Wyman // This READ_VIN for CLEAR_FAULTS does not check the returned value. 1083225a45cSBrandon Wyman EXPECT_CALL(pmbus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 1093225a45cSBrandon Wyman // The call for clearing faults includes clearing VIN_UV fault. 1103225a45cSBrandon Wyman // The voltage defaults to 0, the first call to analyze should update the 1113225a45cSBrandon Wyman // voltage to the current reading, triggering clearing VIN_UV fault(s) 1123225a45cSBrandon Wyman // due to below minimum to within range voltage. 1133225a45cSBrandon Wyman EXPECT_CALL(pmbus, read("in1_lcrit_alarm", _, _)) 11482affd94SBrandon Wyman .Times(2) 1153225a45cSBrandon Wyman .WillRepeatedly(Return(1)); 116391a0690SBrandon Wyman // Missing/present call will update Presence in inventory. 117391a0690SBrandon Wyman EXPECT_CALL(util, setPresence(_, _, true, _)); 118391a0690SBrandon Wyman } 119391a0690SBrandon Wyman 1203f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Constructor) 1213f1242f3SBrandon Wyman { 1223f1242f3SBrandon Wyman /** 1233f1242f3SBrandon Wyman * @param[in] invpath - String for inventory path to use 1243f1242f3SBrandon Wyman * @param[in] i2cbus - The bus number this power supply is on 1253f1242f3SBrandon Wyman * @param[in] i2caddr - The 16-bit I2C address of the power supply 126681b2a36SB. J. Wyman * @param[in] gpioLineName - The string for the gpio-line-name to read for 127681b2a36SB. J. Wyman * presence. 128681b2a36SB. J. Wyman * @param[in] bindDelay - Time in milliseconds to delay binding the device 129681b2a36SB. J. Wyman * driver after seeing the presence line go active. 1303f1242f3SBrandon Wyman */ 1313f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1321d7a7df8SBrandon Wyman 1331d7a7df8SBrandon Wyman // Try where inventory path is empty, constructor should fail. 1341d7a7df8SBrandon Wyman try 1351d7a7df8SBrandon Wyman { 136c3324424SBrandon Wyman auto psu = std::make_unique<PowerSupply>(bus, "", 3, 0x68, "ibm-cffps", 137c3324424SBrandon Wyman PSUGPIOLineName); 1381d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have reached this line."; 1391d7a7df8SBrandon Wyman } 1401d7a7df8SBrandon Wyman catch (const std::invalid_argument& e) 1411d7a7df8SBrandon Wyman { 1421d7a7df8SBrandon Wyman EXPECT_STREQ(e.what(), "Invalid empty inventoryPath"); 1431d7a7df8SBrandon Wyman } 1441d7a7df8SBrandon Wyman catch (...) 1451d7a7df8SBrandon Wyman { 1461d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 1471d7a7df8SBrandon Wyman } 1481d7a7df8SBrandon Wyman 149681b2a36SB. J. Wyman // TODO: Try invalid i2c address? 150681b2a36SB. J. Wyman 151681b2a36SB. J. Wyman // Try where gpioLineName is empty. 1521d7a7df8SBrandon Wyman try 1531d7a7df8SBrandon Wyman { 154c3324424SBrandon Wyman auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, 155c3324424SBrandon Wyman "ibm-cffps", ""); 156681b2a36SB. J. Wyman ADD_FAILURE() 157681b2a36SB. J. Wyman << "Should not have reached this line. Invalid gpioLineName."; 158681b2a36SB. J. Wyman } 159681b2a36SB. J. Wyman catch (const std::invalid_argument& e) 160681b2a36SB. J. Wyman { 161681b2a36SB. J. Wyman EXPECT_STREQ(e.what(), "Invalid empty gpioLineName"); 162681b2a36SB. J. Wyman } 163681b2a36SB. J. Wyman catch (...) 164681b2a36SB. J. Wyman { 165681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 166681b2a36SB. J. Wyman } 167681b2a36SB. J. Wyman 168681b2a36SB. J. Wyman // Test with valid arguments 169681b2a36SB. J. Wyman // NOT using D-Bus inventory path for presence. 170681b2a36SB. J. Wyman try 171681b2a36SB. J. Wyman { 172681b2a36SB. J. Wyman auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, 173c3324424SBrandon Wyman "ibm-cffps", PSUGPIOLineName); 1743f1242f3SBrandon Wyman 1753f1242f3SBrandon Wyman EXPECT_EQ(psu->isPresent(), false); 1763f1242f3SBrandon Wyman EXPECT_EQ(psu->isFaulted(), false); 1778da35c51SBrandon Wyman EXPECT_EQ(psu->hasCommFault(), false); 1783f1242f3SBrandon Wyman EXPECT_EQ(psu->hasInputFault(), false); 1793f1242f3SBrandon Wyman EXPECT_EQ(psu->hasMFRFault(), false); 1803f1242f3SBrandon Wyman EXPECT_EQ(psu->hasVINUVFault(), false); 1816710ba2cSBrandon Wyman EXPECT_EQ(psu->hasVoutOVFault(), false); 182b10b3be0SBrandon Wyman EXPECT_EQ(psu->hasIoutOCFault(), false); 1832cf46945SBrandon Wyman EXPECT_EQ(psu->hasVoutUVFault(), false); 1847ee4d7e4SBrandon Wyman EXPECT_EQ(psu->hasFanFault(), false); 18596893a46SBrandon Wyman EXPECT_EQ(psu->hasTempFault(), false); 1862916ea52SBrandon Wyman EXPECT_EQ(psu->hasPgoodFault(), false); 18739ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPSKillFault(), false); 18839ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPS12VcsFault(), false); 18939ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPSCS12VFault(), false); 1903f1242f3SBrandon Wyman } 1911d7a7df8SBrandon Wyman catch (...) 1921d7a7df8SBrandon Wyman { 1931d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 1941d7a7df8SBrandon Wyman } 195681b2a36SB. J. Wyman 196681b2a36SB. J. Wyman // Test with valid arguments 197681b2a36SB. J. Wyman // TODO: Using D-Bus inventory path for presence. 198681b2a36SB. J. Wyman try 199681b2a36SB. J. Wyman { 200681b2a36SB. J. Wyman // FIXME: How do I get that presenceGPIO.read() in the startup to throw 201681b2a36SB. J. Wyman // an exception? 202681b2a36SB. J. Wyman 203681b2a36SB. J. Wyman // EXPECT_CALL(mockedUtil, getPresence(_, 204681b2a36SB. J. Wyman // StrEq(PSUInventoryPath))) 205681b2a36SB. J. Wyman // .Times(1); 206681b2a36SB. J. Wyman } 207681b2a36SB. J. Wyman catch (...) 208681b2a36SB. J. Wyman { 209681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 210681b2a36SB. J. Wyman } 2111d7a7df8SBrandon Wyman } 2123f1242f3SBrandon Wyman 2133f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Analyze) 2143f1242f3SBrandon Wyman { 2153f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2163f1242f3SBrandon Wyman 217b654c619SBrandon Wyman { 218681b2a36SB. J. Wyman // If I default to reading the GPIO, I will NOT expect a call to 219681b2a36SB. J. Wyman // getPresence(). 220681b2a36SB. J. Wyman 221c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 222c3324424SBrandon Wyman 0x69, "ibm-cffps", PSUGPIOLineName}; 2233ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 2243ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 225681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0)); 226681b2a36SB. J. Wyman 2273f1242f3SBrandon Wyman psu.analyze(); 2283f1242f3SBrandon Wyman // By default, nothing should change. 2293f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 2303f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 2313f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 2323f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 2333f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 23485c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 2356710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 236b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 2372cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 2387ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 23996893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 2402916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 24139ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 24239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 24339ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 244b654c619SBrandon Wyman } 2453f1242f3SBrandon Wyman 246c3324424SBrandon Wyman PowerSupply psu2{bus, PSUInventoryPath, 5, 247c3324424SBrandon Wyman 0x6a, "ibm-cffps", PSUGPIOLineName}; 248681b2a36SB. J. Wyman // In order to get the various faults tested, the power supply needs to 249681b2a36SB. J. Wyman // be present in order to read from the PMBus device(s). 2503ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO2 = 2513ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO()); 25206ca4590SBrandon Wyman // Always return 1 to indicate present. 25306ca4590SBrandon Wyman // Each analyze() call will trigger a read of the presence GPIO. 25406ca4590SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO2, read()).WillRepeatedly(Return(1)); 255681b2a36SB. J. Wyman EXPECT_EQ(psu2.isPresent(), false); 2563f1242f3SBrandon Wyman 2573f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus()); 258391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 259*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 260*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 261*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 262*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 263*ae35ac5dSBrandon Wyman .Times(1) 264*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 265b654c619SBrandon Wyman 266b654c619SBrandon Wyman // STATUS_WORD INPUT fault. 267b654c619SBrandon Wyman { 268b654c619SBrandon Wyman // Start with STATUS_WORD 0x0000. Powered on, no faults. 269b654c619SBrandon Wyman // Set expectations for a no fault 270b654c619SBrandon Wyman PMBusExpectations expectations; 271b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 27282affd94SBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 27382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 27482affd94SBrandon Wyman .Times(1) 27582affd94SBrandon Wyman .WillOnce(Return("206000")); 2763f1242f3SBrandon Wyman psu2.analyze(); 2773f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2783f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 2793f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 2803f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 2813f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 28285c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 2836710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 284b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 2852cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 2867ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 28796893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 2882916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 28939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 29039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 29139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 2923f1242f3SBrandon Wyman 293b654c619SBrandon Wyman // Update expectations for STATUS_WORD input fault/warn 29496893a46SBrandon Wyman // STATUS_INPUT fault bits ... on. 295b654c619SBrandon Wyman expectations.statusWordValue = (status_word::INPUT_FAULT_WARN); 2963225a45cSBrandon Wyman // IIN_OC fault. 2973225a45cSBrandon Wyman expectations.statusInputValue = 0x04; 298c2906f47SBrandon Wyman 299c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 300c2906f47SBrandon Wyman { 301b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 30282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 30382affd94SBrandon Wyman .Times(1) 30482affd94SBrandon Wyman .WillOnce(Return("207000")); 3053f1242f3SBrandon Wyman psu2.analyze(); 3063f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 307c2906f47SBrandon Wyman // Should not be faulted until it reaches the deglitch limit. 308c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 309c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT); 3103f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 3113f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 31285c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 3136710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 314b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 3152cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 3167ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 31796893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 3182916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 31939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 32039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 32139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 322b654c619SBrandon Wyman } 323c2906f47SBrandon Wyman } 324c2906f47SBrandon Wyman 32532453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 3263225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 3273225a45cSBrandon Wyman .Times(1) 3283225a45cSBrandon Wyman .WillOnce(Return(1)); 329c2906f47SBrandon Wyman psu2.clearFaults(); 3303f1242f3SBrandon Wyman 3313f1242f3SBrandon Wyman // STATUS_WORD INPUT/UV fault. 332b654c619SBrandon Wyman { 3333f1242f3SBrandon Wyman // First need it to return good status, then the fault 334b654c619SBrandon Wyman PMBusExpectations expectations; 335b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 33682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 33782affd94SBrandon Wyman .Times(1) 33882affd94SBrandon Wyman .WillOnce(Return("208000")); 3393f1242f3SBrandon Wyman psu2.analyze(); 340c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 341c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 3428da35c51SBrandon Wyman // Now set fault bits in STATUS_WORD 343b654c619SBrandon Wyman expectations.statusWordValue = 3448da35c51SBrandon Wyman (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT); 3458da35c51SBrandon Wyman // STATUS_INPUT fault bits ... on. 3463225a45cSBrandon Wyman expectations.statusInputValue = 0x18; 347c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 348c2906f47SBrandon Wyman { 349b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 35082affd94SBrandon Wyman // Input/UV fault, so voltage should read back low. 35182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 35282affd94SBrandon Wyman .Times(1) 35382affd94SBrandon Wyman .WillOnce(Return("19123")); 3543f1242f3SBrandon Wyman psu2.analyze(); 3553f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 356c2906f47SBrandon Wyman // Only faulted if hit deglitch limit 357c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 358c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT); 359c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), x >= DEGLITCH_LIMIT); 3603f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 36185c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 3626710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 363b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 3642cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 3657ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 36696893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 3672916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 36839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 36939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 37039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 371c2906f47SBrandon Wyman } 37282affd94SBrandon Wyman // Turning VIN_UV fault off causes clearing of faults, causing read of 37382affd94SBrandon Wyman // in1_input as an attempt to get CLEAR_FAULTS called. 37482affd94SBrandon Wyman expectations.statusWordValue = 0; 37582affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 37682affd94SBrandon Wyman // The call to read the voltage 37782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 37882affd94SBrandon Wyman .Times(1) 37982affd94SBrandon Wyman .WillOnce(Return("209000")); 3803225a45cSBrandon Wyman // The call to clear VIN_UV/Off fault(s) 3813225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 38232453e9bSBrandon Wyman .Times(1) 3833225a45cSBrandon Wyman .WillOnce(Return(1)); 38482affd94SBrandon Wyman psu2.analyze(); 38582affd94SBrandon Wyman // Should remain present, no longer be faulted, no input fault, no 38682affd94SBrandon Wyman // VIN_UV fault. Nothing else should change. 38782affd94SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 38882affd94SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 38982affd94SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 39082affd94SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 391b654c619SBrandon Wyman } 3923f1242f3SBrandon Wyman 39332453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 3943225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 3953225a45cSBrandon Wyman .Times(1) 3963225a45cSBrandon Wyman .WillOnce(Return(1)); 397c2906f47SBrandon Wyman psu2.clearFaults(); 398c2906f47SBrandon Wyman 3993f1242f3SBrandon Wyman // STATUS_WORD MFR fault. 400b654c619SBrandon Wyman { 401f07bc797SBrandon Wyman // First need it to return good status, then the fault 402b654c619SBrandon Wyman PMBusExpectations expectations; 403b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 40482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 40582affd94SBrandon Wyman .Times(1) 40682affd94SBrandon Wyman .WillOnce(Return("210000")); 4073f1242f3SBrandon Wyman psu2.analyze(); 4088da35c51SBrandon Wyman // Now STATUS_WORD with MFR fault bit on. 409b654c619SBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 4108da35c51SBrandon Wyman // STATUS_MFR bits on. 411b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 412c2906f47SBrandon Wyman 413c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 414c2906f47SBrandon Wyman { 415b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 41682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 41782affd94SBrandon Wyman .Times(1) 41882affd94SBrandon Wyman .WillOnce(Return("211000")); 4193f1242f3SBrandon Wyman psu2.analyze(); 4203f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 421c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 4223f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 423c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), x >= DEGLITCH_LIMIT); 424c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), x >= DEGLITCH_LIMIT); 425c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 426c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 4273f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 42885c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 4296710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 430b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 4312cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 4327ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 43396893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 4342916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 435c2906f47SBrandon Wyman } 436b654c619SBrandon Wyman } 4373f1242f3SBrandon Wyman 43832453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 4393225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 4403225a45cSBrandon Wyman .Times(1) 4413225a45cSBrandon Wyman .WillOnce(Return(1)); 442c2906f47SBrandon Wyman psu2.clearFaults(); 4433225a45cSBrandon Wyman 44496893a46SBrandon Wyman // Temperature fault. 445b654c619SBrandon Wyman { 446f07bc797SBrandon Wyman // First STATUS_WORD with no bits set, then with temperature fault. 447b654c619SBrandon Wyman PMBusExpectations expectations; 448b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 44982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 45082affd94SBrandon Wyman .Times(1) 45182affd94SBrandon Wyman .WillOnce(Return("212000")); 4523f1242f3SBrandon Wyman psu2.analyze(); 4538da35c51SBrandon Wyman // STATUS_WORD with temperature fault bit on. 454b654c619SBrandon Wyman expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 45596893a46SBrandon Wyman // STATUS_TEMPERATURE with fault bit(s) on. 45696893a46SBrandon Wyman expectations.statusTempValue = 0x10; 457c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 458c2906f47SBrandon Wyman { 459b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 46082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 46182affd94SBrandon Wyman .Times(1) 46282affd94SBrandon Wyman .WillOnce(Return("213000")); 4633f1242f3SBrandon Wyman psu2.analyze(); 4643f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 465c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 4663f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 4673f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 4683f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 46985c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 4706710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 471b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 4722cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 4737ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 474c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), x >= DEGLITCH_LIMIT); 4752916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 47639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 47739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 47839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 479b654c619SBrandon Wyman } 480c2906f47SBrandon Wyman } 48185c7bf41SBrandon Wyman 48232453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 4833225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 4843225a45cSBrandon Wyman .Times(1) 4853225a45cSBrandon Wyman .WillOnce(Return(1)); 486c2906f47SBrandon Wyman psu2.clearFaults(); 4873225a45cSBrandon Wyman 48885c7bf41SBrandon Wyman // CML fault 489b654c619SBrandon Wyman { 49085c7bf41SBrandon Wyman // First STATUS_WORD wit no bits set, then with CML 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("214000")); 49685c7bf41SBrandon Wyman psu2.analyze(); 4978da35c51SBrandon Wyman // STATUS_WORD with CML fault bit on. 498b654c619SBrandon Wyman expectations.statusWordValue = (status_word::CML_FAULT); 49985c7bf41SBrandon Wyman // Turn on STATUS_CML fault bit(s) 500b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 501c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 502c2906f47SBrandon Wyman { 503b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 50482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 50582affd94SBrandon Wyman .Times(1) 50682affd94SBrandon Wyman .WillOnce(Return("215000")); 50785c7bf41SBrandon Wyman psu2.analyze(); 50885c7bf41SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 509c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 510c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), x >= DEGLITCH_LIMIT); 51185c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 51285c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 51385c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 5146710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 515b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 5162cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 5177ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 51896893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 5192916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 52039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 52139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 52239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 523b654c619SBrandon Wyman } 524c2906f47SBrandon Wyman } 5256710ba2cSBrandon Wyman 52632453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 5273225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 5283225a45cSBrandon Wyman .Times(1) 5293225a45cSBrandon Wyman .WillOnce(Return(1)); 530c2906f47SBrandon Wyman psu2.clearFaults(); 5313225a45cSBrandon Wyman 5326710ba2cSBrandon Wyman // VOUT_OV_FAULT fault 533b654c619SBrandon Wyman { 5346710ba2cSBrandon Wyman // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault. 535b654c619SBrandon Wyman PMBusExpectations expectations; 536b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 53782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 53882affd94SBrandon Wyman .Times(1) 53982affd94SBrandon Wyman .WillOnce(Return("216000")); 5406710ba2cSBrandon Wyman psu2.analyze(); 5416710ba2cSBrandon Wyman // STATUS_WORD with VOUT/VOUT_OV fault. 542b654c619SBrandon Wyman expectations.statusWordValue = 5436710ba2cSBrandon Wyman ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT)); 5446710ba2cSBrandon Wyman // Turn on STATUS_VOUT fault bit(s) 545b654c619SBrandon Wyman expectations.statusVOUTValue = 0xA0; 546c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 547c2906f47SBrandon Wyman { 54896893a46SBrandon Wyman // STATUS_TEMPERATURE don't care (default) 549b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 55082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 55182affd94SBrandon Wyman .Times(1) 55282affd94SBrandon Wyman .WillOnce(Return("217000")); 5536710ba2cSBrandon Wyman psu2.analyze(); 5546710ba2cSBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 555c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 5566710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 5576710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 5586710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 5596710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 560c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 5612cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 562b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 5637ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 564b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 565b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 56639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 56739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 56839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 569b10b3be0SBrandon Wyman } 570c2906f47SBrandon Wyman } 571b10b3be0SBrandon Wyman 572b10b3be0SBrandon Wyman // IOUT_OC_FAULT fault 573b10b3be0SBrandon Wyman { 574b10b3be0SBrandon Wyman // First STATUS_WORD with no bits set, then with IOUT_OC fault. 575b10b3be0SBrandon Wyman PMBusExpectations expectations; 576b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 57782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 57882affd94SBrandon Wyman .Times(1) 57982affd94SBrandon Wyman .WillOnce(Return("218000")); 580b10b3be0SBrandon Wyman psu2.analyze(); 581b10b3be0SBrandon Wyman // STATUS_WORD with IOUT_OC fault. 582b10b3be0SBrandon Wyman expectations.statusWordValue = status_word::IOUT_OC_FAULT; 583b10b3be0SBrandon Wyman // Turn on STATUS_IOUT fault bit(s) 584b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0x88; 585c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 586c2906f47SBrandon Wyman { 587b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 58882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 58982affd94SBrandon Wyman .Times(1) 59082affd94SBrandon Wyman .WillOnce(Return("219000")); 591b10b3be0SBrandon Wyman psu2.analyze(); 592b10b3be0SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 593c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 594b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 595b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 596b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 597b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 598b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 599c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 6002cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 6017ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 6022cf46945SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6032cf46945SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 60439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 60539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 60639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 6072cf46945SBrandon Wyman } 608c2906f47SBrandon Wyman } 6092cf46945SBrandon Wyman 6102cf46945SBrandon Wyman // VOUT_UV_FAULT 6112cf46945SBrandon Wyman { 6122cf46945SBrandon Wyman // First STATUS_WORD with no bits set, then with VOUT fault. 6132cf46945SBrandon Wyman PMBusExpectations expectations; 6142cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 61582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 61682affd94SBrandon Wyman .Times(1) 61782affd94SBrandon Wyman .WillOnce(Return("220000")); 6182cf46945SBrandon Wyman psu2.analyze(); 6192cf46945SBrandon Wyman // Change STATUS_WORD to indicate VOUT fault. 6202cf46945SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_FAULT); 6212cf46945SBrandon Wyman // Turn on STATUS_VOUT fault bit(s) 6222cf46945SBrandon Wyman expectations.statusVOUTValue = 0x30; 623c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 624c2906f47SBrandon Wyman { 6252cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 62682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 62782affd94SBrandon Wyman .Times(1) 62882affd94SBrandon Wyman .WillOnce(Return("221000")); 6292cf46945SBrandon Wyman psu2.analyze(); 6302cf46945SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 631c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 6322cf46945SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 6332cf46945SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 6342cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 6352cf46945SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 6362cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 6372cf46945SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 638c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), x >= DEGLITCH_LIMIT); 6397ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 64096893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6412916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 64239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 64339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 64439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 645b654c619SBrandon Wyman } 646c2906f47SBrandon Wyman } 6473f1242f3SBrandon Wyman 6487ee4d7e4SBrandon Wyman // Fan fault 649b654c619SBrandon Wyman { 650b654c619SBrandon Wyman // First STATUS_WORD with no bits set, then with fan fault. 651b654c619SBrandon Wyman PMBusExpectations expectations; 652b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 65382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 65482affd94SBrandon Wyman .Times(1) 65582affd94SBrandon Wyman .WillOnce(Return("222000")); 6563f1242f3SBrandon Wyman psu2.analyze(); 657b654c619SBrandon Wyman expectations.statusWordValue = (status_word::FAN_FAULT); 6587ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with fan 1 warning & fault bits on. 6597ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xA0; 660c2906f47SBrandon Wyman 661c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 662c2906f47SBrandon Wyman { 663b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 66482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 66582affd94SBrandon Wyman .Times(1) 66682affd94SBrandon Wyman .WillOnce(Return("223000")); 6673f1242f3SBrandon Wyman psu2.analyze(); 6683f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 669c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 670c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), x >= DEGLITCH_LIMIT); 6713f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 6723f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 6733f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 67485c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 6756710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 676b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 6772cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 67896893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6792916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 68039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 68139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 68239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 683b654c619SBrandon Wyman } 684c2906f47SBrandon Wyman } 6852916ea52SBrandon Wyman 68606ca4590SBrandon Wyman // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT. 6872cf46945SBrandon Wyman { 6882916ea52SBrandon Wyman // First STATUS_WORD with no bits set. 6892916ea52SBrandon Wyman PMBusExpectations expectations; 6902916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 69182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 69282affd94SBrandon Wyman .Times(1) 69382affd94SBrandon Wyman .WillOnce(Return("123000")); 6942916ea52SBrandon Wyman psu2.analyze(); 6952916ea52SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 6962916ea52SBrandon Wyman // POWER_GOOD# inactive, and OFF bit on. 6972916ea52SBrandon Wyman expectations.statusWordValue = 6982916ea52SBrandon Wyman ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF)); 69906ca4590SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 70006ca4590SBrandon Wyman { 7012916ea52SBrandon Wyman // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and 7022916ea52SBrandon Wyman // STATUS_TEMPERATURE: Don't care if bits set or not (defaults). 7032916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 70482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 70582affd94SBrandon Wyman .Times(1) 70682affd94SBrandon Wyman .WillOnce(Return("124000")); 7072916ea52SBrandon Wyman psu2.analyze(); 7082916ea52SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 709c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 7102916ea52SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 7112916ea52SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 7122916ea52SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 7132916ea52SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 7142916ea52SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 7152cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 716b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 7177ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 7182916ea52SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 71932453e9bSBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), x >= DEGLITCH_LIMIT); 72006ca4590SBrandon Wyman } 72106ca4590SBrandon Wyman } 7222916ea52SBrandon Wyman 7233f1242f3SBrandon Wyman // TODO: ReadFailure 7243f1242f3SBrandon Wyman } 7253f1242f3SBrandon Wyman 72659a35793SBrandon Wyman TEST_F(PowerSupplyTests, OnOffConfig) 72759a35793SBrandon Wyman { 72859a35793SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 72959a35793SBrandon Wyman uint8_t data = 0x15; 73059a35793SBrandon Wyman 73159a35793SBrandon Wyman // Test where PSU is NOT present 73259a35793SBrandon Wyman try 73359a35793SBrandon Wyman { 734681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 7350975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, _)).Times(0); 736c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 737c3324424SBrandon Wyman 0x69, "ibm-cffps", PSUGPIOLineName}; 738681b2a36SB. J. Wyman 7393ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7403ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 741681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0)); 74259a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 743681b2a36SB. J. Wyman // Constructor should set initial presence, default read returns 0. 74459a35793SBrandon Wyman // If it is not present, I should not be trying to write to it. 74559a35793SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0); 74659a35793SBrandon Wyman psu.onOffConfig(data); 74759a35793SBrandon Wyman } 74859a35793SBrandon Wyman catch (...) 7490c9a33d6SAdriana Kobylak {} 75059a35793SBrandon Wyman 75159a35793SBrandon Wyman // Test where PSU is present 75259a35793SBrandon Wyman try 75359a35793SBrandon Wyman { 754681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 7550975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 756c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 5, 757c3324424SBrandon Wyman 0x6a, "ibm-cffps", PSUGPIOLineName}; 7583ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7593ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 760391a0690SBrandon Wyman // There will potentially be multiple calls, we want it to continue 761391a0690SBrandon Wyman // returning 1 for the GPIO read to keep the power supply present. 762391a0690SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 76359a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 764391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 765*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 766*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 767*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 768*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 769*ae35ac5dSBrandon Wyman .Times(1) 770*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 771391a0690SBrandon Wyman // If I am calling analyze(), I should probably give it good data. 772391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 773391a0690SBrandon Wyman PMBusExpectations expectations; 774391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 77582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 77682affd94SBrandon Wyman .Times(1) 77782affd94SBrandon Wyman .WillOnce(Return("205000")); 778681b2a36SB. J. Wyman psu.analyze(); 779391a0690SBrandon Wyman // I definitely should be writting ON_OFF_CONFIG if I call the function 780391a0690SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, ElementsAre(0x15), 781391a0690SBrandon Wyman Type::HwmonDeviceDebug)) 78259a35793SBrandon Wyman .Times(1); 78359a35793SBrandon Wyman psu.onOffConfig(data); 78459a35793SBrandon Wyman } 78559a35793SBrandon Wyman catch (...) 7860c9a33d6SAdriana Kobylak {} 78759a35793SBrandon Wyman } 78859a35793SBrandon Wyman 7893f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, ClearFaults) 7903f1242f3SBrandon Wyman { 7913f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 792c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 13, 793c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 7943ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7953ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 79606ca4590SBrandon Wyman // Always return 1 to indicate present. 79706ca4590SBrandon Wyman // Each analyze() call will trigger a read of the presence GPIO. 79806ca4590SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 799681b2a36SB. J. Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 800391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 801*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 802*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 803*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 804*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 805*ae35ac5dSBrandon Wyman .Times(1) 806*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 8078da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 808b654c619SBrandon Wyman PMBusExpectations expectations; 809b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 81082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 81182affd94SBrandon Wyman .Times(1) 81282affd94SBrandon Wyman .WillOnce(Return("207000")); 813681b2a36SB. J. Wyman psu.analyze(); 8143f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8153f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 8163f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 8173f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 8183f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 81985c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 8206710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 821b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 8222cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 8237ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 82496893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 8252916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 82639ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 82739ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 82839ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 829b654c619SBrandon Wyman 830f07bc797SBrandon Wyman // STATUS_WORD with fault bits galore! 831b654c619SBrandon Wyman expectations.statusWordValue = 0xFFFF; 832f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 833b654c619SBrandon Wyman expectations.statusInputValue = 0xFF; 834f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 835b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 83685c7bf41SBrandon Wyman // STATUS_CML with bits on. 837b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 8386710ba2cSBrandon Wyman // STATUS_VOUT with bits on. 839b654c619SBrandon Wyman expectations.statusVOUTValue = 0xFF; 840b10b3be0SBrandon Wyman // STATUS_IOUT with bits on. 841b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0xFF; 8427ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with bits on. 8437ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xFF; 84496893a46SBrandon Wyman // STATUS_TEMPERATURE with bits on. 84596893a46SBrandon Wyman expectations.statusTempValue = 0xFF; 846c2906f47SBrandon Wyman 847c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 848c2906f47SBrandon Wyman { 849b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 85082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 85182affd94SBrandon Wyman .Times(1) 85282affd94SBrandon Wyman .WillOnce(Return("0")); 8530975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 8540975eaf4SMatt Spinler { 8550975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 8560975eaf4SMatt Spinler } 8573f1242f3SBrandon Wyman psu.analyze(); 8583f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8592cf46945SBrandon Wyman // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT. 8602cf46945SBrandon Wyman // Rely on HasVoutUVFault() to verify this sets and clears. 8612cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 862c2906f47SBrandon Wyman // All faults are deglitched up to DEGLITCH_LIMIT 863c2906f47SBrandon Wyman EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT); 864c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 865c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 866c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 867c2906f47SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), x >= DEGLITCH_LIMIT); 868c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 869c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 870c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 871c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 872c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), x >= DEGLITCH_LIMIT); 873c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 874c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 875c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 876c2906f47SBrandon Wyman } 877c2906f47SBrandon Wyman 87832453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)) 87932453e9bSBrandon Wyman .Times(1) 88032453e9bSBrandon Wyman .WillOnce(Return(207000)); 8813225a45cSBrandon Wyman // Clearing VIN_UV fault via in1_lcrit_alarm 8823225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 8833225a45cSBrandon Wyman .Times(1) 8843225a45cSBrandon Wyman .WillOnce(Return(1)); 8850975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 8863f1242f3SBrandon Wyman psu.clearFaults(); 8873f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8883f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 8893f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 8903f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 8913f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 89285c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 8936710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 894b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 8952cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 8967ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 89796893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 8982916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 89939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 90039ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 90139ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 902681b2a36SB. J. Wyman 90382affd94SBrandon Wyman // Faults clear on READ_VIN 0 -> !0 90482affd94SBrandon Wyman // STATUS_WORD with fault bits galore! 90582affd94SBrandon Wyman expectations.statusWordValue = 0xFFFF; 90682affd94SBrandon Wyman // STATUS_INPUT with fault bits on. 90782affd94SBrandon Wyman expectations.statusInputValue = 0xFF; 90882affd94SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 90982affd94SBrandon Wyman expectations.statusMFRValue = 0xFF; 91082affd94SBrandon Wyman // STATUS_CML with bits on. 91182affd94SBrandon Wyman expectations.statusCMLValue = 0xFF; 91282affd94SBrandon Wyman // STATUS_VOUT with bits on. 91382affd94SBrandon Wyman expectations.statusVOUTValue = 0xFF; 91482affd94SBrandon Wyman // STATUS_IOUT with bits on. 91582affd94SBrandon Wyman expectations.statusIOUTValue = 0xFF; 91682affd94SBrandon Wyman // STATUS_FANS_1_2 with bits on. 91782affd94SBrandon Wyman expectations.statusFans12Value = 0xFF; 91882affd94SBrandon Wyman // STATUS_TEMPERATURE with bits on. 91982affd94SBrandon Wyman expectations.statusTempValue = 0xFF; 920c2906f47SBrandon Wyman 921c2906f47SBrandon Wyman // All faults degltiched now. Check for false before limit above. 922c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 923c2906f47SBrandon Wyman { 92482affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 92582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 92682affd94SBrandon Wyman .Times(1) 92782affd94SBrandon Wyman .WillOnce(Return("0")); 9280975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 9290975eaf4SMatt Spinler { 9300975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 9310975eaf4SMatt Spinler } 93282affd94SBrandon Wyman psu.analyze(); 933c2906f47SBrandon Wyman } 934c2906f47SBrandon Wyman 93582affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 93682affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 93782affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 93882affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 93982affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 94082affd94SBrandon Wyman // True due to CML fault bits on 94182affd94SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), true); 94282affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 94382affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), true); 94482affd94SBrandon Wyman // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT. 94582affd94SBrandon Wyman // Rely on HasVoutUVFault() to verify this sets and clears. 94682affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 94782affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), true); 94882affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), true); 949c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 95082affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), true); 95182affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), true); 95282affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), true); 95382affd94SBrandon Wyman // STATUS_WORD with INPUT/VIN_UV fault bits off. 95482affd94SBrandon Wyman expectations.statusWordValue = 0xDFF7; 95582affd94SBrandon Wyman // STATUS_INPUT with VIN_UV_WARNING, VIN_UV_FAULT, and Unit Off For 95682affd94SBrandon Wyman // Insufficient Input Voltage bits off. 95782affd94SBrandon Wyman expectations.statusInputValue = 0xC7; 95882affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 95982affd94SBrandon Wyman // READ_VIN back in range. 96082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 96182affd94SBrandon Wyman .Times(1) 96282affd94SBrandon Wyman .WillOnce(Return("206000")); 9633225a45cSBrandon Wyman // VIN_UV cleared via in1_lcrit_alarm when voltage back in range. 9643225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 9653225a45cSBrandon Wyman .Times(1) 9663225a45cSBrandon Wyman .WillOnce(Return(1)); 9673225a45cSBrandon Wyman psu.analyze(); 9683225a45cSBrandon Wyman // We only cleared the VIN_UV and OFF faults. 9693225a45cSBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 9703225a45cSBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 9713225a45cSBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 9723225a45cSBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 9733225a45cSBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 9743225a45cSBrandon Wyman EXPECT_EQ(psu.hasCommFault(), true); 9753225a45cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 9763225a45cSBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), true); 9773225a45cSBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 9783225a45cSBrandon Wyman EXPECT_EQ(psu.hasFanFault(), true); 9793225a45cSBrandon Wyman EXPECT_EQ(psu.hasTempFault(), true); 9803225a45cSBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 9813225a45cSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), true); 9823225a45cSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), true); 9833225a45cSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), true); 9843225a45cSBrandon Wyman 9853225a45cSBrandon Wyman // All faults cleared 9863225a45cSBrandon Wyman expectations = {0}; 9873225a45cSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 9883225a45cSBrandon Wyman // READ_VIN back in range. 9893225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 9903225a45cSBrandon Wyman .Times(1) 9913225a45cSBrandon Wyman .WillOnce(Return("206000")); 9920975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 99382affd94SBrandon Wyman psu.analyze(); 99482affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 99582affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 99682affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 99782affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 99882affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 99982affd94SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 100082affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 100182affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 100282affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 100382affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 100482affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 100582affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 100682affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 100782affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 100882affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 100982affd94SBrandon Wyman 1010681b2a36SB. J. Wyman // TODO: Faults clear on missing/present? 10113f1242f3SBrandon Wyman } 10123f1242f3SBrandon Wyman 10133f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory) 10143f1242f3SBrandon Wyman { 10153f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 10161d7a7df8SBrandon Wyman 10171d7a7df8SBrandon Wyman try 10181d7a7df8SBrandon Wyman { 1019c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1020c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 10211d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 10221d7a7df8SBrandon Wyman // If it is not present, I should not be trying to read a string 10231d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).Times(0); 10241d7a7df8SBrandon Wyman psu.updateInventory(); 10251d7a7df8SBrandon Wyman } 10261d7a7df8SBrandon Wyman catch (...) 10271d7a7df8SBrandon Wyman { 10281d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 10291d7a7df8SBrandon Wyman } 10301d7a7df8SBrandon Wyman 10311d7a7df8SBrandon Wyman try 10321d7a7df8SBrandon Wyman { 1033c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 13, 1034c3324424SBrandon Wyman 0x69, "ibm-cffps", PSUGPIOLineName}; 10353ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10363ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1037681b2a36SB. J. Wyman // GPIO read return 1 to indicate present. 1038681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 10391d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1040391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1041*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1042*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1043*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1044*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1045*ae35ac5dSBrandon Wyman .Times(1) 1046*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1047391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1048391a0690SBrandon Wyman PMBusExpectations expectations; 1049391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 105082affd94SBrandon Wyman // Call to analyze will read voltage, trigger clear faults for 0 to 105182affd94SBrandon Wyman // within range. 105282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 105382affd94SBrandon Wyman .Times(1) 105482affd94SBrandon Wyman .WillOnce(Return("123456")); 1055391a0690SBrandon Wyman psu.analyze(); 10561d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return("")); 10573f1242f3SBrandon Wyman psu.updateInventory(); 10581d7a7df8SBrandon Wyman 10593c530fbdSBrandon Wyman #if IBM_VPD 10601d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)) 10611d7a7df8SBrandon Wyman .WillOnce(Return("CCIN")) 10621d7a7df8SBrandon Wyman .WillOnce(Return("PN3456")) 10631d7a7df8SBrandon Wyman .WillOnce(Return("FN3456")) 10641d7a7df8SBrandon Wyman .WillOnce(Return("HEADER")) 10651d7a7df8SBrandon Wyman .WillOnce(Return("SN3456")) 10661d7a7df8SBrandon Wyman .WillOnce(Return("FW3456")); 10673c530fbdSBrandon Wyman #endif 10681d7a7df8SBrandon Wyman psu.updateInventory(); 10691d7a7df8SBrandon Wyman // TODO: D-Bus mocking to verify values stored on D-Bus (???) 10701d7a7df8SBrandon Wyman } 10711d7a7df8SBrandon Wyman catch (...) 10721d7a7df8SBrandon Wyman { 10731d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 10741d7a7df8SBrandon Wyman } 10753f1242f3SBrandon Wyman } 10763f1242f3SBrandon Wyman 10773f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent) 10783f1242f3SBrandon Wyman { 10793f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1080681b2a36SB. J. Wyman 1081c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1082c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 10833ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10843ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 10853f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 10863f1242f3SBrandon Wyman 1087681b2a36SB. J. Wyman // Change GPIO read to return 1 to indicate present. 1088681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 1089391a0690SBrandon Wyman // Call to analyze() will update to present, that will trigger updating 1090391a0690SBrandon Wyman // to the correct/latest HWMON directory, in case it changes. 1091391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1092391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1093*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1094*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1095*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1096*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1097*ae35ac5dSBrandon Wyman .Times(1) 1098*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1099391a0690SBrandon Wyman // Call to analyze things will trigger read of STATUS_WORD and READ_VIN. 1100391a0690SBrandon Wyman // Default expectations will be on, no faults. 1101391a0690SBrandon Wyman PMBusExpectations expectations; 1102391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 110382affd94SBrandon Wyman // Give it an input voltage in the 100-volt range. 110482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 110582affd94SBrandon Wyman .Times(1) 110682affd94SBrandon Wyman .WillOnce(Return("123456")); 11070975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1108681b2a36SB. J. Wyman psu.analyze(); 1109681b2a36SB. J. Wyman EXPECT_EQ(psu.isPresent(), true); 11103f1242f3SBrandon Wyman } 11113f1242f3SBrandon Wyman 11123f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted) 11133f1242f3SBrandon Wyman { 11143f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1115681b2a36SB. J. Wyman 1116c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 11, 1117c3324424SBrandon Wyman 0x6f, "ibm-cffps", PSUGPIOLineName}; 11183ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 11193ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1120681b2a36SB. J. Wyman // Always return 1 to indicate present. 1121681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1122391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1123391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1124*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1125*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1126*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1127*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1128*ae35ac5dSBrandon Wyman .Times(1) 1129*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1130391a0690SBrandon Wyman // Call to analyze things will trigger read of STATUS_WORD and READ_VIN. 1131391a0690SBrandon Wyman // Default expectations will be on, no faults. 1132391a0690SBrandon Wyman PMBusExpectations expectations; 1133391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 113482affd94SBrandon Wyman // Give it an input voltage in the 100-volt range. 113582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 113682affd94SBrandon Wyman .Times(1) 113782affd94SBrandon Wyman .WillOnce(Return("124680")); 1138681b2a36SB. J. Wyman psu.analyze(); 11393f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 1140f07bc797SBrandon Wyman // STATUS_WORD with fault bits on. 1141b654c619SBrandon Wyman expectations.statusWordValue = 0xFFFF; 1142f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 1143b654c619SBrandon Wyman expectations.statusInputValue = 0xFF; 1144f07bc797SBrandon Wyman // STATUS_MFR_SPECIFIC with faults bits on. 1145b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 114685c7bf41SBrandon Wyman // STATUS_CML with faults bits on. 1147b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 11486710ba2cSBrandon Wyman // STATUS_VOUT with fault bits on. 1149b654c619SBrandon Wyman expectations.statusVOUTValue = 0xFF; 1150b10b3be0SBrandon Wyman // STATUS_IOUT with fault bits on. 1151b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0xFF; 11527ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with bits on. 11537ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xFF; 115496893a46SBrandon Wyman // STATUS_TEMPERATURE with fault bits on. 115596893a46SBrandon Wyman expectations.statusTempValue = 0xFF; 1156c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1157c2906f47SBrandon Wyman { 1158b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 11594fc191f0SBrandon Wyman // Also get another read of READ_VIN, faulted, so not in 100-volt range 116082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 116182affd94SBrandon Wyman .Times(1) 11624fc191f0SBrandon Wyman .WillOnce(Return("19000")); 11630975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 11640975eaf4SMatt Spinler { 11650975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 11660975eaf4SMatt Spinler } 11673f1242f3SBrandon Wyman psu.analyze(); 1168c2906f47SBrandon Wyman EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT); 1169c2906f47SBrandon Wyman } 11703f1242f3SBrandon Wyman } 11713f1242f3SBrandon Wyman 11723f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasInputFault) 11733f1242f3SBrandon Wyman { 11743f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1175681b2a36SB. J. Wyman 1176c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1177c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 11783ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 11793ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1180681b2a36SB. J. Wyman // Always return 1 to indicate present. 1181681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 11823f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1183391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1184*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1185*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1186*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1187*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1188*ae35ac5dSBrandon Wyman .Times(1) 1189*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 11908da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1191b654c619SBrandon Wyman PMBusExpectations expectations; 1192b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 119382affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 119482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 119582affd94SBrandon Wyman .Times(1) 119682affd94SBrandon Wyman .WillOnce(Return("201100")); 11973f1242f3SBrandon Wyman psu.analyze(); 11983f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 1199f07bc797SBrandon Wyman // STATUS_WORD with input fault/warn on. 1200b654c619SBrandon Wyman expectations.statusWordValue = (status_word::INPUT_FAULT_WARN); 1201f07bc797SBrandon Wyman // STATUS_INPUT with an input fault bit on. 1202b654c619SBrandon Wyman expectations.statusInputValue = 0x80; 1203c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1204c2906f47SBrandon Wyman { 1205b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 120682affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 120782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 120882affd94SBrandon Wyman .Times(1) 120982affd94SBrandon Wyman .WillOnce(Return("201200")); 12100975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 12110975eaf4SMatt Spinler { 12120975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 12130975eaf4SMatt Spinler } 12143f1242f3SBrandon Wyman psu.analyze(); 1215c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 1216c2906f47SBrandon Wyman } 1217f07bc797SBrandon Wyman // STATUS_WORD with no bits on. 1218b654c619SBrandon Wyman expectations.statusWordValue = 0; 1219b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 122082affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 122182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 122282affd94SBrandon Wyman .Times(1) 122382affd94SBrandon Wyman .WillOnce(Return("201300")); 12240975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 12253f1242f3SBrandon Wyman psu.analyze(); 12263f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 12273f1242f3SBrandon Wyman } 12283f1242f3SBrandon Wyman 12293f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault) 12303f1242f3SBrandon Wyman { 12313f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1232681b2a36SB. J. Wyman 1233c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1234c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 12353ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 12363ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1237681b2a36SB. J. Wyman // Always return 1 to indicate present. 1238681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 12393f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1240391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1241*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1242*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1243*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1244*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1245*ae35ac5dSBrandon Wyman .Times(1) 1246*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1247f07bc797SBrandon Wyman // First return STATUS_WORD with no bits on. 12488da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1249b654c619SBrandon Wyman PMBusExpectations expectations; 1250b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 125182affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 125282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 125382affd94SBrandon Wyman .Times(1) 125482affd94SBrandon Wyman .WillOnce(Return("202100")); 12553f1242f3SBrandon Wyman psu.analyze(); 12563f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 1257f07bc797SBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 1258b654c619SBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 1259f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 1260b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 1261c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1262c2906f47SBrandon Wyman { 1263b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 126482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 126582affd94SBrandon Wyman .Times(1) 126682affd94SBrandon Wyman .WillOnce(Return("202200")); 12673f1242f3SBrandon Wyman psu.analyze(); 1268c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 1269c2906f47SBrandon Wyman } 1270f07bc797SBrandon Wyman // Back to no bits on in STATUS_WORD 1271b654c619SBrandon Wyman expectations.statusWordValue = 0; 1272b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 127382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 127482affd94SBrandon Wyman .Times(1) 127582affd94SBrandon Wyman .WillOnce(Return("202300")); 12763f1242f3SBrandon Wyman psu.analyze(); 12773f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 12783f1242f3SBrandon Wyman } 12793f1242f3SBrandon Wyman 12803f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault) 12813f1242f3SBrandon Wyman { 12823f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1283681b2a36SB. J. Wyman 1284c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1285c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 12863ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 12873ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1288681b2a36SB. J. Wyman // Always return 1 to indicate present. 1289681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 12903f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1291391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1292*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1293*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1294*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1295*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1296*ae35ac5dSBrandon Wyman .Times(1) 1297*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 129882affd94SBrandon Wyman 129982affd94SBrandon Wyman // Presence change from missing to present will trigger in1_input read in 130082affd94SBrandon Wyman // an attempt to get CLEAR_FAULTS called. Return value ignored. 130182affd94SBrandon Wyman // Zero to non-zero voltage, for missing/present change, triggers clear 130282affd94SBrandon Wyman // faults call again. Return value ignored. 130382affd94SBrandon Wyman // Fault (low voltage) to not faulted (voltage in range) triggers clear 130482affd94SBrandon Wyman // faults call a third time. 130582affd94SBrandon Wyman 13068da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1307b654c619SBrandon Wyman PMBusExpectations expectations; 1308b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 130982affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 131082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 131182affd94SBrandon Wyman .Times(1) 131282affd94SBrandon Wyman .WillOnce(Return("201100")); 13133f1242f3SBrandon Wyman psu.analyze(); 13143f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 1315f07bc797SBrandon Wyman // Turn fault on. 1316b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VIN_UV_FAULT); 131785c7bf41SBrandon Wyman // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by 131885c7bf41SBrandon Wyman // Figure 16, and assume bits on in STATUS_INPUT. 1319b654c619SBrandon Wyman expectations.statusInputValue = 0x18; 1320c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1321c2906f47SBrandon Wyman { 1322b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 132382affd94SBrandon Wyman // If there is a VIN_UV fault, fake reading voltage of less than 20V 132482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 132582affd94SBrandon Wyman .Times(1) 132682affd94SBrandon Wyman .WillOnce(Return("19876")); 13270975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 13280975eaf4SMatt Spinler { 13290975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 13300975eaf4SMatt Spinler } 13313f1242f3SBrandon Wyman psu.analyze(); 1332c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 1333c2906f47SBrandon Wyman } 1334f07bc797SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1335b654c619SBrandon Wyman expectations.statusWordValue = 0; 1336b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 133782affd94SBrandon Wyman // Updates now result in clearing faults if read voltage goes from below the 133882affd94SBrandon Wyman // minimum, to within a valid range. 133982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 134082affd94SBrandon Wyman .Times(1) 134182affd94SBrandon Wyman .WillOnce(Return("201300")); 13423225a45cSBrandon Wyman // Went from below minimum to within range, expect clearVinUVFault(). 13433225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 13443225a45cSBrandon Wyman .Times(1) 13453225a45cSBrandon Wyman .WillOnce(Return(1)); 13460975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 13473f1242f3SBrandon Wyman psu.analyze(); 13483f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 13493f1242f3SBrandon Wyman } 13506710ba2cSBrandon Wyman 13516710ba2cSBrandon Wyman TEST_F(PowerSupplyTests, HasVoutOVFault) 13526710ba2cSBrandon Wyman { 13536710ba2cSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 13546710ba2cSBrandon Wyman 1355c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1356c3324424SBrandon Wyman 0x69, "ibm-cffps", PSUGPIOLineName}; 13576710ba2cSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 13586710ba2cSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 13596710ba2cSBrandon Wyman // Always return 1 to indicate present. 13606710ba2cSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 13616710ba2cSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1362391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1363*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1364*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1365*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1366*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1367*ae35ac5dSBrandon Wyman .Times(1) 1368*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 13696710ba2cSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1370b654c619SBrandon Wyman PMBusExpectations expectations; 1371b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 137282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 137382affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 137482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 137582affd94SBrandon Wyman .Times(1) 137682affd94SBrandon Wyman .WillOnce(Return("202100")); 13776710ba2cSBrandon Wyman psu.analyze(); 13786710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 13796710ba2cSBrandon Wyman // Turn fault on. 1380b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_OV_FAULT); 13816710ba2cSBrandon Wyman // STATUS_VOUT fault bit(s) 1382b654c619SBrandon Wyman expectations.statusVOUTValue = 0x80; 1383c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1384c2906f47SBrandon Wyman { 1385b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 138682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 138782affd94SBrandon Wyman .Times(1) 138882affd94SBrandon Wyman .WillOnce(Return("202200")); 13896710ba2cSBrandon Wyman psu.analyze(); 1390c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 1391c2906f47SBrandon Wyman } 13926710ba2cSBrandon Wyman // Back to no fault bits on in STATUS_WORD 1393b654c619SBrandon Wyman expectations.statusWordValue = 0; 1394b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 139582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 139682affd94SBrandon Wyman .Times(1) 139782affd94SBrandon Wyman .WillOnce(Return("202300")); 13986710ba2cSBrandon Wyman psu.analyze(); 13996710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 14006710ba2cSBrandon Wyman } 140196893a46SBrandon Wyman 1402b10b3be0SBrandon Wyman TEST_F(PowerSupplyTests, HasIoutOCFault) 1403b10b3be0SBrandon Wyman { 1404b10b3be0SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1405b10b3be0SBrandon Wyman 1406c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1407c3324424SBrandon Wyman 0x6d, "ibm-cffps", PSUGPIOLineName}; 1408b10b3be0SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1409b10b3be0SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1410b10b3be0SBrandon Wyman // Always return 1 to indicate present. 1411b10b3be0SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1412b10b3be0SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1413391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1414*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1415*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1416*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1417*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1418*ae35ac5dSBrandon Wyman .Times(1) 1419*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1420b10b3be0SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1421b10b3be0SBrandon Wyman PMBusExpectations expectations; 1422b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 142382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 142482affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 142582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 142682affd94SBrandon Wyman .Times(1) 142782affd94SBrandon Wyman .WillOnce(Return("203100")); 1428b10b3be0SBrandon Wyman psu.analyze(); 1429b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1430b10b3be0SBrandon Wyman // Turn fault on. 1431b10b3be0SBrandon Wyman expectations.statusWordValue = status_word::IOUT_OC_FAULT; 1432b10b3be0SBrandon Wyman // STATUS_IOUT fault bit(s) 1433b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0x88; 1434c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1435c2906f47SBrandon Wyman { 1436b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 143782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 143882affd94SBrandon Wyman .Times(1) 143982affd94SBrandon Wyman .WillOnce(Return("203200")); 14400975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 14410975eaf4SMatt Spinler { 14420975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 14430975eaf4SMatt Spinler } 1444b10b3be0SBrandon Wyman psu.analyze(); 1445c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 1446c2906f47SBrandon Wyman } 1447b10b3be0SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1448b10b3be0SBrandon Wyman expectations.statusWordValue = 0; 1449b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 145082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 145182affd94SBrandon Wyman .Times(1) 145282affd94SBrandon Wyman .WillOnce(Return("203300")); 14530975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1454b10b3be0SBrandon Wyman psu.analyze(); 1455b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1456b10b3be0SBrandon Wyman } 1457b10b3be0SBrandon Wyman 14582cf46945SBrandon Wyman TEST_F(PowerSupplyTests, HasVoutUVFault) 14592cf46945SBrandon Wyman { 14602cf46945SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 14612cf46945SBrandon Wyman 1462c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1463c3324424SBrandon Wyman 0x6a, "ibm-cffps", PSUGPIOLineName}; 14642cf46945SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 14652cf46945SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 14662cf46945SBrandon Wyman // Always return 1 to indicate present. 14672cf46945SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 14682cf46945SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1469391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1470*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1471*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1472*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1473*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1474*ae35ac5dSBrandon Wyman .Times(1) 1475*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1476391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 14772cf46945SBrandon Wyman PMBusExpectations expectations; 14782cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 147982affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 148082affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 148182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 148282affd94SBrandon Wyman .Times(1) 148382affd94SBrandon Wyman .WillOnce(Return("204100")); 14842cf46945SBrandon Wyman psu.analyze(); 14852cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 14862cf46945SBrandon Wyman // Turn fault on. 14872cf46945SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_FAULT); 14882cf46945SBrandon Wyman // STATUS_VOUT fault bit(s) 14892cf46945SBrandon Wyman expectations.statusVOUTValue = 0x30; 1490c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1491c2906f47SBrandon Wyman { 14922cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 149382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 149482affd94SBrandon Wyman .Times(1) 149582affd94SBrandon Wyman .WillOnce(Return("204200")); 14962cf46945SBrandon Wyman psu.analyze(); 1497c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), x >= DEGLITCH_LIMIT); 1498c2906f47SBrandon Wyman } 14992cf46945SBrandon Wyman // Back to no fault bits on in STATUS_WORD 15002cf46945SBrandon Wyman expectations.statusWordValue = 0; 15012cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 150282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 150382affd94SBrandon Wyman .Times(1) 150482affd94SBrandon Wyman .WillOnce(Return("204300")); 15052cf46945SBrandon Wyman psu.analyze(); 15062cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 15072cf46945SBrandon Wyman } 15082cf46945SBrandon Wyman 15097ee4d7e4SBrandon Wyman TEST_F(PowerSupplyTests, HasFanFault) 15107ee4d7e4SBrandon Wyman { 15117ee4d7e4SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 15127ee4d7e4SBrandon Wyman 15130975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1); 15140975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0); 15150975eaf4SMatt Spinler 1516c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1517c3324424SBrandon Wyman 0x6d, "ibm-cffps", PSUGPIOLineName}; 15187ee4d7e4SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 15197ee4d7e4SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 15207ee4d7e4SBrandon Wyman // Always return 1 to indicate present. 15217ee4d7e4SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 15227ee4d7e4SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1523391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1524*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1525*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1526*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1527*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1528*ae35ac5dSBrandon Wyman .Times(1) 1529*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 15307ee4d7e4SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 15317ee4d7e4SBrandon Wyman PMBusExpectations expectations; 15327ee4d7e4SBrandon 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("205100")); 15387ee4d7e4SBrandon Wyman psu.analyze(); 15397ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 15407ee4d7e4SBrandon Wyman // Turn fault on. 15417ee4d7e4SBrandon Wyman expectations.statusWordValue = (status_word::FAN_FAULT); 15427ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 fault bit on (Fan 1 Fault) 15437ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0x80; 1544c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1545c2906f47SBrandon Wyman { 15467ee4d7e4SBrandon 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("205200")); 15517ee4d7e4SBrandon Wyman psu.analyze(); 1552c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 1553c2906f47SBrandon Wyman } 15547ee4d7e4SBrandon Wyman // Back to no fault bits on in STATUS_WORD 15557ee4d7e4SBrandon Wyman expectations.statusWordValue = 0; 15567ee4d7e4SBrandon 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("205300")); 15617ee4d7e4SBrandon Wyman psu.analyze(); 15627ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 15637ee4d7e4SBrandon Wyman } 15647ee4d7e4SBrandon Wyman 156596893a46SBrandon Wyman TEST_F(PowerSupplyTests, HasTempFault) 156696893a46SBrandon Wyman { 156796893a46SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 156896893a46SBrandon Wyman 15690975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1); 15700975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0); 15710975eaf4SMatt Spinler 1572c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1573c3324424SBrandon Wyman 0x6a, "ibm-cffps", PSUGPIOLineName}; 157496893a46SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 157596893a46SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 157696893a46SBrandon Wyman // Always return 1 to indicate present. 157796893a46SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 157896893a46SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1579391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1580*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1581*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1582*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1583*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1584*ae35ac5dSBrandon Wyman .Times(1) 1585*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 158696893a46SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 158796893a46SBrandon Wyman PMBusExpectations expectations; 158896893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 158982affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 159082affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 159182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 159282affd94SBrandon Wyman .Times(1) 159382affd94SBrandon Wyman .WillOnce(Return("206100")); 159496893a46SBrandon Wyman psu.analyze(); 159596893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 159696893a46SBrandon Wyman // Turn fault on. 159796893a46SBrandon Wyman expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 159896893a46SBrandon Wyman // STATUS_TEMPERATURE fault bit on (OT Fault) 159996893a46SBrandon Wyman expectations.statusTempValue = 0x80; 1600c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1601c2906f47SBrandon Wyman { 160296893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 160382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 160482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 160582affd94SBrandon Wyman .Times(1) 160682affd94SBrandon Wyman .WillOnce(Return("206200")); 160796893a46SBrandon Wyman psu.analyze(); 1608c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 1609c2906f47SBrandon Wyman } 161096893a46SBrandon Wyman // Back to no fault bits on in STATUS_WORD 161196893a46SBrandon Wyman expectations.statusWordValue = 0; 161296893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 161382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 161482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 161582affd94SBrandon Wyman .Times(1) 161682affd94SBrandon Wyman .WillOnce(Return("206300")); 161796893a46SBrandon Wyman psu.analyze(); 161896893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 161996893a46SBrandon Wyman } 16202916ea52SBrandon Wyman 16212916ea52SBrandon Wyman TEST_F(PowerSupplyTests, HasPgoodFault) 16222916ea52SBrandon Wyman { 16232916ea52SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 16242916ea52SBrandon Wyman 1625c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1626c3324424SBrandon Wyman 0x6b, "ibm-cffps", PSUGPIOLineName}; 16272916ea52SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 16282916ea52SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 16292916ea52SBrandon Wyman // Always return 1 to indicate present. 16302916ea52SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 16312916ea52SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1632391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1633*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1634*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1635*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1636*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1637*ae35ac5dSBrandon Wyman .Times(1) 1638*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 16392916ea52SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 16402916ea52SBrandon Wyman PMBusExpectations expectations; 16412916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 164282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 164382affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 164482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 164582affd94SBrandon Wyman .Times(1) 164682affd94SBrandon Wyman .WillOnce(Return("207100")); 16472916ea52SBrandon Wyman psu.analyze(); 16482916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 1649391a0690SBrandon Wyman // Setup another expectation of no faults. 1650391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 165182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 165282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 165382affd94SBrandon Wyman .Times(1) 165482affd94SBrandon Wyman .WillOnce(Return("207200")); 165582affd94SBrandon Wyman psu.analyze(); 165682affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 165782affd94SBrandon Wyman // Setup another expectation of no faults. 165882affd94SBrandon 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("207300")); 1663391a0690SBrandon Wyman psu.analyze(); 1664391a0690SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 16652916ea52SBrandon Wyman // Turn PGOOD# off (fault on). 16662916ea52SBrandon Wyman expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED); 16672916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 166882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 166982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 167082affd94SBrandon Wyman .Times(1) 167182affd94SBrandon Wyman .WillOnce(Return("207400")); 16722916ea52SBrandon Wyman psu.analyze(); 167306ca4590SBrandon Wyman // Expect false until reaches DEGLITCH_LIMIT 167406ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 167506ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 167682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 167782affd94SBrandon Wyman .Times(1) 167882affd94SBrandon Wyman .WillOnce(Return("207500")); 167906ca4590SBrandon Wyman psu.analyze(); 168006ca4590SBrandon Wyman // Expect false until reaches DEGLITCH_LIMIT 168106ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 168206ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 168382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 168482affd94SBrandon Wyman .Times(1) 168582affd94SBrandon Wyman .WillOnce(Return("207600")); 168606ca4590SBrandon Wyman psu.analyze(); 168706ca4590SBrandon Wyman // DEGLITCH_LIMIT reached, expect true. 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) 169582affd94SBrandon Wyman .WillOnce(Return("207700")); 16962916ea52SBrandon Wyman psu.analyze(); 16972916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 169882affd94SBrandon Wyman 16992916ea52SBrandon Wyman // Turn OFF bit on 17002916ea52SBrandon Wyman expectations.statusWordValue = (status_word::UNIT_IS_OFF); 17012916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 170282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 170382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 170482affd94SBrandon Wyman .Times(1) 170582affd94SBrandon Wyman .WillOnce(Return("208100")); 17062916ea52SBrandon Wyman psu.analyze(); 170706ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 170806ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 170982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 171082affd94SBrandon Wyman .Times(1) 171182affd94SBrandon Wyman .WillOnce(Return("208200")); 171206ca4590SBrandon Wyman psu.analyze(); 171306ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 171406ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 171582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 171682affd94SBrandon Wyman .Times(1) 171782affd94SBrandon Wyman .WillOnce(Return("208300")); 171806ca4590SBrandon Wyman psu.analyze(); 17192916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 17202916ea52SBrandon Wyman // Back to no fault bits on in STATUS_WORD 17212916ea52SBrandon Wyman expectations.statusWordValue = 0; 17222916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 172382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 172482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 172582affd94SBrandon Wyman .Times(1) 172682affd94SBrandon Wyman .WillOnce(Return("208400")); 17272916ea52SBrandon Wyman psu.analyze(); 17282916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 17292916ea52SBrandon Wyman } 173039ea02bcSBrandon Wyman 173139ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSKillFault) 173239ea02bcSBrandon Wyman { 173339ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1734c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 1735c3324424SBrandon Wyman 0x6d, "ibm-cffps", PSUGPIOLineName}; 173639ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 173739ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 173839ea02bcSBrandon Wyman // Always return 1 to indicate present. 173939ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 174039ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 174182affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1742*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1743*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1744*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1745*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1746*ae35ac5dSBrandon Wyman .Times(1) 1747*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 174839ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 174939ea02bcSBrandon Wyman PMBusExpectations expectations; 175039ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 175182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 175282affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 175382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 175482affd94SBrandon Wyman .Times(1) 175582affd94SBrandon Wyman .WillOnce(Return("208100")); 175639ea02bcSBrandon Wyman psu.analyze(); 175739ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 175839ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 175939ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 176039ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 176139ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1762c2906f47SBrandon Wyman 1763c2906f47SBrandon Wyman // Deglitching faults, false until read the fault bits on up to the limit. 1764c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1765c2906f47SBrandon Wyman { 176639ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 176782affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 176882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 176982affd94SBrandon Wyman .Times(1) 177082affd94SBrandon Wyman .WillOnce(Return("208200")); 17710975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 17720975eaf4SMatt Spinler { 17730975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 17740975eaf4SMatt Spinler } 177539ea02bcSBrandon Wyman psu.analyze(); 1776c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1777c2906f47SBrandon Wyman } 1778c2906f47SBrandon Wyman 177939ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 178039ea02bcSBrandon Wyman expectations.statusWordValue = 0; 178139ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 178282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 178382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 178482affd94SBrandon Wyman .Times(1) 178582affd94SBrandon Wyman .WillOnce(Return("208300")); 17860975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 178739ea02bcSBrandon Wyman psu.analyze(); 178839ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 178939ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 179039ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 179139ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 4 on. 179239ea02bcSBrandon Wyman expectations.statusMFRValue = 0x10; 1793c2906f47SBrandon Wyman 1794c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1795c2906f47SBrandon Wyman { 179639ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 179782affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 179882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 179982affd94SBrandon Wyman .Times(1) 180082affd94SBrandon Wyman .WillOnce(Return("208400")); 18010975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 18020975eaf4SMatt Spinler { 18030975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 18040975eaf4SMatt Spinler } 180539ea02bcSBrandon Wyman psu.analyze(); 1806c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1807c2906f47SBrandon Wyman } 1808c2906f47SBrandon Wyman 180939ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 181039ea02bcSBrandon Wyman expectations.statusWordValue = 0; 181139ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 181282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 181382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 181482affd94SBrandon Wyman .Times(1) 181582affd94SBrandon Wyman .WillOnce(Return("208500")); 18160975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 181739ea02bcSBrandon Wyman psu.analyze(); 181839ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 181939ea02bcSBrandon Wyman } 182039ea02bcSBrandon Wyman 182139ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPS12VcsFault) 182239ea02bcSBrandon Wyman { 182339ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1824c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 5, 1825c3324424SBrandon Wyman 0x6e, "ibm-cffps", PSUGPIOLineName}; 182639ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 182739ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 182839ea02bcSBrandon Wyman // Always return 1 to indicate present. 182939ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 183039ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 183182affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1832*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1833*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1834*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1835*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1836*ae35ac5dSBrandon Wyman .Times(1) 1837*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 183839ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 183939ea02bcSBrandon Wyman PMBusExpectations expectations; 184039ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 184182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 184282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 184382affd94SBrandon Wyman .Times(1) 184482affd94SBrandon Wyman .WillOnce(Return("209100")); 184539ea02bcSBrandon Wyman psu.analyze(); 184639ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 184739ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 184839ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 184939ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 185039ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1851c2906f47SBrandon Wyman 1852c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1853c2906f47SBrandon Wyman { 185439ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 185582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 185682affd94SBrandon Wyman .Times(1) 185782affd94SBrandon Wyman .WillOnce(Return("209200")); 185839ea02bcSBrandon Wyman psu.analyze(); 1859c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1860c2906f47SBrandon Wyman } 1861c2906f47SBrandon Wyman 186239ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 186339ea02bcSBrandon Wyman expectations.statusWordValue = 0; 186439ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 186582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 186682affd94SBrandon Wyman .Times(1) 186782affd94SBrandon Wyman .WillOnce(Return("209300")); 186839ea02bcSBrandon Wyman psu.analyze(); 186939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 187039ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 187139ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 187239ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 6 on. 187339ea02bcSBrandon Wyman expectations.statusMFRValue = 0x40; 1874c2906f47SBrandon Wyman 1875c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1876c2906f47SBrandon Wyman { 187739ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 187882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 187982affd94SBrandon Wyman .Times(1) 188082affd94SBrandon Wyman .WillOnce(Return("209400")); 188139ea02bcSBrandon Wyman psu.analyze(); 1882c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1883c2906f47SBrandon Wyman } 1884c2906f47SBrandon Wyman 188539ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 188639ea02bcSBrandon Wyman expectations.statusWordValue = 0; 188739ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 188882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 188982affd94SBrandon Wyman .Times(1) 189082affd94SBrandon Wyman .WillOnce(Return("209500")); 189139ea02bcSBrandon Wyman psu.analyze(); 189239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 189339ea02bcSBrandon Wyman } 189439ea02bcSBrandon Wyman 189539ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSCS12VFault) 189639ea02bcSBrandon Wyman { 189739ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1898c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 6, 1899c3324424SBrandon Wyman 0x6f, "ibm-cffps", PSUGPIOLineName}; 190039ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 190139ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 190239ea02bcSBrandon Wyman // Always return 1 to indicate present. 190339ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 190439ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 190582affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1906*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1907*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1908*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1909*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1910*ae35ac5dSBrandon Wyman .Times(1) 1911*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 191239ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 191339ea02bcSBrandon Wyman PMBusExpectations expectations; 191439ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 191582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 191682affd94SBrandon Wyman .Times(1) 191782affd94SBrandon Wyman .WillOnce(Return("209100")); 191839ea02bcSBrandon Wyman psu.analyze(); 191939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 192039ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 192139ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 192239ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 192339ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1924c2906f47SBrandon Wyman 1925c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1926c2906f47SBrandon Wyman { 192739ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 192882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 192982affd94SBrandon Wyman .Times(1) 193082affd94SBrandon Wyman .WillOnce(Return("209200")); 193139ea02bcSBrandon Wyman psu.analyze(); 1932c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1933c2906f47SBrandon Wyman } 1934c2906f47SBrandon Wyman 193539ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 193639ea02bcSBrandon Wyman expectations.statusWordValue = 0; 193739ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 193882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 193982affd94SBrandon Wyman .Times(1) 194082affd94SBrandon Wyman .WillOnce(Return("209300")); 194139ea02bcSBrandon Wyman psu.analyze(); 194239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 194339ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 194439ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 194539ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 7 on. 194639ea02bcSBrandon Wyman expectations.statusMFRValue = 0x80; 1947c2906f47SBrandon Wyman 1948c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1949c2906f47SBrandon Wyman { 195039ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 195182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 195282affd94SBrandon Wyman .Times(1) 195382affd94SBrandon Wyman .WillOnce(Return("209400")); 195439ea02bcSBrandon Wyman psu.analyze(); 1955c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1956c2906f47SBrandon Wyman } 1957c2906f47SBrandon Wyman 195839ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 195939ea02bcSBrandon Wyman expectations.statusWordValue = 0; 196039ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 196182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 196282affd94SBrandon Wyman .Times(1) 196382affd94SBrandon Wyman .WillOnce(Return("209500")); 196439ea02bcSBrandon Wyman psu.analyze(); 196539ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 196639ea02bcSBrandon Wyman } 1967c3324424SBrandon Wyman 1968c3324424SBrandon Wyman TEST_F(PowerSupplyTests, SetupInputHistory) 1969c3324424SBrandon Wyman { 1970c3324424SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1971c3324424SBrandon Wyman { 1972c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 6, 1973c3324424SBrandon Wyman 0x6f, "ibm-cffps", PSUGPIOLineName}; 1974c3324424SBrandon Wyman // Defaults to not present due to constructor and mock ordering. 1975c3324424SBrandon Wyman psu.setupInputHistory(); 1976c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 1977c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1978c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1979*ae35ac5dSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1980c3324424SBrandon Wyman // Always return 1 to indicate present. 1981c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1982*ae35ac5dSBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1983*ae35ac5dSBrandon Wyman PMBusExpectations expectations; 1984*ae35ac5dSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 1985*ae35ac5dSBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 1986*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 1987*ae35ac5dSBrandon Wyman .Times(1) 1988*ae35ac5dSBrandon Wyman .WillOnce(Return("206000")); 1989*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1990*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1991*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1992*ae35ac5dSBrandon Wyman /// Also called when I redo setupInputHistory(). 1993*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1994*ae35ac5dSBrandon Wyman .Times(2) 1995*ae35ac5dSBrandon Wyman .WillRepeatedly(Return("2000")); 1996*ae35ac5dSBrandon Wyman // Call to analyze() and above expectations to get missing/present and 1997*ae35ac5dSBrandon Wyman // good status. 1998c3324424SBrandon Wyman psu.analyze(); 1999c3324424SBrandon Wyman psu.setupInputHistory(); 2000c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2001c3324424SBrandon Wyman } 2002c3324424SBrandon Wyman { 2003*ae35ac5dSBrandon Wyman // Workaround - Disable INPUT_HISTORY collection if 1400W 2004*ae35ac5dSBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 2005*ae35ac5dSBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 2006*ae35ac5dSBrandon Wyman // Defaults to not present due to constructor and mock ordering. 2007*ae35ac5dSBrandon Wyman psu.setupInputHistory(); 2008*ae35ac5dSBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2009*ae35ac5dSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 2010*ae35ac5dSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 2011*ae35ac5dSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2012*ae35ac5dSBrandon Wyman // Always return 1 to indicate present. 2013*ae35ac5dSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 2014*ae35ac5dSBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2015*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 2016*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 2017*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate 1400W IBM value, unsupported. 2018*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2019*ae35ac5dSBrandon Wyman .Times(2) 2020*ae35ac5dSBrandon Wyman .WillRepeatedly(Return("30725")); 2021*ae35ac5dSBrandon Wyman PMBusExpectations expectations; 2022*ae35ac5dSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2023*ae35ac5dSBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 2024*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2025*ae35ac5dSBrandon Wyman .Times(1) 2026*ae35ac5dSBrandon Wyman .WillOnce(Return("206000")); 2027*ae35ac5dSBrandon Wyman // Call to analyze() and above expectations to get missing/present and 2028*ae35ac5dSBrandon Wyman // good status. 2029*ae35ac5dSBrandon Wyman psu.analyze(); 2030*ae35ac5dSBrandon Wyman psu.setupInputHistory(); 2031*ae35ac5dSBrandon Wyman // After updating to present, and retrying setup, expect ibm-cffps with 2032*ae35ac5dSBrandon Wyman // 1400W to still not support INPUT_HISTORY. 2033*ae35ac5dSBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2034*ae35ac5dSBrandon Wyman } 2035*ae35ac5dSBrandon Wyman { 2036c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 11, 2037c3324424SBrandon Wyman 0x58, "inspur-ipsps", PSUGPIOLineName}; 2038c3324424SBrandon Wyman // Defaults to not present due to constructor and mock ordering. 2039c3324424SBrandon Wyman psu.setupInputHistory(); 2040c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2041c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 2042c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 2043*ae35ac5dSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2044c3324424SBrandon Wyman // Always return 1 to indicate present. 2045c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 2046*ae35ac5dSBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2047*ae35ac5dSBrandon Wyman PMBusExpectations expectations; 2048*ae35ac5dSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2049*ae35ac5dSBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 2050*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2051*ae35ac5dSBrandon Wyman .Times(1) 2052*ae35ac5dSBrandon Wyman .WillOnce(Return("206000")); 2053*ae35ac5dSBrandon Wyman // Call to analyze() and above expectations to get missing/present and 2054*ae35ac5dSBrandon Wyman // good status. 2055c3324424SBrandon Wyman psu.analyze(); 2056c3324424SBrandon Wyman psu.setupInputHistory(); 2057c3324424SBrandon Wyman // After updating to present, and retrying setup, expect inspur-ipsps to 2058c3324424SBrandon Wyman // still not support INPUT_HISTORY. 2059c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2060c3324424SBrandon Wyman } 2061c3324424SBrandon Wyman } 2062c3324424SBrandon Wyman 2063c3324424SBrandon Wyman TEST_F(PowerSupplyTests, UpdateHistory) 2064c3324424SBrandon Wyman { 2065c3324424SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2066c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 7, 2067c3324424SBrandon Wyman 0x6e, "ibm-cffps", PSUGPIOLineName}; 2068c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2069c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 0); 2070c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 2071c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 2072c3324424SBrandon Wyman // Always return 1 to indicate present. 2073c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 2074c3324424SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2075c3324424SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2076*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 2077*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 2078*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 2079*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2080*ae35ac5dSBrandon Wyman .Times(1) 2081*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 2082c3324424SBrandon Wyman PMBusExpectations expectations; 2083c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2084c3324424SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2085c3324424SBrandon Wyman .Times(6) 2086c3324424SBrandon Wyman .WillRepeatedly(Return("205000")); 2087c3324424SBrandon Wyman EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 2088c3324424SBrandon Wyman // First read after missing/present will have no data. 2089c3324424SBrandon Wyman std::vector<uint8_t> emptyHistory{}; 2090c3324424SBrandon Wyman // Second read, after about 30 seconds, should have a record. 5-bytes. 2091c3324424SBrandon Wyman // Sequence Number: 0x00, Average: 0x50 0xf3 (212), Maximum: 0x54 0xf3 (213) 2092c3324424SBrandon Wyman std::vector<uint8_t> firstHistory{0x00, 0x50, 0xf3, 0x54, 0xf3}; 2093c3324424SBrandon Wyman // Third read, after about 60 seconds, should have two records, 10-bytes, 2094c3324424SBrandon Wyman // but only reading 5 bytes, so make sure new/next sequence number 2095c3324424SBrandon Wyman std::vector<uint8_t> secondHistory{0x01, 0x54, 0xf3, 0x58, 0xf3}; 2096c3324424SBrandon Wyman // Fourth read, 3rd sequence number (0x02). 2097c3324424SBrandon Wyman std::vector<uint8_t> thirdHistory{0x02, 0x54, 0xf3, 0x58, 0xf3}; 2098c3324424SBrandon Wyman // Fifth read, out of sequence, clear and insert this one? 2099c3324424SBrandon Wyman std::vector<uint8_t> outseqHistory{0xff, 0x5c, 0xf3, 0x60, 0xf3}; 2100c3324424SBrandon Wyman EXPECT_CALL( 2101c3324424SBrandon Wyman mockPMBus, 2102c3324424SBrandon Wyman readBinary(INPUT_HISTORY, Type::HwmonDeviceDebug, 2103c3324424SBrandon Wyman phosphor::power::history::RecordManager::RAW_RECORD_SIZE)) 2104c3324424SBrandon Wyman .Times(6) 2105c3324424SBrandon Wyman .WillOnce(Return(emptyHistory)) 2106c3324424SBrandon Wyman .WillOnce(Return(firstHistory)) 2107c3324424SBrandon Wyman .WillOnce(Return(secondHistory)) 2108c3324424SBrandon Wyman .WillOnce(Return(thirdHistory)) 2109c3324424SBrandon Wyman .WillOnce(Return(outseqHistory)) 2110c3324424SBrandon Wyman .WillOnce(Return(emptyHistory)); 2111c3324424SBrandon Wyman // Calling analyze will update the presence, which will setup the input 2112c3324424SBrandon Wyman // history if the power supply went from missing to present. 2113c3324424SBrandon Wyman psu.analyze(); 2114c3324424SBrandon Wyman // The ibm-cffps power supply should support input history 2115c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2116c3324424SBrandon Wyman // Usually should have empty buffer right after missing to present. 2117c3324424SBrandon Wyman // Faked that out above with mocked readBinary with emptyHistory data. 2118c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 0); 2119c3324424SBrandon Wyman // Second run through... 2120c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2121c3324424SBrandon Wyman psu.analyze(); 2122c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2123c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 1); 2124c3324424SBrandon Wyman // Third run through 2125c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2126c3324424SBrandon Wyman psu.analyze(); 2127c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2128c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 2); 2129c3324424SBrandon Wyman // Fourth run through. Up to 3 records now? 2130c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2131c3324424SBrandon Wyman psu.analyze(); 2132c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2133c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 3); 2134c3324424SBrandon Wyman // Out of sequencer, reset, insert new one. 2135c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2136c3324424SBrandon Wyman psu.analyze(); 2137c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2138c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 1); 2139c3324424SBrandon Wyman // Empty one after last one good. Reset/clear. 2140c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2141c3324424SBrandon Wyman psu.analyze(); 2142c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2143c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 0); 2144c3324424SBrandon Wyman } 214518a24d92SBrandon Wyman 214618a24d92SBrandon Wyman TEST_F(PowerSupplyTests, IsSyncHistoryRequired) 214718a24d92SBrandon Wyman { 214818a24d92SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 214918a24d92SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 8, 215018a24d92SBrandon Wyman 0x6f, "ibm-cffps", PSUGPIOLineName}; 215118a24d92SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 215218a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), false); 215318a24d92SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 215418a24d92SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 215518a24d92SBrandon Wyman // Always return 1 to indicate present. 215618a24d92SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 215718a24d92SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 215818a24d92SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2159*ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 2160*ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 2161*ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 2162*ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2163*ae35ac5dSBrandon Wyman .Times(1) 2164*ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 216518a24d92SBrandon Wyman PMBusExpectations expectations; 216618a24d92SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 216718a24d92SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 216818a24d92SBrandon Wyman .Times(1) 216918a24d92SBrandon Wyman .WillRepeatedly(Return("205000")); 217018a24d92SBrandon Wyman EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 217118a24d92SBrandon Wyman psu.analyze(); 217218a24d92SBrandon Wyman // The ibm-cffps power supply should support input history 217318a24d92SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 217418a24d92SBrandon Wyman // Missing -> Present requires history sync 217518a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), true); 217618a24d92SBrandon Wyman psu.clearSyncHistoryRequired(); 217718a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), false); 217818a24d92SBrandon Wyman } 2179