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); 259b654c619SBrandon Wyman 260b654c619SBrandon Wyman // STATUS_WORD INPUT fault. 261b654c619SBrandon Wyman { 262b654c619SBrandon Wyman // Start with STATUS_WORD 0x0000. Powered on, no faults. 263b654c619SBrandon Wyman // Set expectations for a no fault 264b654c619SBrandon Wyman PMBusExpectations expectations; 265b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 26682affd94SBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 26782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 26882affd94SBrandon Wyman .Times(1) 26982affd94SBrandon Wyman .WillOnce(Return("206000")); 2703f1242f3SBrandon Wyman psu2.analyze(); 2713f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2723f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 2733f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 2743f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 2753f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 27685c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 2776710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 278b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 2792cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 2807ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 28196893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 2822916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 28339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 28439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 28539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 2863f1242f3SBrandon Wyman 287b654c619SBrandon Wyman // Update expectations for STATUS_WORD input fault/warn 28896893a46SBrandon Wyman // STATUS_INPUT fault bits ... on. 289b654c619SBrandon Wyman expectations.statusWordValue = (status_word::INPUT_FAULT_WARN); 2903225a45cSBrandon Wyman // IIN_OC fault. 2913225a45cSBrandon Wyman expectations.statusInputValue = 0x04; 292c2906f47SBrandon Wyman 293c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 294c2906f47SBrandon Wyman { 295b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 29682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 29782affd94SBrandon Wyman .Times(1) 29882affd94SBrandon Wyman .WillOnce(Return("207000")); 2993f1242f3SBrandon Wyman psu2.analyze(); 3003f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 301c2906f47SBrandon Wyman // Should not be faulted until it reaches the deglitch limit. 302c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 303c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT); 3043f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 3053f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 30685c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 3076710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 308b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 3092cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 3107ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 31196893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 3122916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 31339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 31439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 31539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 316b654c619SBrandon Wyman } 317c2906f47SBrandon Wyman } 318c2906f47SBrandon Wyman 31932453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 3203225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 3213225a45cSBrandon Wyman .Times(1) 3223225a45cSBrandon Wyman .WillOnce(Return(1)); 323c2906f47SBrandon Wyman psu2.clearFaults(); 3243f1242f3SBrandon Wyman 3253f1242f3SBrandon Wyman // STATUS_WORD INPUT/UV fault. 326b654c619SBrandon Wyman { 3273f1242f3SBrandon Wyman // First need it to return good status, then the fault 328b654c619SBrandon Wyman PMBusExpectations expectations; 329b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 33082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 33182affd94SBrandon Wyman .Times(1) 33282affd94SBrandon Wyman .WillOnce(Return("208000")); 3333f1242f3SBrandon Wyman psu2.analyze(); 334c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 335c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 3368da35c51SBrandon Wyman // Now set fault bits in STATUS_WORD 337b654c619SBrandon Wyman expectations.statusWordValue = 3388da35c51SBrandon Wyman (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT); 3398da35c51SBrandon Wyman // STATUS_INPUT fault bits ... on. 3403225a45cSBrandon Wyman expectations.statusInputValue = 0x18; 341c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 342c2906f47SBrandon Wyman { 343b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 34482affd94SBrandon Wyman // Input/UV fault, so voltage should read back low. 34582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 34682affd94SBrandon Wyman .Times(1) 34782affd94SBrandon Wyman .WillOnce(Return("19123")); 3483f1242f3SBrandon Wyman psu2.analyze(); 3493f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 350c2906f47SBrandon Wyman // Only faulted if hit deglitch limit 351c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 352c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT); 353c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), x >= DEGLITCH_LIMIT); 3543f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 35585c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 3566710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 357b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 3582cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 3597ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 36096893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 3612916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 36239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 36339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 36439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 365c2906f47SBrandon Wyman } 36682affd94SBrandon Wyman // Turning VIN_UV fault off causes clearing of faults, causing read of 36782affd94SBrandon Wyman // in1_input as an attempt to get CLEAR_FAULTS called. 36882affd94SBrandon Wyman expectations.statusWordValue = 0; 36982affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 37082affd94SBrandon Wyman // The call to read the voltage 37182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 37282affd94SBrandon Wyman .Times(1) 37382affd94SBrandon Wyman .WillOnce(Return("209000")); 3743225a45cSBrandon Wyman // The call to clear VIN_UV/Off fault(s) 3753225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 37632453e9bSBrandon Wyman .Times(1) 3773225a45cSBrandon Wyman .WillOnce(Return(1)); 37882affd94SBrandon Wyman psu2.analyze(); 37982affd94SBrandon Wyman // Should remain present, no longer be faulted, no input fault, no 38082affd94SBrandon Wyman // VIN_UV fault. Nothing else should change. 38182affd94SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 38282affd94SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 38382affd94SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 38482affd94SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 385b654c619SBrandon Wyman } 3863f1242f3SBrandon Wyman 38732453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 3883225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 3893225a45cSBrandon Wyman .Times(1) 3903225a45cSBrandon Wyman .WillOnce(Return(1)); 391c2906f47SBrandon Wyman psu2.clearFaults(); 392c2906f47SBrandon Wyman 3933f1242f3SBrandon Wyman // STATUS_WORD MFR fault. 394b654c619SBrandon Wyman { 395f07bc797SBrandon Wyman // First need it to return good status, then the fault 396b654c619SBrandon Wyman PMBusExpectations expectations; 397b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 39882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 39982affd94SBrandon Wyman .Times(1) 40082affd94SBrandon Wyman .WillOnce(Return("210000")); 4013f1242f3SBrandon Wyman psu2.analyze(); 4028da35c51SBrandon Wyman // Now STATUS_WORD with MFR fault bit on. 403b654c619SBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 4048da35c51SBrandon Wyman // STATUS_MFR bits on. 405b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 406c2906f47SBrandon Wyman 407c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 408c2906f47SBrandon Wyman { 409b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 41082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 41182affd94SBrandon Wyman .Times(1) 41282affd94SBrandon Wyman .WillOnce(Return("211000")); 4133f1242f3SBrandon Wyman psu2.analyze(); 4143f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 415c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 4163f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 417c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), x >= DEGLITCH_LIMIT); 418c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), x >= DEGLITCH_LIMIT); 419c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 420c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 4213f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 42285c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 4236710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 424b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 4252cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 4267ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 42796893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 4282916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 429c2906f47SBrandon Wyman } 430b654c619SBrandon Wyman } 4313f1242f3SBrandon Wyman 43232453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 4333225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 4343225a45cSBrandon Wyman .Times(1) 4353225a45cSBrandon Wyman .WillOnce(Return(1)); 436c2906f47SBrandon Wyman psu2.clearFaults(); 4373225a45cSBrandon Wyman 43896893a46SBrandon Wyman // Temperature fault. 439b654c619SBrandon Wyman { 440f07bc797SBrandon Wyman // First STATUS_WORD with no bits set, then with temperature fault. 441b654c619SBrandon Wyman PMBusExpectations expectations; 442b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 44382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 44482affd94SBrandon Wyman .Times(1) 44582affd94SBrandon Wyman .WillOnce(Return("212000")); 4463f1242f3SBrandon Wyman psu2.analyze(); 4478da35c51SBrandon Wyman // STATUS_WORD with temperature fault bit on. 448b654c619SBrandon Wyman expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 44996893a46SBrandon Wyman // STATUS_TEMPERATURE with fault bit(s) on. 45096893a46SBrandon Wyman expectations.statusTempValue = 0x10; 451c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 452c2906f47SBrandon Wyman { 453b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 45482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 45582affd94SBrandon Wyman .Times(1) 45682affd94SBrandon Wyman .WillOnce(Return("213000")); 4573f1242f3SBrandon Wyman psu2.analyze(); 4583f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 459c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 4603f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 4613f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 4623f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 46385c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 4646710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 465b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 4662cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 4677ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 468c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), x >= DEGLITCH_LIMIT); 4692916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 47039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 47139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 47239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 473b654c619SBrandon Wyman } 474c2906f47SBrandon Wyman } 47585c7bf41SBrandon Wyman 47632453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 4773225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 4783225a45cSBrandon Wyman .Times(1) 4793225a45cSBrandon Wyman .WillOnce(Return(1)); 480c2906f47SBrandon Wyman psu2.clearFaults(); 4813225a45cSBrandon Wyman 48285c7bf41SBrandon Wyman // CML fault 483b654c619SBrandon Wyman { 48485c7bf41SBrandon Wyman // First STATUS_WORD wit no bits set, then with CML fault. 485b654c619SBrandon Wyman PMBusExpectations expectations; 486b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 48782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 48882affd94SBrandon Wyman .Times(1) 48982affd94SBrandon Wyman .WillOnce(Return("214000")); 49085c7bf41SBrandon Wyman psu2.analyze(); 4918da35c51SBrandon Wyman // STATUS_WORD with CML fault bit on. 492b654c619SBrandon Wyman expectations.statusWordValue = (status_word::CML_FAULT); 49385c7bf41SBrandon Wyman // Turn on STATUS_CML fault bit(s) 494b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 495c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 496c2906f47SBrandon Wyman { 497b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 49882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 49982affd94SBrandon Wyman .Times(1) 50082affd94SBrandon Wyman .WillOnce(Return("215000")); 50185c7bf41SBrandon Wyman psu2.analyze(); 50285c7bf41SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 503c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 504c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), x >= DEGLITCH_LIMIT); 50585c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 50685c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 50785c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 5086710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 509b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 5102cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 5117ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 51296893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 5132916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 51439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 51539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 51639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 517b654c619SBrandon Wyman } 518c2906f47SBrandon Wyman } 5196710ba2cSBrandon Wyman 52032453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 5213225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 5223225a45cSBrandon Wyman .Times(1) 5233225a45cSBrandon Wyman .WillOnce(Return(1)); 524c2906f47SBrandon Wyman psu2.clearFaults(); 5253225a45cSBrandon Wyman 5266710ba2cSBrandon Wyman // VOUT_OV_FAULT fault 527b654c619SBrandon Wyman { 5286710ba2cSBrandon Wyman // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault. 529b654c619SBrandon Wyman PMBusExpectations expectations; 530b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 53182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 53282affd94SBrandon Wyman .Times(1) 53382affd94SBrandon Wyman .WillOnce(Return("216000")); 5346710ba2cSBrandon Wyman psu2.analyze(); 5356710ba2cSBrandon Wyman // STATUS_WORD with VOUT/VOUT_OV fault. 536b654c619SBrandon Wyman expectations.statusWordValue = 5376710ba2cSBrandon Wyman ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT)); 5386710ba2cSBrandon Wyman // Turn on STATUS_VOUT fault bit(s) 539b654c619SBrandon Wyman expectations.statusVOUTValue = 0xA0; 540c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 541c2906f47SBrandon Wyman { 54296893a46SBrandon Wyman // STATUS_TEMPERATURE don't care (default) 543b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 54482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 54582affd94SBrandon Wyman .Times(1) 54682affd94SBrandon Wyman .WillOnce(Return("217000")); 5476710ba2cSBrandon Wyman psu2.analyze(); 5486710ba2cSBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 549c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 5506710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 5516710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 5526710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 5536710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 554c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 5552cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 556b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 5577ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 558b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 559b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 56039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 56139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 56239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 563b10b3be0SBrandon Wyman } 564c2906f47SBrandon Wyman } 565b10b3be0SBrandon Wyman 566b10b3be0SBrandon Wyman // IOUT_OC_FAULT fault 567b10b3be0SBrandon Wyman { 568b10b3be0SBrandon Wyman // First STATUS_WORD with no bits set, then with IOUT_OC fault. 569b10b3be0SBrandon Wyman PMBusExpectations expectations; 570b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 57182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 57282affd94SBrandon Wyman .Times(1) 57382affd94SBrandon Wyman .WillOnce(Return("218000")); 574b10b3be0SBrandon Wyman psu2.analyze(); 575b10b3be0SBrandon Wyman // STATUS_WORD with IOUT_OC fault. 576b10b3be0SBrandon Wyman expectations.statusWordValue = status_word::IOUT_OC_FAULT; 577b10b3be0SBrandon Wyman // Turn on STATUS_IOUT fault bit(s) 578b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0x88; 579c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 580c2906f47SBrandon Wyman { 581b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 58282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 58382affd94SBrandon Wyman .Times(1) 58482affd94SBrandon Wyman .WillOnce(Return("219000")); 585b10b3be0SBrandon Wyman psu2.analyze(); 586b10b3be0SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 587c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 588b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 589b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 590b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 591b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 592b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 593c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 5942cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 5957ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 5962cf46945SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 5972cf46945SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 59839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 59939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 60039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 6012cf46945SBrandon Wyman } 602c2906f47SBrandon Wyman } 6032cf46945SBrandon Wyman 6042cf46945SBrandon Wyman // VOUT_UV_FAULT 6052cf46945SBrandon Wyman { 6062cf46945SBrandon Wyman // First STATUS_WORD with no bits set, then with VOUT fault. 6072cf46945SBrandon Wyman PMBusExpectations expectations; 6082cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 60982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 61082affd94SBrandon Wyman .Times(1) 61182affd94SBrandon Wyman .WillOnce(Return("220000")); 6122cf46945SBrandon Wyman psu2.analyze(); 6132cf46945SBrandon Wyman // Change STATUS_WORD to indicate VOUT fault. 6142cf46945SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_FAULT); 6152cf46945SBrandon Wyman // Turn on STATUS_VOUT fault bit(s) 6162cf46945SBrandon Wyman expectations.statusVOUTValue = 0x30; 617c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 618c2906f47SBrandon Wyman { 6192cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 62082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 62182affd94SBrandon Wyman .Times(1) 62282affd94SBrandon Wyman .WillOnce(Return("221000")); 6232cf46945SBrandon Wyman psu2.analyze(); 6242cf46945SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 625c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 6262cf46945SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 6272cf46945SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 6282cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 6292cf46945SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 6302cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 6312cf46945SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 632c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), x >= DEGLITCH_LIMIT); 6337ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 63496893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6352916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 63639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 63739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 63839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 639b654c619SBrandon Wyman } 640c2906f47SBrandon Wyman } 6413f1242f3SBrandon Wyman 6427ee4d7e4SBrandon Wyman // Fan fault 643b654c619SBrandon Wyman { 644b654c619SBrandon Wyman // First STATUS_WORD with no bits set, then with fan fault. 645b654c619SBrandon Wyman PMBusExpectations expectations; 646b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 64782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 64882affd94SBrandon Wyman .Times(1) 64982affd94SBrandon Wyman .WillOnce(Return("222000")); 6503f1242f3SBrandon Wyman psu2.analyze(); 651b654c619SBrandon Wyman expectations.statusWordValue = (status_word::FAN_FAULT); 6527ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with fan 1 warning & fault bits on. 6537ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xA0; 654c2906f47SBrandon Wyman 655c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 656c2906f47SBrandon Wyman { 657b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 65882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 65982affd94SBrandon Wyman .Times(1) 66082affd94SBrandon Wyman .WillOnce(Return("223000")); 6613f1242f3SBrandon Wyman psu2.analyze(); 6623f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 663c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 664c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), x >= DEGLITCH_LIMIT); 6653f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 6663f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 6673f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 66885c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 6696710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 670b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 6712cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 67296893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6732916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 67439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 67539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 67639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 677b654c619SBrandon Wyman } 678c2906f47SBrandon Wyman } 6792916ea52SBrandon Wyman 68006ca4590SBrandon Wyman // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT. 6812cf46945SBrandon Wyman { 6822916ea52SBrandon Wyman // First STATUS_WORD with no bits set. 6832916ea52SBrandon Wyman PMBusExpectations expectations; 6842916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 68582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 68682affd94SBrandon Wyman .Times(1) 68782affd94SBrandon Wyman .WillOnce(Return("123000")); 6882916ea52SBrandon Wyman psu2.analyze(); 6892916ea52SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 6902916ea52SBrandon Wyman // POWER_GOOD# inactive, and OFF bit on. 6912916ea52SBrandon Wyman expectations.statusWordValue = 6922916ea52SBrandon Wyman ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF)); 69306ca4590SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 69406ca4590SBrandon Wyman { 6952916ea52SBrandon Wyman // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and 6962916ea52SBrandon Wyman // STATUS_TEMPERATURE: Don't care if bits set or not (defaults). 6972916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 69882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 69982affd94SBrandon Wyman .Times(1) 70082affd94SBrandon Wyman .WillOnce(Return("124000")); 7012916ea52SBrandon Wyman psu2.analyze(); 7022916ea52SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 703c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 7042916ea52SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 7052916ea52SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 7062916ea52SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 7072916ea52SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 7082916ea52SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 7092cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 710b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 7117ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 7122916ea52SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 71332453e9bSBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), x >= DEGLITCH_LIMIT); 71406ca4590SBrandon Wyman } 71506ca4590SBrandon Wyman } 7162916ea52SBrandon Wyman 7173f1242f3SBrandon Wyman // TODO: ReadFailure 7183f1242f3SBrandon Wyman } 7193f1242f3SBrandon Wyman 72059a35793SBrandon Wyman TEST_F(PowerSupplyTests, OnOffConfig) 72159a35793SBrandon Wyman { 72259a35793SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 72359a35793SBrandon Wyman uint8_t data = 0x15; 72459a35793SBrandon Wyman 72559a35793SBrandon Wyman // Test where PSU is NOT present 72659a35793SBrandon Wyman try 72759a35793SBrandon Wyman { 728681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 7290975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, _)).Times(0); 730c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 731c3324424SBrandon Wyman 0x69, "ibm-cffps", PSUGPIOLineName}; 732681b2a36SB. J. Wyman 7333ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7343ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 735681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0)); 73659a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 737681b2a36SB. J. Wyman // Constructor should set initial presence, default read returns 0. 73859a35793SBrandon Wyman // If it is not present, I should not be trying to write to it. 73959a35793SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0); 74059a35793SBrandon Wyman psu.onOffConfig(data); 74159a35793SBrandon Wyman } 74259a35793SBrandon Wyman catch (...) 7430c9a33d6SAdriana Kobylak {} 74459a35793SBrandon Wyman 74559a35793SBrandon Wyman // Test where PSU is present 74659a35793SBrandon Wyman try 74759a35793SBrandon Wyman { 748681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 7490975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 750c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 5, 751c3324424SBrandon Wyman 0x6a, "ibm-cffps", PSUGPIOLineName}; 7523ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7533ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 754391a0690SBrandon Wyman // There will potentially be multiple calls, we want it to continue 755391a0690SBrandon Wyman // returning 1 for the GPIO read to keep the power supply present. 756391a0690SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 75759a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 758391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 759391a0690SBrandon Wyman // If I am calling analyze(), I should probably give it good data. 760391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 761391a0690SBrandon Wyman PMBusExpectations expectations; 762391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 76382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 76482affd94SBrandon Wyman .Times(1) 76582affd94SBrandon Wyman .WillOnce(Return("205000")); 766681b2a36SB. J. Wyman psu.analyze(); 767391a0690SBrandon Wyman // I definitely should be writting ON_OFF_CONFIG if I call the function 768391a0690SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, ElementsAre(0x15), 769391a0690SBrandon Wyman Type::HwmonDeviceDebug)) 77059a35793SBrandon Wyman .Times(1); 77159a35793SBrandon Wyman psu.onOffConfig(data); 77259a35793SBrandon Wyman } 77359a35793SBrandon Wyman catch (...) 7740c9a33d6SAdriana Kobylak {} 77559a35793SBrandon Wyman } 77659a35793SBrandon Wyman 7773f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, ClearFaults) 7783f1242f3SBrandon Wyman { 7793f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 780c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 13, 781c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 7823ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7833ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 78406ca4590SBrandon Wyman // Always return 1 to indicate present. 78506ca4590SBrandon Wyman // Each analyze() call will trigger a read of the presence GPIO. 78606ca4590SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 787681b2a36SB. J. Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 788391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 7898da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 790b654c619SBrandon Wyman PMBusExpectations expectations; 791b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 79282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 79382affd94SBrandon Wyman .Times(1) 79482affd94SBrandon Wyman .WillOnce(Return("207000")); 795681b2a36SB. J. Wyman psu.analyze(); 7963f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 7973f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 7983f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 7993f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 8003f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 80185c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 8026710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 803b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 8042cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 8057ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 80696893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 8072916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 80839ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 80939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 81039ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 811b654c619SBrandon Wyman 812f07bc797SBrandon Wyman // STATUS_WORD with fault bits galore! 813b654c619SBrandon Wyman expectations.statusWordValue = 0xFFFF; 814f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 815b654c619SBrandon Wyman expectations.statusInputValue = 0xFF; 816f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 817b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 81885c7bf41SBrandon Wyman // STATUS_CML with bits on. 819b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 8206710ba2cSBrandon Wyman // STATUS_VOUT with bits on. 821b654c619SBrandon Wyman expectations.statusVOUTValue = 0xFF; 822b10b3be0SBrandon Wyman // STATUS_IOUT with bits on. 823b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0xFF; 8247ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with bits on. 8257ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xFF; 82696893a46SBrandon Wyman // STATUS_TEMPERATURE with bits on. 82796893a46SBrandon Wyman expectations.statusTempValue = 0xFF; 828c2906f47SBrandon Wyman 829c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 830c2906f47SBrandon Wyman { 831b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 83282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 83382affd94SBrandon Wyman .Times(1) 83482affd94SBrandon Wyman .WillOnce(Return("0")); 8350975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 8360975eaf4SMatt Spinler { 8370975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 8380975eaf4SMatt Spinler } 8393f1242f3SBrandon Wyman psu.analyze(); 8403f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8412cf46945SBrandon Wyman // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT. 8422cf46945SBrandon Wyman // Rely on HasVoutUVFault() to verify this sets and clears. 8432cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 844c2906f47SBrandon Wyman // All faults are deglitched up to DEGLITCH_LIMIT 845c2906f47SBrandon Wyman EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT); 846c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 847c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 848c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 849c2906f47SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), x >= DEGLITCH_LIMIT); 850c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 851c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 852c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 853c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 854c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), x >= DEGLITCH_LIMIT); 855c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 856c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 857c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 858c2906f47SBrandon Wyman } 859c2906f47SBrandon Wyman 86032453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)) 86132453e9bSBrandon Wyman .Times(1) 86232453e9bSBrandon Wyman .WillOnce(Return(207000)); 8633225a45cSBrandon Wyman // Clearing VIN_UV fault via in1_lcrit_alarm 8643225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 8653225a45cSBrandon Wyman .Times(1) 8663225a45cSBrandon Wyman .WillOnce(Return(1)); 8670975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 8683f1242f3SBrandon Wyman psu.clearFaults(); 8693f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8703f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 8713f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 8723f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 8733f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 87485c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 8756710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 876b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 8772cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 8787ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 87996893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 8802916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 88139ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 88239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 88339ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 884681b2a36SB. J. Wyman 88582affd94SBrandon Wyman // Faults clear on READ_VIN 0 -> !0 88682affd94SBrandon Wyman // STATUS_WORD with fault bits galore! 88782affd94SBrandon Wyman expectations.statusWordValue = 0xFFFF; 88882affd94SBrandon Wyman // STATUS_INPUT with fault bits on. 88982affd94SBrandon Wyman expectations.statusInputValue = 0xFF; 89082affd94SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 89182affd94SBrandon Wyman expectations.statusMFRValue = 0xFF; 89282affd94SBrandon Wyman // STATUS_CML with bits on. 89382affd94SBrandon Wyman expectations.statusCMLValue = 0xFF; 89482affd94SBrandon Wyman // STATUS_VOUT with bits on. 89582affd94SBrandon Wyman expectations.statusVOUTValue = 0xFF; 89682affd94SBrandon Wyman // STATUS_IOUT with bits on. 89782affd94SBrandon Wyman expectations.statusIOUTValue = 0xFF; 89882affd94SBrandon Wyman // STATUS_FANS_1_2 with bits on. 89982affd94SBrandon Wyman expectations.statusFans12Value = 0xFF; 90082affd94SBrandon Wyman // STATUS_TEMPERATURE with bits on. 90182affd94SBrandon Wyman expectations.statusTempValue = 0xFF; 902c2906f47SBrandon Wyman 903c2906f47SBrandon Wyman // All faults degltiched now. Check for false before limit above. 904c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 905c2906f47SBrandon Wyman { 90682affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 90782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 90882affd94SBrandon Wyman .Times(1) 90982affd94SBrandon Wyman .WillOnce(Return("0")); 9100975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 9110975eaf4SMatt Spinler { 9120975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 9130975eaf4SMatt Spinler } 91482affd94SBrandon Wyman psu.analyze(); 915c2906f47SBrandon Wyman } 916c2906f47SBrandon Wyman 91782affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 91882affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 91982affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 92082affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 92182affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 92282affd94SBrandon Wyman // True due to CML fault bits on 92382affd94SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), true); 92482affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 92582affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), true); 92682affd94SBrandon Wyman // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT. 92782affd94SBrandon Wyman // Rely on HasVoutUVFault() to verify this sets and clears. 92882affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 92982affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), true); 93082affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), true); 931c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 93282affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), true); 93382affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), true); 93482affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), true); 93582affd94SBrandon Wyman // STATUS_WORD with INPUT/VIN_UV fault bits off. 93682affd94SBrandon Wyman expectations.statusWordValue = 0xDFF7; 93782affd94SBrandon Wyman // STATUS_INPUT with VIN_UV_WARNING, VIN_UV_FAULT, and Unit Off For 93882affd94SBrandon Wyman // Insufficient Input Voltage bits off. 93982affd94SBrandon Wyman expectations.statusInputValue = 0xC7; 94082affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 94182affd94SBrandon Wyman // READ_VIN back in range. 94282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 94382affd94SBrandon Wyman .Times(1) 94482affd94SBrandon Wyman .WillOnce(Return("206000")); 9453225a45cSBrandon Wyman // VIN_UV cleared via in1_lcrit_alarm when voltage back in range. 9463225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 9473225a45cSBrandon Wyman .Times(1) 9483225a45cSBrandon Wyman .WillOnce(Return(1)); 9493225a45cSBrandon Wyman psu.analyze(); 9503225a45cSBrandon Wyman // We only cleared the VIN_UV and OFF faults. 9513225a45cSBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 9523225a45cSBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 9533225a45cSBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 9543225a45cSBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 9553225a45cSBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 9563225a45cSBrandon Wyman EXPECT_EQ(psu.hasCommFault(), true); 9573225a45cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 9583225a45cSBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), true); 9593225a45cSBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 9603225a45cSBrandon Wyman EXPECT_EQ(psu.hasFanFault(), true); 9613225a45cSBrandon Wyman EXPECT_EQ(psu.hasTempFault(), true); 9623225a45cSBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 9633225a45cSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), true); 9643225a45cSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), true); 9653225a45cSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), true); 9663225a45cSBrandon Wyman 9673225a45cSBrandon Wyman // All faults cleared 9683225a45cSBrandon Wyman expectations = {0}; 9693225a45cSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 9703225a45cSBrandon Wyman // READ_VIN back in range. 9713225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 9723225a45cSBrandon Wyman .Times(1) 9733225a45cSBrandon Wyman .WillOnce(Return("206000")); 9740975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 97582affd94SBrandon Wyman psu.analyze(); 97682affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 97782affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 97882affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 97982affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 98082affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 98182affd94SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 98282affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 98382affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 98482affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 98582affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 98682affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 98782affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 98882affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 98982affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 99082affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 99182affd94SBrandon Wyman 992681b2a36SB. J. Wyman // TODO: Faults clear on missing/present? 9933f1242f3SBrandon Wyman } 9943f1242f3SBrandon Wyman 9953f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory) 9963f1242f3SBrandon Wyman { 9973f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 9981d7a7df8SBrandon Wyman 9991d7a7df8SBrandon Wyman try 10001d7a7df8SBrandon Wyman { 1001c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1002c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 10031d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 10041d7a7df8SBrandon Wyman // If it is not present, I should not be trying to read a string 10051d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).Times(0); 10061d7a7df8SBrandon Wyman psu.updateInventory(); 10071d7a7df8SBrandon Wyman } 10081d7a7df8SBrandon Wyman catch (...) 10091d7a7df8SBrandon Wyman { 10101d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 10111d7a7df8SBrandon Wyman } 10121d7a7df8SBrandon Wyman 10131d7a7df8SBrandon Wyman try 10141d7a7df8SBrandon Wyman { 1015c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 13, 1016c3324424SBrandon Wyman 0x69, "ibm-cffps", PSUGPIOLineName}; 10173ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10183ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1019681b2a36SB. J. Wyman // GPIO read return 1 to indicate present. 1020681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 10211d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1022391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1023391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1024391a0690SBrandon Wyman PMBusExpectations expectations; 1025391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 102682affd94SBrandon Wyman // Call to analyze will read voltage, trigger clear faults for 0 to 102782affd94SBrandon Wyman // within range. 102882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 102982affd94SBrandon Wyman .Times(1) 103082affd94SBrandon Wyman .WillOnce(Return("123456")); 1031391a0690SBrandon Wyman psu.analyze(); 10321d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return("")); 10333f1242f3SBrandon Wyman psu.updateInventory(); 10341d7a7df8SBrandon Wyman 10353c530fbdSBrandon Wyman #if IBM_VPD 10361d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)) 10371d7a7df8SBrandon Wyman .WillOnce(Return("CCIN")) 10381d7a7df8SBrandon Wyman .WillOnce(Return("PN3456")) 10391d7a7df8SBrandon Wyman .WillOnce(Return("FN3456")) 10401d7a7df8SBrandon Wyman .WillOnce(Return("HEADER")) 10411d7a7df8SBrandon Wyman .WillOnce(Return("SN3456")) 10421d7a7df8SBrandon Wyman .WillOnce(Return("FW3456")); 10433c530fbdSBrandon Wyman #endif 10441d7a7df8SBrandon Wyman psu.updateInventory(); 10451d7a7df8SBrandon Wyman // TODO: D-Bus mocking to verify values stored on D-Bus (???) 10461d7a7df8SBrandon Wyman } 10471d7a7df8SBrandon Wyman catch (...) 10481d7a7df8SBrandon Wyman { 10491d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 10501d7a7df8SBrandon Wyman } 10513f1242f3SBrandon Wyman } 10523f1242f3SBrandon Wyman 10533f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent) 10543f1242f3SBrandon Wyman { 10553f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1056681b2a36SB. J. Wyman 1057c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1058c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 10593ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10603ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 10613f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 10623f1242f3SBrandon Wyman 1063681b2a36SB. J. Wyman // Change GPIO read to return 1 to indicate present. 1064681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 1065391a0690SBrandon Wyman // Call to analyze() will update to present, that will trigger updating 1066391a0690SBrandon Wyman // to the correct/latest HWMON directory, in case it changes. 1067391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1068391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1069391a0690SBrandon Wyman // Call to analyze things will trigger read of STATUS_WORD and READ_VIN. 1070391a0690SBrandon Wyman // Default expectations will be on, no faults. 1071391a0690SBrandon Wyman PMBusExpectations expectations; 1072391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 107382affd94SBrandon Wyman // Give it an input voltage in the 100-volt range. 107482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 107582affd94SBrandon Wyman .Times(1) 107682affd94SBrandon Wyman .WillOnce(Return("123456")); 10770975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1078681b2a36SB. J. Wyman psu.analyze(); 1079681b2a36SB. J. Wyman EXPECT_EQ(psu.isPresent(), true); 10803f1242f3SBrandon Wyman } 10813f1242f3SBrandon Wyman 10823f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted) 10833f1242f3SBrandon Wyman { 10843f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1085681b2a36SB. J. Wyman 1086c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 11, 1087c3324424SBrandon Wyman 0x6f, "ibm-cffps", PSUGPIOLineName}; 10883ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10893ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1090681b2a36SB. J. Wyman // Always return 1 to indicate present. 1091681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1092391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1093391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1094391a0690SBrandon Wyman // Call to analyze things will trigger read of STATUS_WORD and READ_VIN. 1095391a0690SBrandon Wyman // Default expectations will be on, no faults. 1096391a0690SBrandon Wyman PMBusExpectations expectations; 1097391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 109882affd94SBrandon Wyman // Give it an input voltage in the 100-volt range. 109982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 110082affd94SBrandon Wyman .Times(1) 110182affd94SBrandon Wyman .WillOnce(Return("124680")); 1102681b2a36SB. J. Wyman psu.analyze(); 11033f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 1104f07bc797SBrandon Wyman // STATUS_WORD with fault bits on. 1105b654c619SBrandon Wyman expectations.statusWordValue = 0xFFFF; 1106f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 1107b654c619SBrandon Wyman expectations.statusInputValue = 0xFF; 1108f07bc797SBrandon Wyman // STATUS_MFR_SPECIFIC with faults bits on. 1109b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 111085c7bf41SBrandon Wyman // STATUS_CML with faults bits on. 1111b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 11126710ba2cSBrandon Wyman // STATUS_VOUT with fault bits on. 1113b654c619SBrandon Wyman expectations.statusVOUTValue = 0xFF; 1114b10b3be0SBrandon Wyman // STATUS_IOUT with fault bits on. 1115b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0xFF; 11167ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with bits on. 11177ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xFF; 111896893a46SBrandon Wyman // STATUS_TEMPERATURE with fault bits on. 111996893a46SBrandon Wyman expectations.statusTempValue = 0xFF; 1120c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1121c2906f47SBrandon Wyman { 1122b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 11234fc191f0SBrandon Wyman // Also get another read of READ_VIN, faulted, so not in 100-volt range 112482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 112582affd94SBrandon Wyman .Times(1) 11264fc191f0SBrandon Wyman .WillOnce(Return("19000")); 11270975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 11280975eaf4SMatt Spinler { 11290975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 11300975eaf4SMatt Spinler } 11313f1242f3SBrandon Wyman psu.analyze(); 1132c2906f47SBrandon Wyman EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT); 1133c2906f47SBrandon Wyman } 11343f1242f3SBrandon Wyman } 11353f1242f3SBrandon Wyman 11363f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasInputFault) 11373f1242f3SBrandon Wyman { 11383f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1139681b2a36SB. J. Wyman 1140c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1141c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 11423ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 11433ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1144681b2a36SB. J. Wyman // Always return 1 to indicate present. 1145681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 11463f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1147391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 11488da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1149b654c619SBrandon Wyman PMBusExpectations expectations; 1150b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 115182affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 115282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 115382affd94SBrandon Wyman .Times(1) 115482affd94SBrandon Wyman .WillOnce(Return("201100")); 11553f1242f3SBrandon Wyman psu.analyze(); 11563f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 1157f07bc797SBrandon Wyman // STATUS_WORD with input fault/warn on. 1158b654c619SBrandon Wyman expectations.statusWordValue = (status_word::INPUT_FAULT_WARN); 1159f07bc797SBrandon Wyman // STATUS_INPUT with an input fault bit on. 1160b654c619SBrandon Wyman expectations.statusInputValue = 0x80; 1161c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1162c2906f47SBrandon Wyman { 1163b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 116482affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 116582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 116682affd94SBrandon Wyman .Times(1) 116782affd94SBrandon Wyman .WillOnce(Return("201200")); 11680975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 11690975eaf4SMatt Spinler { 11700975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 11710975eaf4SMatt Spinler } 11723f1242f3SBrandon Wyman psu.analyze(); 1173c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 1174c2906f47SBrandon Wyman } 1175f07bc797SBrandon Wyman // STATUS_WORD with no bits on. 1176b654c619SBrandon Wyman expectations.statusWordValue = 0; 1177b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 117882affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 117982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 118082affd94SBrandon Wyman .Times(1) 118182affd94SBrandon Wyman .WillOnce(Return("201300")); 11820975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 11833f1242f3SBrandon Wyman psu.analyze(); 11843f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 11853f1242f3SBrandon Wyman } 11863f1242f3SBrandon Wyman 11873f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault) 11883f1242f3SBrandon Wyman { 11893f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1190681b2a36SB. J. Wyman 1191c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1192c3324424SBrandon Wyman 0x68, "ibm-cffps", PSUGPIOLineName}; 11933ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 11943ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1195681b2a36SB. J. Wyman // Always return 1 to indicate present. 1196681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 11973f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1198391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1199f07bc797SBrandon Wyman // First return STATUS_WORD with no bits on. 12008da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1201b654c619SBrandon Wyman PMBusExpectations expectations; 1202b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 120382affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 120482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 120582affd94SBrandon Wyman .Times(1) 120682affd94SBrandon Wyman .WillOnce(Return("202100")); 12073f1242f3SBrandon Wyman psu.analyze(); 12083f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 1209f07bc797SBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 1210b654c619SBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 1211f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 1212b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 1213c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1214c2906f47SBrandon Wyman { 1215b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 121682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 121782affd94SBrandon Wyman .Times(1) 121882affd94SBrandon Wyman .WillOnce(Return("202200")); 12193f1242f3SBrandon Wyman psu.analyze(); 1220c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 1221c2906f47SBrandon Wyman } 1222f07bc797SBrandon Wyman // Back to no bits on in STATUS_WORD 1223b654c619SBrandon Wyman expectations.statusWordValue = 0; 1224b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 122582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 122682affd94SBrandon Wyman .Times(1) 122782affd94SBrandon Wyman .WillOnce(Return("202300")); 12283f1242f3SBrandon Wyman psu.analyze(); 12293f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 12303f1242f3SBrandon Wyman } 12313f1242f3SBrandon Wyman 12323f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault) 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); 124482affd94SBrandon Wyman 124582affd94SBrandon Wyman // Presence change from missing to present will trigger in1_input read in 124682affd94SBrandon Wyman // an attempt to get CLEAR_FAULTS called. Return value ignored. 124782affd94SBrandon Wyman // Zero to non-zero voltage, for missing/present change, triggers clear 124882affd94SBrandon Wyman // faults call again. Return value ignored. 124982affd94SBrandon Wyman // Fault (low voltage) to not faulted (voltage in range) triggers clear 125082affd94SBrandon Wyman // faults call a third time. 125182affd94SBrandon Wyman 12528da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1253b654c619SBrandon Wyman PMBusExpectations expectations; 1254b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 125582affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 125682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 125782affd94SBrandon Wyman .Times(1) 125882affd94SBrandon Wyman .WillOnce(Return("201100")); 12593f1242f3SBrandon Wyman psu.analyze(); 12603f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 1261f07bc797SBrandon Wyman // Turn fault on. 1262b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VIN_UV_FAULT); 126385c7bf41SBrandon Wyman // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by 126485c7bf41SBrandon Wyman // Figure 16, and assume bits on in STATUS_INPUT. 1265b654c619SBrandon Wyman expectations.statusInputValue = 0x18; 1266c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1267c2906f47SBrandon Wyman { 1268b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 126982affd94SBrandon Wyman // If there is a VIN_UV fault, fake reading voltage of less than 20V 127082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 127182affd94SBrandon Wyman .Times(1) 127282affd94SBrandon Wyman .WillOnce(Return("19876")); 12730975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 12740975eaf4SMatt Spinler { 12750975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 12760975eaf4SMatt Spinler } 12773f1242f3SBrandon Wyman psu.analyze(); 1278c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 1279c2906f47SBrandon Wyman } 1280f07bc797SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1281b654c619SBrandon Wyman expectations.statusWordValue = 0; 1282b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 128382affd94SBrandon Wyman // Updates now result in clearing faults if read voltage goes from below the 128482affd94SBrandon Wyman // minimum, to within a valid range. 128582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 128682affd94SBrandon Wyman .Times(1) 128782affd94SBrandon Wyman .WillOnce(Return("201300")); 12883225a45cSBrandon Wyman // Went from below minimum to within range, expect clearVinUVFault(). 12893225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 12903225a45cSBrandon Wyman .Times(1) 12913225a45cSBrandon Wyman .WillOnce(Return(1)); 12920975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 12933f1242f3SBrandon Wyman psu.analyze(); 12943f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 12953f1242f3SBrandon Wyman } 12966710ba2cSBrandon Wyman 12976710ba2cSBrandon Wyman TEST_F(PowerSupplyTests, HasVoutOVFault) 12986710ba2cSBrandon Wyman { 12996710ba2cSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 13006710ba2cSBrandon Wyman 1301c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1302c3324424SBrandon Wyman 0x69, "ibm-cffps", PSUGPIOLineName}; 13036710ba2cSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 13046710ba2cSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 13056710ba2cSBrandon Wyman // Always return 1 to indicate present. 13066710ba2cSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 13076710ba2cSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1308391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 13096710ba2cSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1310b654c619SBrandon Wyman PMBusExpectations expectations; 1311b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 131282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 131382affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 131482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 131582affd94SBrandon Wyman .Times(1) 131682affd94SBrandon Wyman .WillOnce(Return("202100")); 13176710ba2cSBrandon Wyman psu.analyze(); 13186710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 13196710ba2cSBrandon Wyman // Turn fault on. 1320b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_OV_FAULT); 13216710ba2cSBrandon Wyman // STATUS_VOUT fault bit(s) 1322b654c619SBrandon Wyman expectations.statusVOUTValue = 0x80; 1323c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1324c2906f47SBrandon Wyman { 1325b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 132682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 132782affd94SBrandon Wyman .Times(1) 132882affd94SBrandon Wyman .WillOnce(Return("202200")); 13296710ba2cSBrandon Wyman psu.analyze(); 1330c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 1331c2906f47SBrandon Wyman } 13326710ba2cSBrandon Wyman // Back to no fault bits on in STATUS_WORD 1333b654c619SBrandon Wyman expectations.statusWordValue = 0; 1334b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 133582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 133682affd94SBrandon Wyman .Times(1) 133782affd94SBrandon Wyman .WillOnce(Return("202300")); 13386710ba2cSBrandon Wyman psu.analyze(); 13396710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 13406710ba2cSBrandon Wyman } 134196893a46SBrandon Wyman 1342b10b3be0SBrandon Wyman TEST_F(PowerSupplyTests, HasIoutOCFault) 1343b10b3be0SBrandon Wyman { 1344b10b3be0SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1345b10b3be0SBrandon Wyman 1346c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1347c3324424SBrandon Wyman 0x6d, "ibm-cffps", PSUGPIOLineName}; 1348b10b3be0SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1349b10b3be0SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1350b10b3be0SBrandon Wyman // Always return 1 to indicate present. 1351b10b3be0SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1352b10b3be0SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1353391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1354b10b3be0SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1355b10b3be0SBrandon Wyman PMBusExpectations expectations; 1356b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 135782affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 135882affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 135982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 136082affd94SBrandon Wyman .Times(1) 136182affd94SBrandon Wyman .WillOnce(Return("203100")); 1362b10b3be0SBrandon Wyman psu.analyze(); 1363b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1364b10b3be0SBrandon Wyman // Turn fault on. 1365b10b3be0SBrandon Wyman expectations.statusWordValue = status_word::IOUT_OC_FAULT; 1366b10b3be0SBrandon Wyman // STATUS_IOUT fault bit(s) 1367b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0x88; 1368c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1369c2906f47SBrandon Wyman { 1370b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 137182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 137282affd94SBrandon Wyman .Times(1) 137382affd94SBrandon Wyman .WillOnce(Return("203200")); 13740975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 13750975eaf4SMatt Spinler { 13760975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 13770975eaf4SMatt Spinler } 1378b10b3be0SBrandon Wyman psu.analyze(); 1379c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 1380c2906f47SBrandon Wyman } 1381b10b3be0SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1382b10b3be0SBrandon Wyman expectations.statusWordValue = 0; 1383b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 138482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 138582affd94SBrandon Wyman .Times(1) 138682affd94SBrandon Wyman .WillOnce(Return("203300")); 13870975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1388b10b3be0SBrandon Wyman psu.analyze(); 1389b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1390b10b3be0SBrandon Wyman } 1391b10b3be0SBrandon Wyman 13922cf46945SBrandon Wyman TEST_F(PowerSupplyTests, HasVoutUVFault) 13932cf46945SBrandon Wyman { 13942cf46945SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 13952cf46945SBrandon Wyman 1396c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1397c3324424SBrandon Wyman 0x6a, "ibm-cffps", PSUGPIOLineName}; 13982cf46945SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 13992cf46945SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 14002cf46945SBrandon Wyman // Always return 1 to indicate present. 14012cf46945SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 14022cf46945SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1403391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1404391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 14052cf46945SBrandon Wyman PMBusExpectations expectations; 14062cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 140782affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 140882affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 140982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 141082affd94SBrandon Wyman .Times(1) 141182affd94SBrandon Wyman .WillOnce(Return("204100")); 14122cf46945SBrandon Wyman psu.analyze(); 14132cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 14142cf46945SBrandon Wyman // Turn fault on. 14152cf46945SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_FAULT); 14162cf46945SBrandon Wyman // STATUS_VOUT fault bit(s) 14172cf46945SBrandon Wyman expectations.statusVOUTValue = 0x30; 1418c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1419c2906f47SBrandon Wyman { 14202cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 142182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 142282affd94SBrandon Wyman .Times(1) 142382affd94SBrandon Wyman .WillOnce(Return("204200")); 14242cf46945SBrandon Wyman psu.analyze(); 1425c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), x >= DEGLITCH_LIMIT); 1426c2906f47SBrandon Wyman } 14272cf46945SBrandon Wyman // Back to no fault bits on in STATUS_WORD 14282cf46945SBrandon Wyman expectations.statusWordValue = 0; 14292cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 143082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 143182affd94SBrandon Wyman .Times(1) 143282affd94SBrandon Wyman .WillOnce(Return("204300")); 14332cf46945SBrandon Wyman psu.analyze(); 14342cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 14352cf46945SBrandon Wyman } 14362cf46945SBrandon Wyman 14377ee4d7e4SBrandon Wyman TEST_F(PowerSupplyTests, HasFanFault) 14387ee4d7e4SBrandon Wyman { 14397ee4d7e4SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 14407ee4d7e4SBrandon Wyman 14410975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1); 14420975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0); 14430975eaf4SMatt Spinler 1444c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1445c3324424SBrandon Wyman 0x6d, "ibm-cffps", PSUGPIOLineName}; 14467ee4d7e4SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 14477ee4d7e4SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 14487ee4d7e4SBrandon Wyman // Always return 1 to indicate present. 14497ee4d7e4SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 14507ee4d7e4SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1451391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 14527ee4d7e4SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 14537ee4d7e4SBrandon Wyman PMBusExpectations expectations; 14547ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 145582affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 145682affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 145782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 145882affd94SBrandon Wyman .Times(1) 145982affd94SBrandon Wyman .WillOnce(Return("205100")); 14607ee4d7e4SBrandon Wyman psu.analyze(); 14617ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 14627ee4d7e4SBrandon Wyman // Turn fault on. 14637ee4d7e4SBrandon Wyman expectations.statusWordValue = (status_word::FAN_FAULT); 14647ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 fault bit on (Fan 1 Fault) 14657ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0x80; 1466c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1467c2906f47SBrandon Wyman { 14687ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 146982affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 147082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 147182affd94SBrandon Wyman .Times(1) 147282affd94SBrandon Wyman .WillOnce(Return("205200")); 14737ee4d7e4SBrandon Wyman psu.analyze(); 1474c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 1475c2906f47SBrandon Wyman } 14767ee4d7e4SBrandon Wyman // Back to no fault bits on in STATUS_WORD 14777ee4d7e4SBrandon Wyman expectations.statusWordValue = 0; 14787ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 147982affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 148082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 148182affd94SBrandon Wyman .Times(1) 148282affd94SBrandon Wyman .WillOnce(Return("205300")); 14837ee4d7e4SBrandon Wyman psu.analyze(); 14847ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 14857ee4d7e4SBrandon Wyman } 14867ee4d7e4SBrandon Wyman 148796893a46SBrandon Wyman TEST_F(PowerSupplyTests, HasTempFault) 148896893a46SBrandon Wyman { 148996893a46SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 149096893a46SBrandon Wyman 14910975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1); 14920975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0); 14930975eaf4SMatt Spinler 1494c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1495c3324424SBrandon Wyman 0x6a, "ibm-cffps", PSUGPIOLineName}; 149696893a46SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 149796893a46SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 149896893a46SBrandon Wyman // Always return 1 to indicate present. 149996893a46SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 150096893a46SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1501391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 150296893a46SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 150396893a46SBrandon Wyman PMBusExpectations expectations; 150496893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 150582affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 150682affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 150782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 150882affd94SBrandon Wyman .Times(1) 150982affd94SBrandon Wyman .WillOnce(Return("206100")); 151096893a46SBrandon Wyman psu.analyze(); 151196893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 151296893a46SBrandon Wyman // Turn fault on. 151396893a46SBrandon Wyman expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 151496893a46SBrandon Wyman // STATUS_TEMPERATURE fault bit on (OT Fault) 151596893a46SBrandon Wyman expectations.statusTempValue = 0x80; 1516c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1517c2906f47SBrandon Wyman { 151896893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 151982affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 152082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 152182affd94SBrandon Wyman .Times(1) 152282affd94SBrandon Wyman .WillOnce(Return("206200")); 152396893a46SBrandon Wyman psu.analyze(); 1524c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 1525c2906f47SBrandon Wyman } 152696893a46SBrandon Wyman // Back to no fault bits on in STATUS_WORD 152796893a46SBrandon Wyman expectations.statusWordValue = 0; 152896893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 152982affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 153082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 153182affd94SBrandon Wyman .Times(1) 153282affd94SBrandon Wyman .WillOnce(Return("206300")); 153396893a46SBrandon Wyman psu.analyze(); 153496893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 153596893a46SBrandon Wyman } 15362916ea52SBrandon Wyman 15372916ea52SBrandon Wyman TEST_F(PowerSupplyTests, HasPgoodFault) 15382916ea52SBrandon Wyman { 15392916ea52SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 15402916ea52SBrandon Wyman 1541c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 1542c3324424SBrandon Wyman 0x6b, "ibm-cffps", PSUGPIOLineName}; 15432916ea52SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 15442916ea52SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 15452916ea52SBrandon Wyman // Always return 1 to indicate present. 15462916ea52SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 15472916ea52SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1548391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 15492916ea52SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 15502916ea52SBrandon Wyman PMBusExpectations expectations; 15512916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 155282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 155382affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 155482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 155582affd94SBrandon Wyman .Times(1) 155682affd94SBrandon Wyman .WillOnce(Return("207100")); 15572916ea52SBrandon Wyman psu.analyze(); 15582916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 1559391a0690SBrandon Wyman // Setup another expectation of no faults. 1560391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 156182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 156282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 156382affd94SBrandon Wyman .Times(1) 156482affd94SBrandon Wyman .WillOnce(Return("207200")); 156582affd94SBrandon Wyman psu.analyze(); 156682affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 156782affd94SBrandon Wyman // Setup another expectation of no faults. 156882affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 156982affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 157082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 157182affd94SBrandon Wyman .Times(1) 157282affd94SBrandon Wyman .WillOnce(Return("207300")); 1573391a0690SBrandon Wyman psu.analyze(); 1574391a0690SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 15752916ea52SBrandon Wyman // Turn PGOOD# off (fault on). 15762916ea52SBrandon Wyman expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED); 15772916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 157882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 157982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 158082affd94SBrandon Wyman .Times(1) 158182affd94SBrandon Wyman .WillOnce(Return("207400")); 15822916ea52SBrandon Wyman psu.analyze(); 158306ca4590SBrandon Wyman // Expect false until reaches DEGLITCH_LIMIT 158406ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 158506ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 158682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 158782affd94SBrandon Wyman .Times(1) 158882affd94SBrandon Wyman .WillOnce(Return("207500")); 158906ca4590SBrandon Wyman psu.analyze(); 159006ca4590SBrandon Wyman // Expect false until reaches DEGLITCH_LIMIT 159106ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 159206ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 159382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 159482affd94SBrandon Wyman .Times(1) 159582affd94SBrandon Wyman .WillOnce(Return("207600")); 159606ca4590SBrandon Wyman psu.analyze(); 159706ca4590SBrandon Wyman // DEGLITCH_LIMIT reached, expect true. 15982916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 15992916ea52SBrandon Wyman // Back to no fault bits on in STATUS_WORD 16002916ea52SBrandon Wyman expectations.statusWordValue = 0; 16012916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 160282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 160382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 160482affd94SBrandon Wyman .Times(1) 160582affd94SBrandon Wyman .WillOnce(Return("207700")); 16062916ea52SBrandon Wyman psu.analyze(); 16072916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 160882affd94SBrandon Wyman 16092916ea52SBrandon Wyman // Turn OFF bit on 16102916ea52SBrandon Wyman expectations.statusWordValue = (status_word::UNIT_IS_OFF); 16112916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 161282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 161382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 161482affd94SBrandon Wyman .Times(1) 161582affd94SBrandon Wyman .WillOnce(Return("208100")); 16162916ea52SBrandon Wyman psu.analyze(); 161706ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 161806ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 161982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 162082affd94SBrandon Wyman .Times(1) 162182affd94SBrandon Wyman .WillOnce(Return("208200")); 162206ca4590SBrandon Wyman psu.analyze(); 162306ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 162406ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 162582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 162682affd94SBrandon Wyman .Times(1) 162782affd94SBrandon Wyman .WillOnce(Return("208300")); 162806ca4590SBrandon Wyman psu.analyze(); 16292916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 16302916ea52SBrandon Wyman // Back to no fault bits on in STATUS_WORD 16312916ea52SBrandon Wyman expectations.statusWordValue = 0; 16322916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 163382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 163482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 163582affd94SBrandon Wyman .Times(1) 163682affd94SBrandon Wyman .WillOnce(Return("208400")); 16372916ea52SBrandon Wyman psu.analyze(); 16382916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 16392916ea52SBrandon Wyman } 164039ea02bcSBrandon Wyman 164139ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSKillFault) 164239ea02bcSBrandon Wyman { 164339ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1644c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 1645c3324424SBrandon Wyman 0x6d, "ibm-cffps", PSUGPIOLineName}; 164639ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 164739ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 164839ea02bcSBrandon Wyman // Always return 1 to indicate present. 164939ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 165039ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 165182affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 165239ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 165339ea02bcSBrandon Wyman PMBusExpectations expectations; 165439ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 165582affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 165682affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 165782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 165882affd94SBrandon Wyman .Times(1) 165982affd94SBrandon Wyman .WillOnce(Return("208100")); 166039ea02bcSBrandon Wyman psu.analyze(); 166139ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 166239ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 166339ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 166439ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 166539ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1666c2906f47SBrandon Wyman 1667c2906f47SBrandon Wyman // Deglitching faults, false until read the fault bits on up to the limit. 1668c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1669c2906f47SBrandon Wyman { 167039ea02bcSBrandon 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("208200")); 16750975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 16760975eaf4SMatt Spinler { 16770975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 16780975eaf4SMatt Spinler } 167939ea02bcSBrandon Wyman psu.analyze(); 1680c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1681c2906f47SBrandon Wyman } 1682c2906f47SBrandon Wyman 168339ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 168439ea02bcSBrandon Wyman expectations.statusWordValue = 0; 168539ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 168682affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 168782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 168882affd94SBrandon Wyman .Times(1) 168982affd94SBrandon Wyman .WillOnce(Return("208300")); 16900975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 169139ea02bcSBrandon Wyman psu.analyze(); 169239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 169339ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 169439ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 169539ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 4 on. 169639ea02bcSBrandon Wyman expectations.statusMFRValue = 0x10; 1697c2906f47SBrandon Wyman 1698c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1699c2906f47SBrandon Wyman { 170039ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 170182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 170282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 170382affd94SBrandon Wyman .Times(1) 170482affd94SBrandon Wyman .WillOnce(Return("208400")); 17050975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 17060975eaf4SMatt Spinler { 17070975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 17080975eaf4SMatt Spinler } 170939ea02bcSBrandon Wyman psu.analyze(); 1710c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1711c2906f47SBrandon Wyman } 1712c2906f47SBrandon Wyman 171339ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 171439ea02bcSBrandon Wyman expectations.statusWordValue = 0; 171539ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 171682affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 171782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 171882affd94SBrandon Wyman .Times(1) 171982affd94SBrandon Wyman .WillOnce(Return("208500")); 17200975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 172139ea02bcSBrandon Wyman psu.analyze(); 172239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 172339ea02bcSBrandon Wyman } 172439ea02bcSBrandon Wyman 172539ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPS12VcsFault) 172639ea02bcSBrandon Wyman { 172739ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1728c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 5, 1729c3324424SBrandon Wyman 0x6e, "ibm-cffps", PSUGPIOLineName}; 173039ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 173139ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 173239ea02bcSBrandon Wyman // Always return 1 to indicate present. 173339ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 173439ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 173582affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 173639ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 173739ea02bcSBrandon Wyman PMBusExpectations expectations; 173839ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 173982affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 174082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 174182affd94SBrandon Wyman .Times(1) 174282affd94SBrandon Wyman .WillOnce(Return("209100")); 174339ea02bcSBrandon Wyman psu.analyze(); 174439ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 174539ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 174639ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 174739ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 174839ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1749c2906f47SBrandon Wyman 1750c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1751c2906f47SBrandon Wyman { 175239ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 175382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 175482affd94SBrandon Wyman .Times(1) 175582affd94SBrandon Wyman .WillOnce(Return("209200")); 175639ea02bcSBrandon Wyman psu.analyze(); 1757c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1758c2906f47SBrandon Wyman } 1759c2906f47SBrandon Wyman 176039ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 176139ea02bcSBrandon Wyman expectations.statusWordValue = 0; 176239ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 176382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 176482affd94SBrandon Wyman .Times(1) 176582affd94SBrandon Wyman .WillOnce(Return("209300")); 176639ea02bcSBrandon Wyman psu.analyze(); 176739ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 176839ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 176939ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 177039ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 6 on. 177139ea02bcSBrandon Wyman expectations.statusMFRValue = 0x40; 1772c2906f47SBrandon Wyman 1773c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1774c2906f47SBrandon Wyman { 177539ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 177682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 177782affd94SBrandon Wyman .Times(1) 177882affd94SBrandon Wyman .WillOnce(Return("209400")); 177939ea02bcSBrandon Wyman psu.analyze(); 1780c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1781c2906f47SBrandon Wyman } 1782c2906f47SBrandon Wyman 178339ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 178439ea02bcSBrandon Wyman expectations.statusWordValue = 0; 178539ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 178682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 178782affd94SBrandon Wyman .Times(1) 178882affd94SBrandon Wyman .WillOnce(Return("209500")); 178939ea02bcSBrandon Wyman psu.analyze(); 179039ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 179139ea02bcSBrandon Wyman } 179239ea02bcSBrandon Wyman 179339ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSCS12VFault) 179439ea02bcSBrandon Wyman { 179539ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1796c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 6, 1797c3324424SBrandon Wyman 0x6f, "ibm-cffps", PSUGPIOLineName}; 179839ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 179939ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 180039ea02bcSBrandon Wyman // Always return 1 to indicate present. 180139ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 180239ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 180382affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 180439ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 180539ea02bcSBrandon Wyman PMBusExpectations expectations; 180639ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 180782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 180882affd94SBrandon Wyman .Times(1) 180982affd94SBrandon Wyman .WillOnce(Return("209100")); 181039ea02bcSBrandon Wyman psu.analyze(); 181139ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 181239ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 181339ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 181439ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 181539ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1816c2906f47SBrandon Wyman 1817c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1818c2906f47SBrandon Wyman { 181939ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 182082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 182182affd94SBrandon Wyman .Times(1) 182282affd94SBrandon Wyman .WillOnce(Return("209200")); 182339ea02bcSBrandon Wyman psu.analyze(); 1824c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1825c2906f47SBrandon Wyman } 1826c2906f47SBrandon Wyman 182739ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 182839ea02bcSBrandon Wyman expectations.statusWordValue = 0; 182939ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 183082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 183182affd94SBrandon Wyman .Times(1) 183282affd94SBrandon Wyman .WillOnce(Return("209300")); 183339ea02bcSBrandon Wyman psu.analyze(); 183439ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 183539ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 183639ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 183739ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 7 on. 183839ea02bcSBrandon Wyman expectations.statusMFRValue = 0x80; 1839c2906f47SBrandon Wyman 1840c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1841c2906f47SBrandon Wyman { 184239ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 184382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 184482affd94SBrandon Wyman .Times(1) 184582affd94SBrandon Wyman .WillOnce(Return("209400")); 184639ea02bcSBrandon Wyman psu.analyze(); 1847c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1848c2906f47SBrandon Wyman } 1849c2906f47SBrandon Wyman 185039ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 185139ea02bcSBrandon Wyman expectations.statusWordValue = 0; 185239ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 185382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 185482affd94SBrandon Wyman .Times(1) 185582affd94SBrandon Wyman .WillOnce(Return("209500")); 185639ea02bcSBrandon Wyman psu.analyze(); 185739ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 185839ea02bcSBrandon Wyman } 1859c3324424SBrandon Wyman 1860c3324424SBrandon Wyman TEST_F(PowerSupplyTests, SetupInputHistory) 1861c3324424SBrandon Wyman { 1862c3324424SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1863c3324424SBrandon Wyman { 1864c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 6, 1865c3324424SBrandon Wyman 0x6f, "ibm-cffps", PSUGPIOLineName}; 1866c3324424SBrandon Wyman // Defaults to not present due to constructor and mock ordering. 1867c3324424SBrandon Wyman psu.setupInputHistory(); 1868c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 1869c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1870c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1871c3324424SBrandon Wyman // Always return 1 to indicate present. 1872c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1873c3324424SBrandon Wyman psu.analyze(); 1874c3324424SBrandon Wyman psu.setupInputHistory(); 1875c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 1876c3324424SBrandon Wyman } 1877c3324424SBrandon Wyman { 1878c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 11, 1879c3324424SBrandon Wyman 0x58, "inspur-ipsps", PSUGPIOLineName}; 1880c3324424SBrandon Wyman // Defaults to not present due to constructor and mock ordering. 1881c3324424SBrandon Wyman psu.setupInputHistory(); 1882c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 1883c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1884c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1885c3324424SBrandon Wyman // Always return 1 to indicate present. 1886c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1887c3324424SBrandon Wyman psu.analyze(); 1888c3324424SBrandon Wyman psu.setupInputHistory(); 1889c3324424SBrandon Wyman // After updating to present, and retrying setup, expect inspur-ipsps to 1890c3324424SBrandon Wyman // still not support INPUT_HISTORY. 1891c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 1892c3324424SBrandon Wyman } 1893c3324424SBrandon Wyman } 1894c3324424SBrandon Wyman 1895c3324424SBrandon Wyman TEST_F(PowerSupplyTests, UpdateHistory) 1896c3324424SBrandon Wyman { 1897c3324424SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1898c3324424SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 7, 1899c3324424SBrandon Wyman 0x6e, "ibm-cffps", PSUGPIOLineName}; 1900c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 1901c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 0); 1902c3324424SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1903c3324424SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1904c3324424SBrandon Wyman // Always return 1 to indicate present. 1905c3324424SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1906c3324424SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1907c3324424SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1908c3324424SBrandon Wyman PMBusExpectations expectations; 1909c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 1910c3324424SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 1911c3324424SBrandon Wyman .Times(6) 1912c3324424SBrandon Wyman .WillRepeatedly(Return("205000")); 1913c3324424SBrandon Wyman EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1914c3324424SBrandon Wyman // First read after missing/present will have no data. 1915c3324424SBrandon Wyman std::vector<uint8_t> emptyHistory{}; 1916c3324424SBrandon Wyman // Second read, after about 30 seconds, should have a record. 5-bytes. 1917c3324424SBrandon Wyman // Sequence Number: 0x00, Average: 0x50 0xf3 (212), Maximum: 0x54 0xf3 (213) 1918c3324424SBrandon Wyman std::vector<uint8_t> firstHistory{0x00, 0x50, 0xf3, 0x54, 0xf3}; 1919c3324424SBrandon Wyman // Third read, after about 60 seconds, should have two records, 10-bytes, 1920c3324424SBrandon Wyman // but only reading 5 bytes, so make sure new/next sequence number 1921c3324424SBrandon Wyman std::vector<uint8_t> secondHistory{0x01, 0x54, 0xf3, 0x58, 0xf3}; 1922c3324424SBrandon Wyman // Fourth read, 3rd sequence number (0x02). 1923c3324424SBrandon Wyman std::vector<uint8_t> thirdHistory{0x02, 0x54, 0xf3, 0x58, 0xf3}; 1924c3324424SBrandon Wyman // Fifth read, out of sequence, clear and insert this one? 1925c3324424SBrandon Wyman std::vector<uint8_t> outseqHistory{0xff, 0x5c, 0xf3, 0x60, 0xf3}; 1926c3324424SBrandon Wyman EXPECT_CALL( 1927c3324424SBrandon Wyman mockPMBus, 1928c3324424SBrandon Wyman readBinary(INPUT_HISTORY, Type::HwmonDeviceDebug, 1929c3324424SBrandon Wyman phosphor::power::history::RecordManager::RAW_RECORD_SIZE)) 1930c3324424SBrandon Wyman .Times(6) 1931c3324424SBrandon Wyman .WillOnce(Return(emptyHistory)) 1932c3324424SBrandon Wyman .WillOnce(Return(firstHistory)) 1933c3324424SBrandon Wyman .WillOnce(Return(secondHistory)) 1934c3324424SBrandon Wyman .WillOnce(Return(thirdHistory)) 1935c3324424SBrandon Wyman .WillOnce(Return(outseqHistory)) 1936c3324424SBrandon Wyman .WillOnce(Return(emptyHistory)); 1937c3324424SBrandon Wyman // Calling analyze will update the presence, which will setup the input 1938c3324424SBrandon Wyman // history if the power supply went from missing to present. 1939c3324424SBrandon Wyman psu.analyze(); 1940c3324424SBrandon Wyman // The ibm-cffps power supply should support input history 1941c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 1942c3324424SBrandon Wyman // Usually should have empty buffer right after missing to present. 1943c3324424SBrandon Wyman // Faked that out above with mocked readBinary with emptyHistory data. 1944c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 0); 1945c3324424SBrandon Wyman // Second run through... 1946c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 1947c3324424SBrandon Wyman psu.analyze(); 1948c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 1949c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 1); 1950c3324424SBrandon Wyman // Third run through 1951c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 1952c3324424SBrandon Wyman psu.analyze(); 1953c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 1954c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 2); 1955c3324424SBrandon Wyman // Fourth run through. Up to 3 records now? 1956c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 1957c3324424SBrandon Wyman psu.analyze(); 1958c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 1959c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 3); 1960c3324424SBrandon Wyman // Out of sequencer, reset, insert new one. 1961c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 1962c3324424SBrandon Wyman psu.analyze(); 1963c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 1964c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 1); 1965c3324424SBrandon Wyman // Empty one after last one good. Reset/clear. 1966c3324424SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 1967c3324424SBrandon Wyman psu.analyze(); 1968c3324424SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 1969c3324424SBrandon Wyman EXPECT_EQ(psu.getNumInputHistoryRecords(), 0); 1970c3324424SBrandon Wyman } 1971*18a24d92SBrandon Wyman 1972*18a24d92SBrandon Wyman TEST_F(PowerSupplyTests, IsSyncHistoryRequired) 1973*18a24d92SBrandon Wyman { 1974*18a24d92SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1975*18a24d92SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 8, 1976*18a24d92SBrandon Wyman 0x6f, "ibm-cffps", PSUGPIOLineName}; 1977*18a24d92SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), false); 1978*18a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), false); 1979*18a24d92SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1980*18a24d92SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1981*18a24d92SBrandon Wyman // Always return 1 to indicate present. 1982*18a24d92SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1983*18a24d92SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1984*18a24d92SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1985*18a24d92SBrandon Wyman PMBusExpectations expectations; 1986*18a24d92SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 1987*18a24d92SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 1988*18a24d92SBrandon Wyman .Times(1) 1989*18a24d92SBrandon Wyman .WillRepeatedly(Return("205000")); 1990*18a24d92SBrandon Wyman EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1991*18a24d92SBrandon Wyman psu.analyze(); 1992*18a24d92SBrandon Wyman // The ibm-cffps power supply should support input history 1993*18a24d92SBrandon Wyman EXPECT_EQ(psu.hasInputHistory(), true); 1994*18a24d92SBrandon Wyman // Missing -> Present requires history sync 1995*18a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), true); 1996*18a24d92SBrandon Wyman psu.clearSyncHistoryRequired(); 1997*18a24d92SBrandon Wyman EXPECT_EQ(psu.isSyncHistoryRequired(), false); 1998*18a24d92SBrandon Wyman } 1999