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); 259ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 260ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 261ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 262ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 263ae35ac5dSBrandon Wyman .Times(1) 264ae35ac5dSBrandon 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)); 699*6d469fd4SBrandon Wyman for (auto x = 1; x <= PGOOD_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); 709*6d469fd4SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= PGOOD_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); 719*6d469fd4SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), x >= PGOOD_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); 765ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 766ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 767ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 768ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 769ae35ac5dSBrandon Wyman .Times(1) 770ae35ac5dSBrandon 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); 801ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 802ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 803ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 804ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 805ae35ac5dSBrandon Wyman .Times(1) 806ae35ac5dSBrandon 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 847*6d469fd4SBrandon Wyman for (auto x = 1; x <= PGOOD_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); 862*6d469fd4SBrandon Wyman // pgoodFault at PGOOD_DEGLITCH_LIMIT, all other faults are deglitched 863*6d469fd4SBrandon Wyman // up to DEGLITCH_LIMIT 864c2906f47SBrandon Wyman EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT); 865c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 866c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 867c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 868c2906f47SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), x >= DEGLITCH_LIMIT); 869c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 870c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 871c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 872c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 873*6d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), x >= PGOOD_DEGLITCH_LIMIT); 874c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 875c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 876c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 877c2906f47SBrandon Wyman } 878c2906f47SBrandon Wyman 87932453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)) 88032453e9bSBrandon Wyman .Times(1) 88132453e9bSBrandon Wyman .WillOnce(Return(207000)); 8823225a45cSBrandon Wyman // Clearing VIN_UV fault via in1_lcrit_alarm 8833225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 8843225a45cSBrandon Wyman .Times(1) 8853225a45cSBrandon Wyman .WillOnce(Return(1)); 8860975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 8873f1242f3SBrandon Wyman psu.clearFaults(); 8883f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8893f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 8903f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 8913f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 8923f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 89385c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 8946710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 895b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 8962cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 8977ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 89896893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 8992916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 90039ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 90139ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 90239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 903681b2a36SB. J. Wyman 90482affd94SBrandon Wyman // Faults clear on READ_VIN 0 -> !0 90582affd94SBrandon Wyman // STATUS_WORD with fault bits galore! 90682affd94SBrandon Wyman expectations.statusWordValue = 0xFFFF; 90782affd94SBrandon Wyman // STATUS_INPUT with fault bits on. 90882affd94SBrandon Wyman expectations.statusInputValue = 0xFF; 90982affd94SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 91082affd94SBrandon Wyman expectations.statusMFRValue = 0xFF; 91182affd94SBrandon Wyman // STATUS_CML with bits on. 91282affd94SBrandon Wyman expectations.statusCMLValue = 0xFF; 91382affd94SBrandon Wyman // STATUS_VOUT with bits on. 91482affd94SBrandon Wyman expectations.statusVOUTValue = 0xFF; 91582affd94SBrandon Wyman // STATUS_IOUT with bits on. 91682affd94SBrandon Wyman expectations.statusIOUTValue = 0xFF; 91782affd94SBrandon Wyman // STATUS_FANS_1_2 with bits on. 91882affd94SBrandon Wyman expectations.statusFans12Value = 0xFF; 91982affd94SBrandon Wyman // STATUS_TEMPERATURE with bits on. 92082affd94SBrandon Wyman expectations.statusTempValue = 0xFF; 921c2906f47SBrandon Wyman 922*6d469fd4SBrandon Wyman // All faults deglitched now. Check for false before limit above. 923c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 924c2906f47SBrandon Wyman { 92582affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 92682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 92782affd94SBrandon Wyman .Times(1) 92882affd94SBrandon Wyman .WillOnce(Return("0")); 9290975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 9300975eaf4SMatt Spinler { 9310975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 9320975eaf4SMatt Spinler } 93382affd94SBrandon Wyman psu.analyze(); 934c2906f47SBrandon Wyman } 935c2906f47SBrandon Wyman 93682affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 93782affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 93882affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 93982affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 94082affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 94182affd94SBrandon Wyman // True due to CML fault bits on 94282affd94SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), true); 94382affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 94482affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), true); 94582affd94SBrandon Wyman // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT. 94682affd94SBrandon Wyman // Rely on HasVoutUVFault() to verify this sets and clears. 94782affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 94882affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), true); 94982affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), true); 950*6d469fd4SBrandon Wyman // No PGOOD fault, as less than PGOOD_DEGLITCH_LIMIT 951*6d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 95282affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), true); 95382affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), true); 95482affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), true); 95582affd94SBrandon Wyman // STATUS_WORD with INPUT/VIN_UV fault bits off. 95682affd94SBrandon Wyman expectations.statusWordValue = 0xDFF7; 95782affd94SBrandon Wyman // STATUS_INPUT with VIN_UV_WARNING, VIN_UV_FAULT, and Unit Off For 95882affd94SBrandon Wyman // Insufficient Input Voltage bits off. 95982affd94SBrandon Wyman expectations.statusInputValue = 0xC7; 96082affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 96182affd94SBrandon Wyman // READ_VIN back in range. 96282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 96382affd94SBrandon Wyman .Times(1) 96482affd94SBrandon Wyman .WillOnce(Return("206000")); 9653225a45cSBrandon Wyman // VIN_UV cleared via in1_lcrit_alarm when voltage back in range. 9663225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 9673225a45cSBrandon Wyman .Times(1) 9683225a45cSBrandon Wyman .WillOnce(Return(1)); 9693225a45cSBrandon Wyman psu.analyze(); 9703225a45cSBrandon Wyman // We only cleared the VIN_UV and OFF faults. 9713225a45cSBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 9723225a45cSBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 9733225a45cSBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 9743225a45cSBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 9753225a45cSBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 9763225a45cSBrandon Wyman EXPECT_EQ(psu.hasCommFault(), true); 9773225a45cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 9783225a45cSBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), true); 9793225a45cSBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 9803225a45cSBrandon Wyman EXPECT_EQ(psu.hasFanFault(), true); 9813225a45cSBrandon Wyman EXPECT_EQ(psu.hasTempFault(), true); 982*6d469fd4SBrandon Wyman // No PGOOD fault, as less than PGOOD_DEGLITCH_LIMIT 983*6d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 9843225a45cSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), true); 9853225a45cSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), true); 9863225a45cSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), true); 9873225a45cSBrandon Wyman 9883225a45cSBrandon Wyman // All faults cleared 9893225a45cSBrandon Wyman expectations = {0}; 9903225a45cSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 9913225a45cSBrandon Wyman // READ_VIN back in range. 9923225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 9933225a45cSBrandon Wyman .Times(1) 9943225a45cSBrandon Wyman .WillOnce(Return("206000")); 9950975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 99682affd94SBrandon Wyman psu.analyze(); 99782affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 99882affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 99982affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 100082affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 100182affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 100282affd94SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 100382affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 100482affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 100582affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 100682affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 100782affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 100882affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 100982affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 101082affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 101182affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 101282affd94SBrandon Wyman 1013681b2a36SB. J. Wyman // TODO: Faults clear on missing/present? 10143f1242f3SBrandon Wyman } 10153f1242f3SBrandon Wyman 10163f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory) 10173f1242f3SBrandon Wyman { 10183f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 10191d7a7df8SBrandon Wyman 10201d7a7df8SBrandon Wyman try 10211d7a7df8SBrandon Wyman { 1022c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1023c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 10241d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 10251d7a7df8SBrandon Wyman // If it is not present, I should not be trying to read a string 10261d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).Times(0); 10271d7a7df8SBrandon Wyman psu.updateInventory(); 10281d7a7df8SBrandon Wyman } 10291d7a7df8SBrandon Wyman catch (...) 10301d7a7df8SBrandon Wyman { 10311d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 10321d7a7df8SBrandon Wyman } 10331d7a7df8SBrandon Wyman 10341d7a7df8SBrandon Wyman try 10351d7a7df8SBrandon Wyman { 1036c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 13, 1037c3324424SBrandon Wyman 0x69, "ibm-cffps", PSUGPIOLineName}; 10383ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10393ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1040681b2a36SB. J. Wyman // GPIO read return 1 to indicate present. 1041681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 10421d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1043391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1044ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1045ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1046ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1047ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1048ae35ac5dSBrandon Wyman .Times(1) 1049ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1050391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1051391a0690SBrandon Wyman PMBusExpectations expectations; 1052391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 105382affd94SBrandon Wyman // Call to analyze will read voltage, trigger clear faults for 0 to 105482affd94SBrandon Wyman // within range. 105582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 105682affd94SBrandon Wyman .Times(1) 105782affd94SBrandon Wyman .WillOnce(Return("123456")); 1058391a0690SBrandon Wyman psu.analyze(); 10591d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return("")); 10603f1242f3SBrandon Wyman psu.updateInventory(); 10611d7a7df8SBrandon Wyman 10623c530fbdSBrandon Wyman #if IBM_VPD 10631d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)) 10641d7a7df8SBrandon Wyman .WillOnce(Return("CCIN")) 10651d7a7df8SBrandon Wyman .WillOnce(Return("PN3456")) 10661d7a7df8SBrandon Wyman .WillOnce(Return("FN3456")) 10671d7a7df8SBrandon Wyman .WillOnce(Return("HEADER")) 10681d7a7df8SBrandon Wyman .WillOnce(Return("SN3456")) 10691d7a7df8SBrandon Wyman .WillOnce(Return("FW3456")); 10703c530fbdSBrandon Wyman #endif 10711d7a7df8SBrandon Wyman psu.updateInventory(); 10721d7a7df8SBrandon Wyman // TODO: D-Bus mocking to verify values stored on D-Bus (???) 10731d7a7df8SBrandon Wyman } 10741d7a7df8SBrandon Wyman catch (...) 10751d7a7df8SBrandon Wyman { 10761d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 10771d7a7df8SBrandon Wyman } 10783f1242f3SBrandon Wyman } 10793f1242f3SBrandon Wyman 10803f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent) 10813f1242f3SBrandon Wyman { 10823f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1083681b2a36SB. J. Wyman 1084c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1085c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 10863ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10873ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 10883f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 10893f1242f3SBrandon Wyman 1090681b2a36SB. J. Wyman // Change GPIO read to return 1 to indicate present. 1091681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 1092391a0690SBrandon Wyman // Call to analyze() will update to present, that will trigger updating 1093391a0690SBrandon Wyman // to the correct/latest HWMON directory, in case it changes. 1094391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1095391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1096ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1097ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1098ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1099ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1100ae35ac5dSBrandon Wyman .Times(1) 1101ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1102391a0690SBrandon Wyman // Call to analyze things will trigger read of STATUS_WORD and READ_VIN. 1103391a0690SBrandon Wyman // Default expectations will be on, no faults. 1104391a0690SBrandon Wyman PMBusExpectations expectations; 1105391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 110682affd94SBrandon Wyman // Give it an input voltage in the 100-volt range. 110782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 110882affd94SBrandon Wyman .Times(1) 110982affd94SBrandon Wyman .WillOnce(Return("123456")); 11100975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1111681b2a36SB. J. Wyman psu.analyze(); 1112681b2a36SB. J. Wyman EXPECT_EQ(psu.isPresent(), true); 11133f1242f3SBrandon Wyman } 11143f1242f3SBrandon Wyman 11153f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted) 11163f1242f3SBrandon Wyman { 11173f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1118681b2a36SB. J. Wyman 1119c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 11, 1120c3324424SBrandon Wyman 0x6f, "ibm-cffps", PSUGPIOLineName}; 11213ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 11223ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1123681b2a36SB. J. Wyman // Always return 1 to indicate present. 1124681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1125391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1126391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1127ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1128ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1129ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1130ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1131ae35ac5dSBrandon Wyman .Times(1) 1132ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1133391a0690SBrandon Wyman // Call to analyze things will trigger read of STATUS_WORD and READ_VIN. 1134391a0690SBrandon Wyman // Default expectations will be on, no faults. 1135391a0690SBrandon Wyman PMBusExpectations expectations; 1136391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 113782affd94SBrandon Wyman // Give it an input voltage in the 100-volt range. 113882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 113982affd94SBrandon Wyman .Times(1) 114082affd94SBrandon Wyman .WillOnce(Return("124680")); 1141681b2a36SB. J. Wyman psu.analyze(); 11423f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 1143f07bc797SBrandon Wyman // STATUS_WORD with fault bits on. 1144b654c619SBrandon Wyman expectations.statusWordValue = 0xFFFF; 1145f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 1146b654c619SBrandon Wyman expectations.statusInputValue = 0xFF; 1147f07bc797SBrandon Wyman // STATUS_MFR_SPECIFIC with faults bits on. 1148b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 114985c7bf41SBrandon Wyman // STATUS_CML with faults bits on. 1150b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 11516710ba2cSBrandon Wyman // STATUS_VOUT with fault bits on. 1152b654c619SBrandon Wyman expectations.statusVOUTValue = 0xFF; 1153b10b3be0SBrandon Wyman // STATUS_IOUT with fault bits on. 1154b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0xFF; 11557ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with bits on. 11567ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xFF; 115796893a46SBrandon Wyman // STATUS_TEMPERATURE with fault bits on. 115896893a46SBrandon Wyman expectations.statusTempValue = 0xFF; 1159c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1160c2906f47SBrandon Wyman { 1161b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 11624fc191f0SBrandon Wyman // Also get another read of READ_VIN, faulted, so not in 100-volt range 116382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 116482affd94SBrandon Wyman .Times(1) 11654fc191f0SBrandon Wyman .WillOnce(Return("19000")); 11660975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 11670975eaf4SMatt Spinler { 11680975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 11690975eaf4SMatt Spinler } 11703f1242f3SBrandon Wyman psu.analyze(); 1171c2906f47SBrandon Wyman EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT); 1172c2906f47SBrandon Wyman } 11733f1242f3SBrandon Wyman } 11743f1242f3SBrandon Wyman 11753f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasInputFault) 11763f1242f3SBrandon Wyman { 11773f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1178681b2a36SB. J. Wyman 1179c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1180c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 11813ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 11823ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1183681b2a36SB. J. Wyman // Always return 1 to indicate present. 1184681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 11853f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1186391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1187ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1188ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1189ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1190ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1191ae35ac5dSBrandon Wyman .Times(1) 1192ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 11938da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1194b654c619SBrandon Wyman PMBusExpectations expectations; 1195b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 119682affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 119782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 119882affd94SBrandon Wyman .Times(1) 119982affd94SBrandon Wyman .WillOnce(Return("201100")); 12003f1242f3SBrandon Wyman psu.analyze(); 12013f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 1202f07bc797SBrandon Wyman // STATUS_WORD with input fault/warn on. 1203b654c619SBrandon Wyman expectations.statusWordValue = (status_word::INPUT_FAULT_WARN); 1204f07bc797SBrandon Wyman // STATUS_INPUT with an input fault bit on. 1205b654c619SBrandon Wyman expectations.statusInputValue = 0x80; 1206c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1207c2906f47SBrandon Wyman { 1208b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 120982affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 121082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 121182affd94SBrandon Wyman .Times(1) 121282affd94SBrandon Wyman .WillOnce(Return("201200")); 12130975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 12140975eaf4SMatt Spinler { 12150975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 12160975eaf4SMatt Spinler } 12173f1242f3SBrandon Wyman psu.analyze(); 1218c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 1219c2906f47SBrandon Wyman } 1220f07bc797SBrandon Wyman // STATUS_WORD with no bits on. 1221b654c619SBrandon Wyman expectations.statusWordValue = 0; 1222b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 122382affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 122482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 122582affd94SBrandon Wyman .Times(1) 122682affd94SBrandon Wyman .WillOnce(Return("201300")); 12270975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 12283f1242f3SBrandon Wyman psu.analyze(); 12293f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 12303f1242f3SBrandon Wyman } 12313f1242f3SBrandon Wyman 12323f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault) 12333f1242f3SBrandon Wyman { 12343f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1235681b2a36SB. J. Wyman 1236c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1237c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 12383ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 12393ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1240681b2a36SB. J. Wyman // Always return 1 to indicate present. 1241681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 12423f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1243391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1244ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1245ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1246ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1247ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1248ae35ac5dSBrandon Wyman .Times(1) 1249ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1250f07bc797SBrandon Wyman // First return STATUS_WORD with no bits on. 12518da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1252b654c619SBrandon Wyman PMBusExpectations expectations; 1253b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 125482affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 125582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 125682affd94SBrandon Wyman .Times(1) 125782affd94SBrandon Wyman .WillOnce(Return("202100")); 12583f1242f3SBrandon Wyman psu.analyze(); 12593f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 1260f07bc797SBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 1261b654c619SBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 1262f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 1263b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 1264c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1265c2906f47SBrandon Wyman { 1266b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 126782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 126882affd94SBrandon Wyman .Times(1) 126982affd94SBrandon Wyman .WillOnce(Return("202200")); 12703f1242f3SBrandon Wyman psu.analyze(); 1271c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 1272c2906f47SBrandon Wyman } 1273f07bc797SBrandon Wyman // Back to no bits on in STATUS_WORD 1274b654c619SBrandon Wyman expectations.statusWordValue = 0; 1275b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 127682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 127782affd94SBrandon Wyman .Times(1) 127882affd94SBrandon Wyman .WillOnce(Return("202300")); 12793f1242f3SBrandon Wyman psu.analyze(); 12803f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 12813f1242f3SBrandon Wyman } 12823f1242f3SBrandon Wyman 12833f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault) 12843f1242f3SBrandon Wyman { 12853f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1286681b2a36SB. J. Wyman 1287c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1288c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 12893ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 12903ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1291681b2a36SB. J. Wyman // Always return 1 to indicate present. 1292681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 12933f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1294391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1295ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1296ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1297ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1298ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1299ae35ac5dSBrandon Wyman .Times(1) 1300ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 130182affd94SBrandon Wyman 130282affd94SBrandon Wyman // Presence change from missing to present will trigger in1_input read in 130382affd94SBrandon Wyman // an attempt to get CLEAR_FAULTS called. Return value ignored. 130482affd94SBrandon Wyman // Zero to non-zero voltage, for missing/present change, triggers clear 130582affd94SBrandon Wyman // faults call again. Return value ignored. 130682affd94SBrandon Wyman // Fault (low voltage) to not faulted (voltage in range) triggers clear 130782affd94SBrandon Wyman // faults call a third time. 130882affd94SBrandon Wyman 13098da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1310b654c619SBrandon Wyman PMBusExpectations expectations; 1311b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 131282affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 131382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 131482affd94SBrandon Wyman .Times(1) 131582affd94SBrandon Wyman .WillOnce(Return("201100")); 13163f1242f3SBrandon Wyman psu.analyze(); 13173f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 1318f07bc797SBrandon Wyman // Turn fault on. 1319b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VIN_UV_FAULT); 132085c7bf41SBrandon Wyman // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by 132185c7bf41SBrandon Wyman // Figure 16, and assume bits on in STATUS_INPUT. 1322b654c619SBrandon Wyman expectations.statusInputValue = 0x18; 1323c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1324c2906f47SBrandon Wyman { 1325b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 132682affd94SBrandon Wyman // If there is a VIN_UV fault, fake reading voltage of less than 20V 132782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 132882affd94SBrandon Wyman .Times(1) 132982affd94SBrandon Wyman .WillOnce(Return("19876")); 13300975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 13310975eaf4SMatt Spinler { 13320975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 13330975eaf4SMatt Spinler } 13343f1242f3SBrandon Wyman psu.analyze(); 1335c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 1336c2906f47SBrandon Wyman } 1337f07bc797SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1338b654c619SBrandon Wyman expectations.statusWordValue = 0; 1339b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 134082affd94SBrandon Wyman // Updates now result in clearing faults if read voltage goes from below the 134182affd94SBrandon Wyman // minimum, to within a valid range. 134282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 134382affd94SBrandon Wyman .Times(1) 134482affd94SBrandon Wyman .WillOnce(Return("201300")); 13453225a45cSBrandon Wyman // Went from below minimum to within range, expect clearVinUVFault(). 13463225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 13473225a45cSBrandon Wyman .Times(1) 13483225a45cSBrandon Wyman .WillOnce(Return(1)); 13490975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 13503f1242f3SBrandon Wyman psu.analyze(); 13513f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 13523f1242f3SBrandon Wyman } 13536710ba2cSBrandon Wyman 13546710ba2cSBrandon Wyman TEST_F(PowerSupplyTests, HasVoutOVFault) 13556710ba2cSBrandon Wyman { 13566710ba2cSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 13576710ba2cSBrandon Wyman 1358c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1359c3324424SBrandon Wyman 0x69, "ibm-cffps", PSUGPIOLineName}; 13606710ba2cSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 13616710ba2cSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 13626710ba2cSBrandon Wyman // Always return 1 to indicate present. 13636710ba2cSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 13646710ba2cSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1365391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1366ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1367ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1368ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1369ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1370ae35ac5dSBrandon Wyman .Times(1) 1371ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 13726710ba2cSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1373b654c619SBrandon Wyman PMBusExpectations expectations; 1374b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 137582affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 137682affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 137782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 137882affd94SBrandon Wyman .Times(1) 137982affd94SBrandon Wyman .WillOnce(Return("202100")); 13806710ba2cSBrandon Wyman psu.analyze(); 13816710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 13826710ba2cSBrandon Wyman // Turn fault on. 1383b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_OV_FAULT); 13846710ba2cSBrandon Wyman // STATUS_VOUT fault bit(s) 1385b654c619SBrandon Wyman expectations.statusVOUTValue = 0x80; 1386c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1387c2906f47SBrandon Wyman { 1388b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 138982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 139082affd94SBrandon Wyman .Times(1) 139182affd94SBrandon Wyman .WillOnce(Return("202200")); 13926710ba2cSBrandon Wyman psu.analyze(); 1393c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 1394c2906f47SBrandon Wyman } 13956710ba2cSBrandon Wyman // Back to no fault bits on in STATUS_WORD 1396b654c619SBrandon Wyman expectations.statusWordValue = 0; 1397b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 139882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 139982affd94SBrandon Wyman .Times(1) 140082affd94SBrandon Wyman .WillOnce(Return("202300")); 14016710ba2cSBrandon Wyman psu.analyze(); 14026710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 14036710ba2cSBrandon Wyman } 140496893a46SBrandon Wyman 1405b10b3be0SBrandon Wyman TEST_F(PowerSupplyTests, HasIoutOCFault) 1406b10b3be0SBrandon Wyman { 1407b10b3be0SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1408b10b3be0SBrandon Wyman 1409c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1410c3324424SBrandon Wyman 0x6d, "ibm-cffps", PSUGPIOLineName}; 1411b10b3be0SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1412b10b3be0SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1413b10b3be0SBrandon Wyman // Always return 1 to indicate present. 1414b10b3be0SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1415b10b3be0SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1416391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1417ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1418ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1419ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1420ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1421ae35ac5dSBrandon Wyman .Times(1) 1422ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1423b10b3be0SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1424b10b3be0SBrandon Wyman PMBusExpectations expectations; 1425b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 142682affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 142782affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 142882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 142982affd94SBrandon Wyman .Times(1) 143082affd94SBrandon Wyman .WillOnce(Return("203100")); 1431b10b3be0SBrandon Wyman psu.analyze(); 1432b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1433b10b3be0SBrandon Wyman // Turn fault on. 1434b10b3be0SBrandon Wyman expectations.statusWordValue = status_word::IOUT_OC_FAULT; 1435b10b3be0SBrandon Wyman // STATUS_IOUT fault bit(s) 1436b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0x88; 1437c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1438c2906f47SBrandon Wyman { 1439b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 144082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 144182affd94SBrandon Wyman .Times(1) 144282affd94SBrandon Wyman .WillOnce(Return("203200")); 14430975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 14440975eaf4SMatt Spinler { 14450975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 14460975eaf4SMatt Spinler } 1447b10b3be0SBrandon Wyman psu.analyze(); 1448c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 1449c2906f47SBrandon Wyman } 1450b10b3be0SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1451b10b3be0SBrandon Wyman expectations.statusWordValue = 0; 1452b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 145382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 145482affd94SBrandon Wyman .Times(1) 145582affd94SBrandon Wyman .WillOnce(Return("203300")); 14560975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1457b10b3be0SBrandon Wyman psu.analyze(); 1458b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1459b10b3be0SBrandon Wyman } 1460b10b3be0SBrandon Wyman 14612cf46945SBrandon Wyman TEST_F(PowerSupplyTests, HasVoutUVFault) 14622cf46945SBrandon Wyman { 14632cf46945SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 14642cf46945SBrandon Wyman 1465c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1466c3324424SBrandon Wyman 0x6a, "ibm-cffps", PSUGPIOLineName}; 14672cf46945SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 14682cf46945SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 14692cf46945SBrandon Wyman // Always return 1 to indicate present. 14702cf46945SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 14712cf46945SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1472391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1473ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1474ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1475ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1476ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1477ae35ac5dSBrandon Wyman .Times(1) 1478ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 1479391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 14802cf46945SBrandon Wyman PMBusExpectations expectations; 14812cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 148282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 148382affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 148482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 148582affd94SBrandon Wyman .Times(1) 148682affd94SBrandon Wyman .WillOnce(Return("204100")); 14872cf46945SBrandon Wyman psu.analyze(); 14882cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 14892cf46945SBrandon Wyman // Turn fault on. 14902cf46945SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_FAULT); 14912cf46945SBrandon Wyman // STATUS_VOUT fault bit(s) 14922cf46945SBrandon Wyman expectations.statusVOUTValue = 0x30; 1493c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1494c2906f47SBrandon Wyman { 14952cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 149682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 149782affd94SBrandon Wyman .Times(1) 149882affd94SBrandon Wyman .WillOnce(Return("204200")); 14992cf46945SBrandon Wyman psu.analyze(); 1500c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), x >= DEGLITCH_LIMIT); 1501c2906f47SBrandon Wyman } 15022cf46945SBrandon Wyman // Back to no fault bits on in STATUS_WORD 15032cf46945SBrandon Wyman expectations.statusWordValue = 0; 15042cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 150582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 150682affd94SBrandon Wyman .Times(1) 150782affd94SBrandon Wyman .WillOnce(Return("204300")); 15082cf46945SBrandon Wyman psu.analyze(); 15092cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 15102cf46945SBrandon Wyman } 15112cf46945SBrandon Wyman 15127ee4d7e4SBrandon Wyman TEST_F(PowerSupplyTests, HasFanFault) 15137ee4d7e4SBrandon Wyman { 15147ee4d7e4SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 15157ee4d7e4SBrandon Wyman 15160975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1); 15170975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0); 15180975eaf4SMatt Spinler 1519c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1520c3324424SBrandon Wyman 0x6d, "ibm-cffps", PSUGPIOLineName}; 15217ee4d7e4SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 15227ee4d7e4SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 15237ee4d7e4SBrandon Wyman // Always return 1 to indicate present. 15247ee4d7e4SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 15257ee4d7e4SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1526391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1527ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1528ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1529ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1530ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1531ae35ac5dSBrandon Wyman .Times(1) 1532ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 15337ee4d7e4SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 15347ee4d7e4SBrandon Wyman PMBusExpectations expectations; 15357ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 153682affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 153782affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 153882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 153982affd94SBrandon Wyman .Times(1) 154082affd94SBrandon Wyman .WillOnce(Return("205100")); 15417ee4d7e4SBrandon Wyman psu.analyze(); 15427ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 15437ee4d7e4SBrandon Wyman // Turn fault on. 15447ee4d7e4SBrandon Wyman expectations.statusWordValue = (status_word::FAN_FAULT); 15457ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 fault bit on (Fan 1 Fault) 15467ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0x80; 1547c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1548c2906f47SBrandon Wyman { 15497ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 155082affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 155182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 155282affd94SBrandon Wyman .Times(1) 155382affd94SBrandon Wyman .WillOnce(Return("205200")); 15547ee4d7e4SBrandon Wyman psu.analyze(); 1555c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 1556c2906f47SBrandon Wyman } 15577ee4d7e4SBrandon Wyman // Back to no fault bits on in STATUS_WORD 15587ee4d7e4SBrandon Wyman expectations.statusWordValue = 0; 15597ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 156082affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 156182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 156282affd94SBrandon Wyman .Times(1) 156382affd94SBrandon Wyman .WillOnce(Return("205300")); 15647ee4d7e4SBrandon Wyman psu.analyze(); 15657ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 15667ee4d7e4SBrandon Wyman } 15677ee4d7e4SBrandon Wyman 156896893a46SBrandon Wyman TEST_F(PowerSupplyTests, HasTempFault) 156996893a46SBrandon Wyman { 157096893a46SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 157196893a46SBrandon Wyman 15720975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1); 15730975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0); 15740975eaf4SMatt Spinler 1575c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1576c3324424SBrandon Wyman 0x6a, "ibm-cffps", PSUGPIOLineName}; 157796893a46SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 157896893a46SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 157996893a46SBrandon Wyman // Always return 1 to indicate present. 158096893a46SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 158196893a46SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1582391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1583ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1584ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1585ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1586ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1587ae35ac5dSBrandon Wyman .Times(1) 1588ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 158996893a46SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 159096893a46SBrandon Wyman PMBusExpectations expectations; 159196893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 159282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 159382affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 159482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 159582affd94SBrandon Wyman .Times(1) 159682affd94SBrandon Wyman .WillOnce(Return("206100")); 159796893a46SBrandon Wyman psu.analyze(); 159896893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 159996893a46SBrandon Wyman // Turn fault on. 160096893a46SBrandon Wyman expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 160196893a46SBrandon Wyman // STATUS_TEMPERATURE fault bit on (OT Fault) 160296893a46SBrandon Wyman expectations.statusTempValue = 0x80; 1603c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1604c2906f47SBrandon Wyman { 160596893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 160682affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 160782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 160882affd94SBrandon Wyman .Times(1) 160982affd94SBrandon Wyman .WillOnce(Return("206200")); 161096893a46SBrandon Wyman psu.analyze(); 1611c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 1612c2906f47SBrandon Wyman } 161396893a46SBrandon Wyman // Back to no fault bits on in STATUS_WORD 161496893a46SBrandon Wyman expectations.statusWordValue = 0; 161596893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 161682affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 161782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 161882affd94SBrandon Wyman .Times(1) 161982affd94SBrandon Wyman .WillOnce(Return("206300")); 162096893a46SBrandon Wyman psu.analyze(); 162196893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 162296893a46SBrandon Wyman } 16232916ea52SBrandon Wyman 16242916ea52SBrandon Wyman TEST_F(PowerSupplyTests, HasPgoodFault) 16252916ea52SBrandon Wyman { 16262916ea52SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 16272916ea52SBrandon Wyman 1628c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1629c3324424SBrandon Wyman 0x6b, "ibm-cffps", PSUGPIOLineName}; 16302916ea52SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 16312916ea52SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 16322916ea52SBrandon Wyman // Always return 1 to indicate present. 16332916ea52SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 16342916ea52SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1635391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1636ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1637ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1638ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1639ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1640ae35ac5dSBrandon Wyman .Times(1) 1641ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 16422916ea52SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 16432916ea52SBrandon Wyman PMBusExpectations expectations; 16442916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 164582affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 164682affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 164782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 164882affd94SBrandon Wyman .Times(1) 164982affd94SBrandon Wyman .WillOnce(Return("207100")); 16502916ea52SBrandon Wyman psu.analyze(); 16512916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 1652391a0690SBrandon Wyman // Setup another expectation of no faults. 1653391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 165482affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 165582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 165682affd94SBrandon Wyman .Times(1) 165782affd94SBrandon Wyman .WillOnce(Return("207200")); 165882affd94SBrandon Wyman psu.analyze(); 165982affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 166082affd94SBrandon Wyman // Setup another expectation of no faults. 166182affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 166282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 166382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 166482affd94SBrandon Wyman .Times(1) 166582affd94SBrandon Wyman .WillOnce(Return("207300")); 1666391a0690SBrandon Wyman psu.analyze(); 1667391a0690SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 16682916ea52SBrandon Wyman // Turn PGOOD# off (fault on). 16692916ea52SBrandon Wyman expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED); 16702916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 167182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 167282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 167382affd94SBrandon Wyman .Times(1) 167482affd94SBrandon Wyman .WillOnce(Return("207400")); 16752916ea52SBrandon Wyman psu.analyze(); 1676*6d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 1 167706ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 167806ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 167982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 168082affd94SBrandon Wyman .Times(1) 168182affd94SBrandon Wyman .WillOnce(Return("207500")); 168206ca4590SBrandon Wyman psu.analyze(); 1683*6d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 2 168406ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 168506ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 168682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 168782affd94SBrandon Wyman .Times(1) 168882affd94SBrandon Wyman .WillOnce(Return("207600")); 168906ca4590SBrandon Wyman psu.analyze(); 1690*6d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 3 1691*6d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 1692*6d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 1693*6d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 1694*6d469fd4SBrandon Wyman .Times(1) 1695*6d469fd4SBrandon Wyman .WillOnce(Return("207700")); 1696*6d469fd4SBrandon Wyman psu.analyze(); 1697*6d469fd4SBrandon Wyman // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 4 1698*6d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 1699*6d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 1700*6d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 1701*6d469fd4SBrandon Wyman .Times(1) 1702*6d469fd4SBrandon Wyman .WillOnce(Return("207800")); 1703*6d469fd4SBrandon Wyman psu.analyze(); 1704*6d469fd4SBrandon Wyman // Expect true. PGOOD_DEGLITCH_LIMIT @ 5 17052916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 17062916ea52SBrandon Wyman // Back to no fault bits on in STATUS_WORD 17072916ea52SBrandon Wyman expectations.statusWordValue = 0; 17082916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 170982affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 171082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 171182affd94SBrandon Wyman .Times(1) 171282affd94SBrandon Wyman .WillOnce(Return("207700")); 17132916ea52SBrandon Wyman psu.analyze(); 17142916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 171582affd94SBrandon Wyman 17162916ea52SBrandon Wyman // Turn OFF bit on 17172916ea52SBrandon Wyman expectations.statusWordValue = (status_word::UNIT_IS_OFF); 17182916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 171982affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 172082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 172182affd94SBrandon Wyman .Times(1) 172282affd94SBrandon Wyman .WillOnce(Return("208100")); 17232916ea52SBrandon Wyman psu.analyze(); 172406ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 172506ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 172682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 172782affd94SBrandon Wyman .Times(1) 172882affd94SBrandon Wyman .WillOnce(Return("208200")); 172906ca4590SBrandon Wyman psu.analyze(); 173006ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 173106ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 173282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 173382affd94SBrandon Wyman .Times(1) 173482affd94SBrandon Wyman .WillOnce(Return("208300")); 173506ca4590SBrandon Wyman psu.analyze(); 1736*6d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 1737*6d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 1738*6d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 1739*6d469fd4SBrandon Wyman .Times(1) 1740*6d469fd4SBrandon Wyman .WillOnce(Return("208400")); 1741*6d469fd4SBrandon Wyman psu.analyze(); 1742*6d469fd4SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 1743*6d469fd4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 1744*6d469fd4SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 1745*6d469fd4SBrandon Wyman .Times(1) 1746*6d469fd4SBrandon Wyman .WillOnce(Return("208500")); 1747*6d469fd4SBrandon Wyman psu.analyze(); 17482916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 17492916ea52SBrandon Wyman // Back to no fault bits on in STATUS_WORD 17502916ea52SBrandon Wyman expectations.statusWordValue = 0; 17512916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 175282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 175382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 175482affd94SBrandon Wyman .Times(1) 1755*6d469fd4SBrandon Wyman .WillOnce(Return("208000")); 17562916ea52SBrandon Wyman psu.analyze(); 17572916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 17582916ea52SBrandon Wyman } 175939ea02bcSBrandon Wyman 176039ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSKillFault) 176139ea02bcSBrandon Wyman { 176239ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1763c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 1764c3324424SBrandon Wyman 0x6d, "ibm-cffps", PSUGPIOLineName}; 176539ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 176639ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 176739ea02bcSBrandon Wyman // Always return 1 to indicate present. 176839ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 176939ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 177082affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1771ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1772ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1773ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1774ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1775ae35ac5dSBrandon Wyman .Times(1) 1776ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 177739ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 177839ea02bcSBrandon Wyman PMBusExpectations expectations; 177939ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 178082affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 178182affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 178282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 178382affd94SBrandon Wyman .Times(1) 178482affd94SBrandon Wyman .WillOnce(Return("208100")); 178539ea02bcSBrandon Wyman psu.analyze(); 178639ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 178739ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 178839ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 178939ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 179039ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1791c2906f47SBrandon Wyman 1792c2906f47SBrandon Wyman // Deglitching faults, false until read the fault bits on up to the limit. 1793c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1794c2906f47SBrandon Wyman { 179539ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 179682affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 179782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 179882affd94SBrandon Wyman .Times(1) 179982affd94SBrandon Wyman .WillOnce(Return("208200")); 18000975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 18010975eaf4SMatt Spinler { 18020975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 18030975eaf4SMatt Spinler } 180439ea02bcSBrandon Wyman psu.analyze(); 1805c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1806c2906f47SBrandon Wyman } 1807c2906f47SBrandon Wyman 180839ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 180939ea02bcSBrandon Wyman expectations.statusWordValue = 0; 181039ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 181182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 181282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 181382affd94SBrandon Wyman .Times(1) 181482affd94SBrandon Wyman .WillOnce(Return("208300")); 18150975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 181639ea02bcSBrandon Wyman psu.analyze(); 181739ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 181839ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 181939ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 182039ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 4 on. 182139ea02bcSBrandon Wyman expectations.statusMFRValue = 0x10; 1822c2906f47SBrandon Wyman 1823c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1824c2906f47SBrandon Wyman { 182539ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 182682affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 182782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 182882affd94SBrandon Wyman .Times(1) 182982affd94SBrandon Wyman .WillOnce(Return("208400")); 18300975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 18310975eaf4SMatt Spinler { 18320975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 18330975eaf4SMatt Spinler } 183439ea02bcSBrandon Wyman psu.analyze(); 1835c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1836c2906f47SBrandon Wyman } 1837c2906f47SBrandon Wyman 183839ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 183939ea02bcSBrandon Wyman expectations.statusWordValue = 0; 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("208500")); 18450975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 184639ea02bcSBrandon Wyman psu.analyze(); 184739ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 184839ea02bcSBrandon Wyman } 184939ea02bcSBrandon Wyman 185039ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPS12VcsFault) 185139ea02bcSBrandon Wyman { 185239ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1853c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 5, 1854c3324424SBrandon Wyman 0x6e, "ibm-cffps", PSUGPIOLineName}; 185539ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 185639ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 185739ea02bcSBrandon Wyman // Always return 1 to indicate present. 185839ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 185939ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 186082affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1861ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1862ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1863ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1864ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1865ae35ac5dSBrandon Wyman .Times(1) 1866ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 186739ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 186839ea02bcSBrandon Wyman PMBusExpectations expectations; 186939ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 187082affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 187182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 187282affd94SBrandon Wyman .Times(1) 187382affd94SBrandon Wyman .WillOnce(Return("209100")); 187439ea02bcSBrandon Wyman psu.analyze(); 187539ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 187639ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 187739ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 187839ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 187939ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1880c2906f47SBrandon Wyman 1881c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1882c2906f47SBrandon Wyman { 188339ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 188482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 188582affd94SBrandon Wyman .Times(1) 188682affd94SBrandon Wyman .WillOnce(Return("209200")); 188739ea02bcSBrandon Wyman psu.analyze(); 1888c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1889c2906f47SBrandon Wyman } 1890c2906f47SBrandon Wyman 189139ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 189239ea02bcSBrandon Wyman expectations.statusWordValue = 0; 189339ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 189482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 189582affd94SBrandon Wyman .Times(1) 189682affd94SBrandon Wyman .WillOnce(Return("209300")); 189739ea02bcSBrandon Wyman psu.analyze(); 189839ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 189939ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 190039ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 190139ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 6 on. 190239ea02bcSBrandon Wyman expectations.statusMFRValue = 0x40; 1903c2906f47SBrandon Wyman 1904c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1905c2906f47SBrandon Wyman { 190639ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 190782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 190882affd94SBrandon Wyman .Times(1) 190982affd94SBrandon Wyman .WillOnce(Return("209400")); 191039ea02bcSBrandon Wyman psu.analyze(); 1911c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1912c2906f47SBrandon Wyman } 1913c2906f47SBrandon Wyman 191439ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 191539ea02bcSBrandon Wyman expectations.statusWordValue = 0; 191639ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 191782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 191882affd94SBrandon Wyman .Times(1) 191982affd94SBrandon Wyman .WillOnce(Return("209500")); 192039ea02bcSBrandon Wyman psu.analyze(); 192139ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 192239ea02bcSBrandon Wyman } 192339ea02bcSBrandon Wyman 192439ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSCS12VFault) 192539ea02bcSBrandon Wyman { 192639ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1927c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 6, 1928c3324424SBrandon Wyman 0x6f, "ibm-cffps", PSUGPIOLineName}; 192939ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 193039ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 193139ea02bcSBrandon Wyman // Always return 1 to indicate present. 193239ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 193339ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 193482affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1935ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 1936ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 1937ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 1938ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 1939ae35ac5dSBrandon Wyman .Times(1) 1940ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 194139ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 194239ea02bcSBrandon Wyman PMBusExpectations expectations; 194339ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 194482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 194582affd94SBrandon Wyman .Times(1) 194682affd94SBrandon Wyman .WillOnce(Return("209100")); 194739ea02bcSBrandon Wyman psu.analyze(); 194839ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 194939ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 195039ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 195139ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 195239ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1953c2906f47SBrandon Wyman 1954c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1955c2906f47SBrandon Wyman { 195639ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 195782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 195882affd94SBrandon Wyman .Times(1) 195982affd94SBrandon Wyman .WillOnce(Return("209200")); 196039ea02bcSBrandon Wyman psu.analyze(); 1961c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1962c2906f47SBrandon Wyman } 1963c2906f47SBrandon Wyman 196439ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 196539ea02bcSBrandon Wyman expectations.statusWordValue = 0; 196639ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 196782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 196882affd94SBrandon Wyman .Times(1) 196982affd94SBrandon Wyman .WillOnce(Return("209300")); 197039ea02bcSBrandon Wyman psu.analyze(); 197139ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 197239ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 197339ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 197439ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 7 on. 197539ea02bcSBrandon Wyman expectations.statusMFRValue = 0x80; 1976c2906f47SBrandon Wyman 1977c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1978c2906f47SBrandon Wyman { 197939ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 198082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 198182affd94SBrandon Wyman .Times(1) 198282affd94SBrandon Wyman .WillOnce(Return("209400")); 198339ea02bcSBrandon Wyman psu.analyze(); 1984c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1985c2906f47SBrandon Wyman } 1986c2906f47SBrandon Wyman 198739ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 198839ea02bcSBrandon Wyman expectations.statusWordValue = 0; 198939ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 199082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 199182affd94SBrandon Wyman .Times(1) 199282affd94SBrandon Wyman .WillOnce(Return("209500")); 199339ea02bcSBrandon Wyman psu.analyze(); 199439ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 199539ea02bcSBrandon Wyman } 1996c3324424SBrandon Wyman 1997c3324424SBrandon Wyman TEST_F(PowerSupplyTests, SetupInputHistory) 1998c3324424SBrandon Wyman { 1999c3324424SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2000c3324424SBrandon Wyman { 2001c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 6, 2002c3324424SBrandon Wyman 0x6f, "ibm-cffps", PSUGPIOLineName}; 2003c3324424SBrandon Wyman // Defaults to not present due to constructor and mock ordering. 2004c3324424SBrandon Wyman psu.setupInputHistory(); 2005c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2006c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 2007c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 2008ae35ac5dSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2009c3324424SBrandon Wyman // Always return 1 to indicate present. 2010c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 2011ae35ac5dSBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2012ae35ac5dSBrandon Wyman PMBusExpectations expectations; 2013ae35ac5dSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2014ae35ac5dSBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 2015ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2016ae35ac5dSBrandon Wyman .Times(1) 2017ae35ac5dSBrandon Wyman .WillOnce(Return("206000")); 2018ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 2019ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 2020ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 2021ae35ac5dSBrandon Wyman /// Also called when I redo setupInputHistory(). 2022ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2023ae35ac5dSBrandon Wyman .Times(2) 2024ae35ac5dSBrandon Wyman .WillRepeatedly(Return("2000")); 2025ae35ac5dSBrandon Wyman // Call to analyze() and above expectations to get missing/present and 2026ae35ac5dSBrandon Wyman // good status. 2027c3324424SBrandon Wyman psu.analyze(); 2028c3324424SBrandon Wyman psu.setupInputHistory(); 2029c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2030c3324424SBrandon Wyman } 2031c3324424SBrandon Wyman { 2032ae35ac5dSBrandon Wyman // Workaround - Disable INPUT_HISTORY collection if 1400W 2033ae35ac5dSBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 2034ae35ac5dSBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 2035ae35ac5dSBrandon Wyman // Defaults to not present due to constructor and mock ordering. 2036ae35ac5dSBrandon Wyman psu.setupInputHistory(); 2037ae35ac5dSBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2038ae35ac5dSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 2039ae35ac5dSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 2040ae35ac5dSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2041ae35ac5dSBrandon Wyman // Always return 1 to indicate present. 2042ae35ac5dSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 2043ae35ac5dSBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2044ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 2045ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 2046ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate 1400W IBM value, unsupported. 2047ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2048ae35ac5dSBrandon Wyman .Times(2) 2049ae35ac5dSBrandon Wyman .WillRepeatedly(Return("30725")); 2050ae35ac5dSBrandon Wyman PMBusExpectations expectations; 2051ae35ac5dSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2052ae35ac5dSBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 2053ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2054ae35ac5dSBrandon Wyman .Times(1) 2055ae35ac5dSBrandon Wyman .WillOnce(Return("206000")); 2056ae35ac5dSBrandon Wyman // Call to analyze() and above expectations to get missing/present and 2057ae35ac5dSBrandon Wyman // good status. 2058ae35ac5dSBrandon Wyman psu.analyze(); 2059ae35ac5dSBrandon Wyman psu.setupInputHistory(); 2060ae35ac5dSBrandon Wyman // After updating to present, and retrying setup, expect ibm-cffps with 2061ae35ac5dSBrandon Wyman // 1400W to still not support INPUT_HISTORY. 2062ae35ac5dSBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2063ae35ac5dSBrandon Wyman } 2064ae35ac5dSBrandon Wyman { 2065c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 11, 2066c3324424SBrandon Wyman 0x58, "inspur-ipsps", PSUGPIOLineName}; 2067c3324424SBrandon Wyman // Defaults to not present due to constructor and mock ordering. 2068c3324424SBrandon Wyman psu.setupInputHistory(); 2069c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2070c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 2071c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 2072ae35ac5dSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2073c3324424SBrandon Wyman // Always return 1 to indicate present. 2074c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 2075ae35ac5dSBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2076ae35ac5dSBrandon Wyman PMBusExpectations expectations; 2077ae35ac5dSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2078ae35ac5dSBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 2079ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2080ae35ac5dSBrandon Wyman .Times(1) 2081ae35ac5dSBrandon Wyman .WillOnce(Return("206000")); 2082ae35ac5dSBrandon Wyman // Call to analyze() and above expectations to get missing/present and 2083ae35ac5dSBrandon Wyman // good status. 2084c3324424SBrandon Wyman psu.analyze(); 2085c3324424SBrandon Wyman psu.setupInputHistory(); 2086c3324424SBrandon Wyman // After updating to present, and retrying setup, expect inspur-ipsps to 2087c3324424SBrandon Wyman // still not support INPUT_HISTORY. 2088c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2089c3324424SBrandon Wyman } 2090c3324424SBrandon Wyman } 2091c3324424SBrandon Wyman 2092c3324424SBrandon Wyman TEST_F(PowerSupplyTests, UpdateHistory) 2093c3324424SBrandon Wyman { 2094c3324424SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2095c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 7, 2096c3324424SBrandon Wyman 0x6e, "ibm-cffps", PSUGPIOLineName}; 2097c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 2098c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 0); 2099c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 2100c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 2101c3324424SBrandon Wyman // Always return 1 to indicate present. 2102c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 2103c3324424SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2104c3324424SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2105ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 2106ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 2107ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 2108ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2109ae35ac5dSBrandon Wyman .Times(1) 2110ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 2111c3324424SBrandon Wyman PMBusExpectations expectations; 2112c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2113c3324424SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 2114c3324424SBrandon Wyman .Times(6) 2115c3324424SBrandon Wyman .WillRepeatedly(Return("205000")); 2116c3324424SBrandon Wyman EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 2117c3324424SBrandon Wyman // First read after missing/present will have no data. 2118c3324424SBrandon Wyman std::vector<uint8_t> emptyHistory{}; 2119c3324424SBrandon Wyman // Second read, after about 30 seconds, should have a record. 5-bytes. 2120c3324424SBrandon Wyman // Sequence Number: 0x00, Average: 0x50 0xf3 (212), Maximum: 0x54 0xf3 (213) 2121c3324424SBrandon Wyman std::vector<uint8_t> firstHistory{0x00, 0x50, 0xf3, 0x54, 0xf3}; 2122c3324424SBrandon Wyman // Third read, after about 60 seconds, should have two records, 10-bytes, 2123c3324424SBrandon Wyman // but only reading 5 bytes, so make sure new/next sequence number 2124c3324424SBrandon Wyman std::vector<uint8_t> secondHistory{0x01, 0x54, 0xf3, 0x58, 0xf3}; 2125c3324424SBrandon Wyman // Fourth read, 3rd sequence number (0x02). 2126c3324424SBrandon Wyman std::vector<uint8_t> thirdHistory{0x02, 0x54, 0xf3, 0x58, 0xf3}; 2127c3324424SBrandon Wyman // Fifth read, out of sequence, clear and insert this one? 2128c3324424SBrandon Wyman std::vector<uint8_t> outseqHistory{0xff, 0x5c, 0xf3, 0x60, 0xf3}; 2129c3324424SBrandon Wyman EXPECT_CALL( 2130c3324424SBrandon Wyman mockPMBus, 2131c3324424SBrandon Wyman readBinary(INPUT_HISTORY, Type::HwmonDeviceDebug, 2132c3324424SBrandon Wyman phosphor::power::history::RecordManager::RAW_RECORD_SIZE)) 2133c3324424SBrandon Wyman .Times(6) 2134c3324424SBrandon Wyman .WillOnce(Return(emptyHistory)) 2135c3324424SBrandon Wyman .WillOnce(Return(firstHistory)) 2136c3324424SBrandon Wyman .WillOnce(Return(secondHistory)) 2137c3324424SBrandon Wyman .WillOnce(Return(thirdHistory)) 2138c3324424SBrandon Wyman .WillOnce(Return(outseqHistory)) 2139c3324424SBrandon Wyman .WillOnce(Return(emptyHistory)); 2140c3324424SBrandon Wyman // Calling analyze will update the presence, which will setup the input 2141c3324424SBrandon Wyman // history if the power supply went from missing to present. 2142c3324424SBrandon Wyman psu.analyze(); 2143c3324424SBrandon Wyman // The ibm-cffps power supply should support input history 2144c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2145c3324424SBrandon Wyman // Usually should have empty buffer right after missing to present. 2146c3324424SBrandon Wyman // Faked that out above with mocked readBinary with emptyHistory data. 2147c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 0); 2148c3324424SBrandon Wyman // Second run through... 2149c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2150c3324424SBrandon Wyman psu.analyze(); 2151c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2152c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 1); 2153c3324424SBrandon Wyman // Third run through 2154c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2155c3324424SBrandon Wyman psu.analyze(); 2156c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2157c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 2); 2158c3324424SBrandon Wyman // Fourth run through. Up to 3 records now? 2159c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2160c3324424SBrandon Wyman psu.analyze(); 2161c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2162c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 3); 2163c3324424SBrandon Wyman // Out of sequencer, reset, insert new one. 2164c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2165c3324424SBrandon Wyman psu.analyze(); 2166c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2167c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 1); 2168c3324424SBrandon Wyman // Empty one after last one good. Reset/clear. 2169c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 2170c3324424SBrandon Wyman psu.analyze(); 2171c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 2172c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 0); 2173c3324424SBrandon Wyman } 217418a24d92SBrandon Wyman 217518a24d92SBrandon Wyman TEST_F(PowerSupplyTests, IsSyncHistoryRequired) 217618a24d92SBrandon Wyman { 217718a24d92SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 217818a24d92SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 8, 217918a24d92SBrandon Wyman 0x6f, "ibm-cffps", PSUGPIOLineName}; 218018a24d92SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 218118a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), false); 218218a24d92SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 218318a24d92SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 218418a24d92SBrandon Wyman // Always return 1 to indicate present. 218518a24d92SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 218618a24d92SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 218718a24d92SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 2188ae35ac5dSBrandon Wyman // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup 2189ae35ac5dSBrandon Wyman // for INPUT_HISTORY will check max_power_out to see if it is 2190ae35ac5dSBrandon Wyman // old/unsupported power supply. Indicate good value, supported. 2191ae35ac5dSBrandon Wyman EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _)) 2192ae35ac5dSBrandon Wyman .Times(1) 2193ae35ac5dSBrandon Wyman .WillOnce(Return("2000")); 219418a24d92SBrandon Wyman PMBusExpectations expectations; 219518a24d92SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 219618a24d92SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 219718a24d92SBrandon Wyman .Times(1) 219818a24d92SBrandon Wyman .WillRepeatedly(Return("205000")); 219918a24d92SBrandon Wyman EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 220018a24d92SBrandon Wyman psu.analyze(); 220118a24d92SBrandon Wyman // The ibm-cffps power supply should support input history 220218a24d92SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 220318a24d92SBrandon Wyman // Missing -> Present requires history sync 220418a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), true); 220518a24d92SBrandon Wyman psu.clearSyncHistoryRequired(); 220618a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), false); 220718a24d92SBrandon Wyman } 2208