13f1242f3SBrandon Wyman #include "../power_supply.hpp" 23f1242f3SBrandon Wyman #include "mock.hpp" 33f1242f3SBrandon Wyman 43f1242f3SBrandon Wyman #include <xyz/openbmc_project/Common/Device/error.hpp> 53f1242f3SBrandon Wyman #include <xyz/openbmc_project/Common/error.hpp> 63f1242f3SBrandon Wyman 73f1242f3SBrandon Wyman #include <gmock/gmock.h> 83f1242f3SBrandon Wyman #include <gtest/gtest.h> 93f1242f3SBrandon Wyman 103f1242f3SBrandon Wyman using namespace phosphor::power::psu; 113f1242f3SBrandon Wyman using namespace phosphor::pmbus; 123f1242f3SBrandon Wyman 133f1242f3SBrandon Wyman using ::testing::_; 1459a35793SBrandon Wyman using ::testing::Args; 153f1242f3SBrandon Wyman using ::testing::Assign; 163f1242f3SBrandon Wyman using ::testing::DoAll; 1759a35793SBrandon Wyman using ::testing::ElementsAre; 1859a35793SBrandon Wyman using ::testing::NotNull; 193f1242f3SBrandon Wyman using ::testing::Return; 203f1242f3SBrandon Wyman using ::testing::StrEq; 213f1242f3SBrandon Wyman 223f1242f3SBrandon Wyman static auto PSUInventoryPath = "/xyz/bmc/inv/sys/chassis/board/powersupply0"; 23681b2a36SB. J. Wyman static auto PSUGPIOLineName = "presence-ps0"; 243f1242f3SBrandon Wyman 25b654c619SBrandon Wyman struct PMBusExpectations 26b654c619SBrandon Wyman { 27b654c619SBrandon Wyman uint16_t statusWordValue{0x0000}; 28b654c619SBrandon Wyman uint8_t statusInputValue{0x00}; 29b654c619SBrandon Wyman uint8_t statusMFRValue{0x00}; 30b654c619SBrandon Wyman uint8_t statusCMLValue{0x00}; 31b654c619SBrandon Wyman uint8_t statusVOUTValue{0x00}; 32b10b3be0SBrandon Wyman uint8_t statusIOUTValue{0x00}; 337ee4d7e4SBrandon Wyman uint8_t statusFans12Value{0x00}; 3496893a46SBrandon Wyman uint8_t statusTempValue{0x00}; 35b654c619SBrandon Wyman }; 36b654c619SBrandon Wyman 378da35c51SBrandon Wyman // Helper function to setup expectations for various STATUS_* commands 38b654c619SBrandon Wyman void setPMBusExpectations(MockedPMBus& mockPMBus, 39b654c619SBrandon Wyman const PMBusExpectations& expectations) 408da35c51SBrandon Wyman { 418da35c51SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 428da35c51SBrandon Wyman .Times(1) 43b654c619SBrandon Wyman .WillOnce(Return(expectations.statusWordValue)); 448da35c51SBrandon Wyman 45b654c619SBrandon Wyman if (expectations.statusWordValue != 0) 468da35c51SBrandon Wyman { 478da35c51SBrandon Wyman // If fault bits are on in STATUS_WORD, there will also be a read of 4896893a46SBrandon Wyman // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT (page 0), and 4996893a46SBrandon Wyman // STATUS_TEMPERATURE. 508da35c51SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _)) 518da35c51SBrandon Wyman .Times(1) 52b654c619SBrandon Wyman .WillOnce(Return(expectations.statusInputValue)); 538da35c51SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _)) 548da35c51SBrandon Wyman .Times(1) 55b654c619SBrandon Wyman .WillOnce(Return(expectations.statusMFRValue)); 568da35c51SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _)) 578da35c51SBrandon Wyman .Times(1) 58b654c619SBrandon Wyman .WillOnce(Return(expectations.statusCMLValue)); 596710ba2cSBrandon Wyman // Page will need to be set to 0 to read STATUS_VOUT. 606710ba2cSBrandon Wyman EXPECT_CALL(mockPMBus, insertPageNum(STATUS_VOUT, 0)) 616710ba2cSBrandon Wyman .Times(1) 626710ba2cSBrandon Wyman .WillOnce(Return("status0_vout")); 636710ba2cSBrandon Wyman EXPECT_CALL(mockPMBus, read("status0_vout", _)) 646710ba2cSBrandon Wyman .Times(1) 65b654c619SBrandon Wyman .WillOnce(Return(expectations.statusVOUTValue)); 66b10b3be0SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_IOUT, _)) 67b10b3be0SBrandon Wyman .Times(1) 68b10b3be0SBrandon Wyman .WillOnce(Return(expectations.statusIOUTValue)); 697ee4d7e4SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_FANS_1_2, _)) 707ee4d7e4SBrandon Wyman .Times(1) 717ee4d7e4SBrandon Wyman .WillOnce(Return(expectations.statusFans12Value)); 7296893a46SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_TEMPERATURE, _)) 7396893a46SBrandon Wyman .Times(1) 7496893a46SBrandon Wyman .WillOnce(Return(expectations.statusTempValue)); 758da35c51SBrandon Wyman } 768da35c51SBrandon Wyman } 778da35c51SBrandon Wyman 783f1242f3SBrandon Wyman class PowerSupplyTests : public ::testing::Test 793f1242f3SBrandon Wyman { 803f1242f3SBrandon Wyman public: 813f1242f3SBrandon Wyman PowerSupplyTests() : 823f1242f3SBrandon Wyman mockedUtil(reinterpret_cast<const MockedUtil&>(getUtils())) 833f1242f3SBrandon Wyman { 843f1242f3SBrandon Wyman ON_CALL(mockedUtil, getPresence(_, _)).WillByDefault(Return(false)); 853f1242f3SBrandon Wyman } 863f1242f3SBrandon Wyman 873f1242f3SBrandon Wyman ~PowerSupplyTests() override 883f1242f3SBrandon Wyman { 893f1242f3SBrandon Wyman freeUtils(); 903f1242f3SBrandon Wyman } 913f1242f3SBrandon Wyman 923f1242f3SBrandon Wyman const MockedUtil& mockedUtil; 933f1242f3SBrandon Wyman }; 943f1242f3SBrandon Wyman 95391a0690SBrandon Wyman // Helper function for when a power supply goes from missing to present. 96391a0690SBrandon Wyman void setMissingToPresentExpects(MockedPMBus& pmbus, const MockedUtil& util) 97391a0690SBrandon Wyman { 98391a0690SBrandon Wyman // Call to analyze() will update to present, that will trigger updating 99391a0690SBrandon Wyman // to the correct/latest HWMON directory, in case it changes. 100391a0690SBrandon Wyman EXPECT_CALL(pmbus, findHwmonDir()); 101391a0690SBrandon Wyman // Presence change from missing to present will trigger write to 102391a0690SBrandon Wyman // ON_OFF_CONFIG. 103391a0690SBrandon Wyman EXPECT_CALL(pmbus, writeBinary(ON_OFF_CONFIG, _, _)); 104391a0690SBrandon Wyman // Presence change from missing to present will trigger in1_input read 105391a0690SBrandon Wyman // in an attempt to get CLEAR_FAULTS called. 10682affd94SBrandon Wyman // The voltage defaults to 0, the first call to analyze should update the 10782affd94SBrandon Wyman // voltage to the current reading, triggering another clearing of faults 10882affd94SBrandon Wyman // due to below minimum to within range voltage. 10982affd94SBrandon Wyman // This READ_VIN for CLEAR_FAULTS does not check the returned value. 11082affd94SBrandon Wyman EXPECT_CALL(pmbus, read(READ_VIN, _)) 11182affd94SBrandon Wyman .Times(2) 11282affd94SBrandon Wyman .WillOnce(Return(1)) 11382affd94SBrandon Wyman .WillOnce(Return(2)); 114391a0690SBrandon Wyman // Missing/present call will update Presence in inventory. 115391a0690SBrandon Wyman EXPECT_CALL(util, setPresence(_, _, true, _)); 116391a0690SBrandon Wyman } 117391a0690SBrandon Wyman 1183f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Constructor) 1193f1242f3SBrandon Wyman { 1203f1242f3SBrandon Wyman /** 1213f1242f3SBrandon Wyman * @param[in] invpath - String for inventory path to use 1223f1242f3SBrandon Wyman * @param[in] i2cbus - The bus number this power supply is on 1233f1242f3SBrandon Wyman * @param[in] i2caddr - The 16-bit I2C address of the power supply 124681b2a36SB. J. Wyman * @param[in] gpioLineName - The string for the gpio-line-name to read for 125681b2a36SB. J. Wyman * presence. 126681b2a36SB. J. Wyman * @param[in] bindDelay - Time in milliseconds to delay binding the device 127681b2a36SB. J. Wyman * driver after seeing the presence line go active. 1283f1242f3SBrandon Wyman */ 1293f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1301d7a7df8SBrandon Wyman 1311d7a7df8SBrandon Wyman // Try where inventory path is empty, constructor should fail. 1321d7a7df8SBrandon Wyman try 1331d7a7df8SBrandon Wyman { 134681b2a36SB. J. Wyman auto psu = 135681b2a36SB. J. Wyman std::make_unique<PowerSupply>(bus, "", 3, 0x68, PSUGPIOLineName); 1361d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have reached this line."; 1371d7a7df8SBrandon Wyman } 1381d7a7df8SBrandon Wyman catch (const std::invalid_argument& e) 1391d7a7df8SBrandon Wyman { 1401d7a7df8SBrandon Wyman EXPECT_STREQ(e.what(), "Invalid empty inventoryPath"); 1411d7a7df8SBrandon Wyman } 1421d7a7df8SBrandon Wyman catch (...) 1431d7a7df8SBrandon Wyman { 1441d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 1451d7a7df8SBrandon Wyman } 1461d7a7df8SBrandon Wyman 147681b2a36SB. J. Wyman // TODO: Try invalid i2c address? 148681b2a36SB. J. Wyman 149681b2a36SB. J. Wyman // Try where gpioLineName is empty. 1501d7a7df8SBrandon Wyman try 1511d7a7df8SBrandon Wyman { 1521d7a7df8SBrandon Wyman auto psu = 153681b2a36SB. J. Wyman std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, ""); 154681b2a36SB. J. Wyman ADD_FAILURE() 155681b2a36SB. J. Wyman << "Should not have reached this line. Invalid gpioLineName."; 156681b2a36SB. J. Wyman } 157681b2a36SB. J. Wyman catch (const std::invalid_argument& e) 158681b2a36SB. J. Wyman { 159681b2a36SB. J. Wyman EXPECT_STREQ(e.what(), "Invalid empty gpioLineName"); 160681b2a36SB. J. Wyman } 161681b2a36SB. J. Wyman catch (...) 162681b2a36SB. J. Wyman { 163681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 164681b2a36SB. J. Wyman } 165681b2a36SB. J. Wyman 166681b2a36SB. J. Wyman // Test with valid arguments 167681b2a36SB. J. Wyman // NOT using D-Bus inventory path for presence. 168681b2a36SB. J. Wyman try 169681b2a36SB. J. Wyman { 170681b2a36SB. J. Wyman auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, 171681b2a36SB. J. Wyman PSUGPIOLineName); 1723f1242f3SBrandon Wyman 1733f1242f3SBrandon Wyman EXPECT_EQ(psu->isPresent(), false); 1743f1242f3SBrandon Wyman EXPECT_EQ(psu->isFaulted(), false); 1758da35c51SBrandon Wyman EXPECT_EQ(psu->hasCommFault(), false); 1763f1242f3SBrandon Wyman EXPECT_EQ(psu->hasInputFault(), false); 1773f1242f3SBrandon Wyman EXPECT_EQ(psu->hasMFRFault(), false); 1783f1242f3SBrandon Wyman EXPECT_EQ(psu->hasVINUVFault(), false); 1796710ba2cSBrandon Wyman EXPECT_EQ(psu->hasVoutOVFault(), false); 180b10b3be0SBrandon Wyman EXPECT_EQ(psu->hasIoutOCFault(), false); 1812cf46945SBrandon Wyman EXPECT_EQ(psu->hasVoutUVFault(), false); 1827ee4d7e4SBrandon Wyman EXPECT_EQ(psu->hasFanFault(), false); 18396893a46SBrandon Wyman EXPECT_EQ(psu->hasTempFault(), false); 1842916ea52SBrandon Wyman EXPECT_EQ(psu->hasPgoodFault(), false); 18539ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPSKillFault(), false); 18639ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPS12VcsFault(), false); 18739ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPSCS12VFault(), false); 1883f1242f3SBrandon Wyman } 1891d7a7df8SBrandon Wyman catch (...) 1901d7a7df8SBrandon Wyman { 1911d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 1921d7a7df8SBrandon Wyman } 193681b2a36SB. J. Wyman 194681b2a36SB. J. Wyman // Test with valid arguments 195681b2a36SB. J. Wyman // TODO: Using D-Bus inventory path for presence. 196681b2a36SB. J. Wyman try 197681b2a36SB. J. Wyman { 198681b2a36SB. J. Wyman // FIXME: How do I get that presenceGPIO.read() in the startup to throw 199681b2a36SB. J. Wyman // an exception? 200681b2a36SB. J. Wyman 201681b2a36SB. J. Wyman // EXPECT_CALL(mockedUtil, getPresence(_, 202681b2a36SB. J. Wyman // StrEq(PSUInventoryPath))) 203681b2a36SB. J. Wyman // .Times(1); 204681b2a36SB. J. Wyman } 205681b2a36SB. J. Wyman catch (...) 206681b2a36SB. J. Wyman { 207681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 208681b2a36SB. J. Wyman } 2091d7a7df8SBrandon Wyman } 2103f1242f3SBrandon Wyman 2113f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Analyze) 2123f1242f3SBrandon Wyman { 2133f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2143f1242f3SBrandon Wyman 215b654c619SBrandon Wyman { 216681b2a36SB. J. Wyman // If I default to reading the GPIO, I will NOT expect a call to 217681b2a36SB. J. Wyman // getPresence(). 218681b2a36SB. J. Wyman 219681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName}; 2203ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 2213ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 222681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0)); 223681b2a36SB. J. Wyman 2243f1242f3SBrandon Wyman psu.analyze(); 2253f1242f3SBrandon Wyman // By default, nothing should change. 2263f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 2273f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 2283f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 2293f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 2303f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 23185c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 2326710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 233b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 2342cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 2357ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 23696893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 2372916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 23839ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 23939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 24039ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 241b654c619SBrandon Wyman } 2423f1242f3SBrandon Wyman 243681b2a36SB. J. Wyman PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName}; 244681b2a36SB. J. Wyman // In order to get the various faults tested, the power supply needs to 245681b2a36SB. J. Wyman // be present in order to read from the PMBus device(s). 2463ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO2 = 2473ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO()); 24806ca4590SBrandon Wyman // Always return 1 to indicate present. 24906ca4590SBrandon Wyman // Each analyze() call will trigger a read of the presence GPIO. 25006ca4590SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO2, read()).WillRepeatedly(Return(1)); 251681b2a36SB. J. Wyman EXPECT_EQ(psu2.isPresent(), false); 2523f1242f3SBrandon Wyman 2533f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus()); 254391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 255b654c619SBrandon Wyman 256b654c619SBrandon Wyman // STATUS_WORD INPUT fault. 257b654c619SBrandon Wyman { 258b654c619SBrandon Wyman // Start with STATUS_WORD 0x0000. Powered on, no faults. 259b654c619SBrandon Wyman // Set expectations for a no fault 260b654c619SBrandon Wyman PMBusExpectations expectations; 261b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 26282affd94SBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 26382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 26482affd94SBrandon Wyman .Times(1) 26582affd94SBrandon Wyman .WillOnce(Return("206000")); 2663f1242f3SBrandon Wyman psu2.analyze(); 2673f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2683f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 2693f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 2703f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 2713f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 27285c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 2736710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 274b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 2752cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 2767ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 27796893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 2782916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 27939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 28039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 28139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 2823f1242f3SBrandon Wyman 283b654c619SBrandon Wyman // Update expectations for STATUS_WORD input fault/warn 28496893a46SBrandon Wyman // STATUS_INPUT fault bits ... on. 285b654c619SBrandon Wyman expectations.statusWordValue = (status_word::INPUT_FAULT_WARN); 286b654c619SBrandon Wyman expectations.statusInputValue = 0x38; 287*c2906f47SBrandon Wyman 288*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 289*c2906f47SBrandon Wyman { 290b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 29182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 29282affd94SBrandon Wyman .Times(1) 29382affd94SBrandon Wyman .WillOnce(Return("207000")); 2943f1242f3SBrandon Wyman psu2.analyze(); 2953f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 296*c2906f47SBrandon Wyman // Should not be faulted until it reaches the deglitch limit. 297*c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 298*c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT); 2993f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 3003f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 30185c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 3026710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 303b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 3042cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 3057ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 30696893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 3072916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 30839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 30939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 31039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 311b654c619SBrandon Wyman } 312*c2906f47SBrandon Wyman } 313*c2906f47SBrandon Wyman 314*c2906f47SBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(1)); 315*c2906f47SBrandon Wyman psu2.clearFaults(); 3163f1242f3SBrandon Wyman 3173f1242f3SBrandon Wyman // STATUS_WORD INPUT/UV fault. 318b654c619SBrandon Wyman { 3193f1242f3SBrandon Wyman // First need it to return good status, then the fault 320b654c619SBrandon Wyman PMBusExpectations expectations; 321b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 32282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 32382affd94SBrandon Wyman .Times(1) 32482affd94SBrandon Wyman .WillOnce(Return("208000")); 3253f1242f3SBrandon Wyman psu2.analyze(); 326*c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 327*c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 3288da35c51SBrandon Wyman // Now set fault bits in STATUS_WORD 329b654c619SBrandon Wyman expectations.statusWordValue = 3308da35c51SBrandon Wyman (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT); 3318da35c51SBrandon Wyman // STATUS_INPUT fault bits ... on. 332b654c619SBrandon Wyman expectations.statusInputValue = 0x38; 333*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 334*c2906f47SBrandon Wyman { 335b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 33682affd94SBrandon Wyman // Input/UV fault, so voltage should read back low. 33782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 33882affd94SBrandon Wyman .Times(1) 33982affd94SBrandon Wyman .WillOnce(Return("19123")); 3403f1242f3SBrandon Wyman psu2.analyze(); 3413f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 342*c2906f47SBrandon Wyman // Only faulted if hit deglitch limit 343*c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 344*c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT); 345*c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), x >= DEGLITCH_LIMIT); 3463f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 34785c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 3486710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 349b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 3502cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 3517ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 35296893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 3532916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 35439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 35539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 35639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 357*c2906f47SBrandon Wyman } 35882affd94SBrandon Wyman // Turning VIN_UV fault off causes clearing of faults, causing read of 35982affd94SBrandon Wyman // in1_input as an attempt to get CLEAR_FAULTS called. 36082affd94SBrandon Wyman expectations.statusWordValue = 0; 36182affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 36282affd94SBrandon Wyman // The call to read the voltage 36382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 36482affd94SBrandon Wyman .Times(1) 36582affd94SBrandon Wyman .WillOnce(Return("209000")); 36682affd94SBrandon Wyman // The call for CLEAR_FAULTS command 36782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(3)); 36882affd94SBrandon Wyman psu2.analyze(); 36982affd94SBrandon Wyman // Should remain present, no longer be faulted, no input fault, no 37082affd94SBrandon Wyman // VIN_UV fault. Nothing else should change. 37182affd94SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 37282affd94SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 37382affd94SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 37482affd94SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 375b654c619SBrandon Wyman } 3763f1242f3SBrandon Wyman 377*c2906f47SBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(1)); 378*c2906f47SBrandon Wyman psu2.clearFaults(); 379*c2906f47SBrandon Wyman 3803f1242f3SBrandon Wyman // STATUS_WORD MFR fault. 381b654c619SBrandon Wyman { 382f07bc797SBrandon Wyman // First need it to return good status, then the fault 383b654c619SBrandon Wyman PMBusExpectations expectations; 384b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 38582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 38682affd94SBrandon Wyman .Times(1) 38782affd94SBrandon Wyman .WillOnce(Return("210000")); 3883f1242f3SBrandon Wyman psu2.analyze(); 3898da35c51SBrandon Wyman // Now STATUS_WORD with MFR fault bit on. 390b654c619SBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 3918da35c51SBrandon Wyman // STATUS_MFR bits on. 392b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 393*c2906f47SBrandon Wyman 394*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 395*c2906f47SBrandon Wyman { 396b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 39782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 39882affd94SBrandon Wyman .Times(1) 39982affd94SBrandon Wyman .WillOnce(Return("211000")); 4003f1242f3SBrandon Wyman psu2.analyze(); 4013f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 402*c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 4033f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 404*c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), x >= DEGLITCH_LIMIT); 405*c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), x >= DEGLITCH_LIMIT); 406*c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 407*c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 4083f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 40985c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 4106710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 411b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 4122cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 4137ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 41496893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 4152916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 416*c2906f47SBrandon Wyman } 417b654c619SBrandon Wyman } 4183f1242f3SBrandon Wyman 419*c2906f47SBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(1)); 420*c2906f47SBrandon Wyman psu2.clearFaults(); 42196893a46SBrandon Wyman // Temperature fault. 422b654c619SBrandon Wyman { 423f07bc797SBrandon Wyman // First STATUS_WORD with no bits set, then with temperature fault. 424b654c619SBrandon Wyman PMBusExpectations expectations; 425b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 42682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 42782affd94SBrandon Wyman .Times(1) 42882affd94SBrandon Wyman .WillOnce(Return("212000")); 4293f1242f3SBrandon Wyman psu2.analyze(); 4308da35c51SBrandon Wyman // STATUS_WORD with temperature fault bit on. 431b654c619SBrandon Wyman expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 43296893a46SBrandon Wyman // STATUS_TEMPERATURE with fault bit(s) on. 43396893a46SBrandon Wyman expectations.statusTempValue = 0x10; 434*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 435*c2906f47SBrandon Wyman { 436b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 43782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 43882affd94SBrandon Wyman .Times(1) 43982affd94SBrandon Wyman .WillOnce(Return("213000")); 4403f1242f3SBrandon Wyman psu2.analyze(); 4413f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 442*c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 4433f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 4443f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 4453f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 44685c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 4476710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 448b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 4492cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 4507ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 451*c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), x >= DEGLITCH_LIMIT); 4522916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 45339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 45439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 45539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 456b654c619SBrandon Wyman } 457*c2906f47SBrandon Wyman } 45885c7bf41SBrandon Wyman 459*c2906f47SBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(1)); 460*c2906f47SBrandon Wyman psu2.clearFaults(); 46185c7bf41SBrandon Wyman // CML fault 462b654c619SBrandon Wyman { 46385c7bf41SBrandon Wyman // First STATUS_WORD wit no bits set, then with CML fault. 464b654c619SBrandon Wyman PMBusExpectations expectations; 465b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 46682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 46782affd94SBrandon Wyman .Times(1) 46882affd94SBrandon Wyman .WillOnce(Return("214000")); 46985c7bf41SBrandon Wyman psu2.analyze(); 4708da35c51SBrandon Wyman // STATUS_WORD with CML fault bit on. 471b654c619SBrandon Wyman expectations.statusWordValue = (status_word::CML_FAULT); 47285c7bf41SBrandon Wyman // Turn on STATUS_CML fault bit(s) 473b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 474*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 475*c2906f47SBrandon Wyman { 476b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 47782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 47882affd94SBrandon Wyman .Times(1) 47982affd94SBrandon Wyman .WillOnce(Return("215000")); 48085c7bf41SBrandon Wyman psu2.analyze(); 48185c7bf41SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 482*c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 483*c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), x >= DEGLITCH_LIMIT); 48485c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 48585c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 48685c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 4876710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 488b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 4892cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 4907ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 49196893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 4922916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 49339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 49439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 49539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 496b654c619SBrandon Wyman } 497*c2906f47SBrandon Wyman } 4986710ba2cSBrandon Wyman 499*c2906f47SBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(1)); 500*c2906f47SBrandon Wyman psu2.clearFaults(); 5016710ba2cSBrandon Wyman // VOUT_OV_FAULT fault 502b654c619SBrandon Wyman { 5036710ba2cSBrandon Wyman // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault. 504b654c619SBrandon Wyman PMBusExpectations expectations; 505b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 50682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 50782affd94SBrandon Wyman .Times(1) 50882affd94SBrandon Wyman .WillOnce(Return("216000")); 5096710ba2cSBrandon Wyman psu2.analyze(); 5106710ba2cSBrandon Wyman // STATUS_WORD with VOUT/VOUT_OV fault. 511b654c619SBrandon Wyman expectations.statusWordValue = 5126710ba2cSBrandon Wyman ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT)); 5136710ba2cSBrandon Wyman // Turn on STATUS_VOUT fault bit(s) 514b654c619SBrandon Wyman expectations.statusVOUTValue = 0xA0; 515*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 516*c2906f47SBrandon Wyman { 51796893a46SBrandon Wyman // STATUS_TEMPERATURE don't care (default) 518b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 51982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 52082affd94SBrandon Wyman .Times(1) 52182affd94SBrandon Wyman .WillOnce(Return("217000")); 5226710ba2cSBrandon Wyman psu2.analyze(); 5236710ba2cSBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 524*c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 5256710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 5266710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 5276710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 5286710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 529*c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 5302cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 531b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 5327ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 533b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 534b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 53539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 53639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 53739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 538b10b3be0SBrandon Wyman } 539*c2906f47SBrandon Wyman } 540b10b3be0SBrandon Wyman 541b10b3be0SBrandon Wyman // IOUT_OC_FAULT fault 542b10b3be0SBrandon Wyman { 543b10b3be0SBrandon Wyman // First STATUS_WORD with no bits set, then with IOUT_OC fault. 544b10b3be0SBrandon Wyman PMBusExpectations expectations; 545b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 54682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 54782affd94SBrandon Wyman .Times(1) 54882affd94SBrandon Wyman .WillOnce(Return("218000")); 549b10b3be0SBrandon Wyman psu2.analyze(); 550b10b3be0SBrandon Wyman // STATUS_WORD with IOUT_OC fault. 551b10b3be0SBrandon Wyman expectations.statusWordValue = status_word::IOUT_OC_FAULT; 552b10b3be0SBrandon Wyman // Turn on STATUS_IOUT fault bit(s) 553b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0x88; 554*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 555*c2906f47SBrandon Wyman { 556b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 55782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 55882affd94SBrandon Wyman .Times(1) 55982affd94SBrandon Wyman .WillOnce(Return("219000")); 560b10b3be0SBrandon Wyman psu2.analyze(); 561b10b3be0SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 562*c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 563b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 564b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 565b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 566b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 567b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 568*c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 5692cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 5707ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 5712cf46945SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 5722cf46945SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 57339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 57439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 57539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 5762cf46945SBrandon Wyman } 577*c2906f47SBrandon Wyman } 5782cf46945SBrandon Wyman 5792cf46945SBrandon Wyman // VOUT_UV_FAULT 5802cf46945SBrandon Wyman { 5812cf46945SBrandon Wyman // First STATUS_WORD with no bits set, then with VOUT fault. 5822cf46945SBrandon Wyman PMBusExpectations expectations; 5832cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 58482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 58582affd94SBrandon Wyman .Times(1) 58682affd94SBrandon Wyman .WillOnce(Return("220000")); 5872cf46945SBrandon Wyman psu2.analyze(); 5882cf46945SBrandon Wyman // Change STATUS_WORD to indicate VOUT fault. 5892cf46945SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_FAULT); 5902cf46945SBrandon Wyman // Turn on STATUS_VOUT fault bit(s) 5912cf46945SBrandon Wyman expectations.statusVOUTValue = 0x30; 592*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 593*c2906f47SBrandon Wyman { 5942cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 59582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 59682affd94SBrandon Wyman .Times(1) 59782affd94SBrandon Wyman .WillOnce(Return("221000")); 5982cf46945SBrandon Wyman psu2.analyze(); 5992cf46945SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 600*c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 6012cf46945SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 6022cf46945SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 6032cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 6042cf46945SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 6052cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 6062cf46945SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 607*c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), x >= DEGLITCH_LIMIT); 6087ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 60996893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6102916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 61139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 61239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 61339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 614b654c619SBrandon Wyman } 615*c2906f47SBrandon Wyman } 6163f1242f3SBrandon Wyman 6177ee4d7e4SBrandon Wyman // Fan fault 618b654c619SBrandon Wyman { 619b654c619SBrandon Wyman // First STATUS_WORD with no bits set, then with fan fault. 620b654c619SBrandon Wyman PMBusExpectations expectations; 621b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 62282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 62382affd94SBrandon Wyman .Times(1) 62482affd94SBrandon Wyman .WillOnce(Return("222000")); 6253f1242f3SBrandon Wyman psu2.analyze(); 626b654c619SBrandon Wyman expectations.statusWordValue = (status_word::FAN_FAULT); 6277ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with fan 1 warning & fault bits on. 6287ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xA0; 629*c2906f47SBrandon Wyman 630*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 631*c2906f47SBrandon Wyman { 632b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 63382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 63482affd94SBrandon Wyman .Times(1) 63582affd94SBrandon Wyman .WillOnce(Return("223000")); 6363f1242f3SBrandon Wyman psu2.analyze(); 6373f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 638*c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 639*c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), x >= DEGLITCH_LIMIT); 6403f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 6413f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 6423f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 64385c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 6446710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 645b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 6462cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 64796893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6482916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 64939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 65039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 65139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 652b654c619SBrandon Wyman } 653*c2906f47SBrandon Wyman } 6542916ea52SBrandon Wyman 65506ca4590SBrandon Wyman // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT. 6562cf46945SBrandon Wyman { 6572916ea52SBrandon Wyman // First STATUS_WORD with no bits set. 6582916ea52SBrandon Wyman PMBusExpectations expectations; 6592916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 66082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 66182affd94SBrandon Wyman .Times(1) 66282affd94SBrandon Wyman .WillOnce(Return("123000")); 6632916ea52SBrandon Wyman psu2.analyze(); 6642916ea52SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 6652916ea52SBrandon Wyman // POWER_GOOD# inactive, and OFF bit on. 6662916ea52SBrandon Wyman expectations.statusWordValue = 6672916ea52SBrandon Wyman ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF)); 66806ca4590SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 66906ca4590SBrandon Wyman { 6702916ea52SBrandon Wyman // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and 6712916ea52SBrandon Wyman // STATUS_TEMPERATURE: Don't care if bits set or not (defaults). 6722916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 67382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 67482affd94SBrandon Wyman .Times(1) 67582affd94SBrandon Wyman .WillOnce(Return("124000")); 6762916ea52SBrandon Wyman psu2.analyze(); 6772916ea52SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 678*c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 6792916ea52SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 6802916ea52SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 6812916ea52SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 6822916ea52SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 6832916ea52SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 6842cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 685b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 6867ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 6872916ea52SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 68806ca4590SBrandon Wyman if (x < DEGLITCH_LIMIT) 68906ca4590SBrandon Wyman { 69006ca4590SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 69106ca4590SBrandon Wyman } 69206ca4590SBrandon Wyman else 69306ca4590SBrandon Wyman { 6942916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), true); 6952916ea52SBrandon Wyman } 69606ca4590SBrandon Wyman } 69706ca4590SBrandon Wyman } 6982916ea52SBrandon Wyman 6993f1242f3SBrandon Wyman // TODO: ReadFailure 7003f1242f3SBrandon Wyman } 7013f1242f3SBrandon Wyman 70259a35793SBrandon Wyman TEST_F(PowerSupplyTests, OnOffConfig) 70359a35793SBrandon Wyman { 70459a35793SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 70559a35793SBrandon Wyman uint8_t data = 0x15; 70659a35793SBrandon Wyman 70759a35793SBrandon Wyman // Test where PSU is NOT present 70859a35793SBrandon Wyman try 70959a35793SBrandon Wyman { 710681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 711681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName}; 712681b2a36SB. J. Wyman 7133ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7143ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 715681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0)); 71659a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 717681b2a36SB. J. Wyman // Constructor should set initial presence, default read returns 0. 71859a35793SBrandon Wyman // If it is not present, I should not be trying to write to it. 71959a35793SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0); 72059a35793SBrandon Wyman psu.onOffConfig(data); 72159a35793SBrandon Wyman } 72259a35793SBrandon Wyman catch (...) 7230c9a33d6SAdriana Kobylak {} 72459a35793SBrandon Wyman 72559a35793SBrandon Wyman // Test where PSU is present 72659a35793SBrandon Wyman try 72759a35793SBrandon Wyman { 728681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 729681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName}; 7303ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7313ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 732391a0690SBrandon Wyman // There will potentially be multiple calls, we want it to continue 733391a0690SBrandon Wyman // returning 1 for the GPIO read to keep the power supply present. 734391a0690SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 73559a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 736391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 737391a0690SBrandon Wyman // If I am calling analyze(), I should probably give it good data. 738391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 739391a0690SBrandon Wyman PMBusExpectations expectations; 740391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 74182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 74282affd94SBrandon Wyman .Times(1) 74382affd94SBrandon Wyman .WillOnce(Return("205000")); 744681b2a36SB. J. Wyman psu.analyze(); 745391a0690SBrandon Wyman // I definitely should be writting ON_OFF_CONFIG if I call the function 746391a0690SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, ElementsAre(0x15), 747391a0690SBrandon Wyman Type::HwmonDeviceDebug)) 74859a35793SBrandon Wyman .Times(1); 74959a35793SBrandon Wyman psu.onOffConfig(data); 75059a35793SBrandon Wyman } 75159a35793SBrandon Wyman catch (...) 7520c9a33d6SAdriana Kobylak {} 75359a35793SBrandon Wyman } 75459a35793SBrandon Wyman 7553f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, ClearFaults) 7563f1242f3SBrandon Wyman { 7573f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 758681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, PSUGPIOLineName}; 7593ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7603ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 76106ca4590SBrandon Wyman // Always return 1 to indicate present. 76206ca4590SBrandon Wyman // Each analyze() call will trigger a read of the presence GPIO. 76306ca4590SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 764681b2a36SB. J. Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 765391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 7668da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 767b654c619SBrandon Wyman PMBusExpectations expectations; 768b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 76982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 77082affd94SBrandon Wyman .Times(1) 77182affd94SBrandon Wyman .WillOnce(Return("207000")); 772681b2a36SB. J. Wyman psu.analyze(); 7733f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 7743f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 7753f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 7763f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 7773f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 77885c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 7796710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 780b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 7812cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 7827ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 78396893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 7842916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 78539ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 78639ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 78739ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 788b654c619SBrandon Wyman 789f07bc797SBrandon Wyman // STATUS_WORD with fault bits galore! 790b654c619SBrandon Wyman expectations.statusWordValue = 0xFFFF; 791f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 792b654c619SBrandon Wyman expectations.statusInputValue = 0xFF; 793f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 794b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 79585c7bf41SBrandon Wyman // STATUS_CML with bits on. 796b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 7976710ba2cSBrandon Wyman // STATUS_VOUT with bits on. 798b654c619SBrandon Wyman expectations.statusVOUTValue = 0xFF; 799b10b3be0SBrandon Wyman // STATUS_IOUT with bits on. 800b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0xFF; 8017ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with bits on. 8027ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xFF; 80396893a46SBrandon Wyman // STATUS_TEMPERATURE with bits on. 80496893a46SBrandon Wyman expectations.statusTempValue = 0xFF; 805*c2906f47SBrandon Wyman 806*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 807*c2906f47SBrandon Wyman { 808b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 80982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 81082affd94SBrandon Wyman .Times(1) 81182affd94SBrandon Wyman .WillOnce(Return("0")); 8123f1242f3SBrandon Wyman psu.analyze(); 8133f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8142cf46945SBrandon Wyman // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT. 8152cf46945SBrandon Wyman // Rely on HasVoutUVFault() to verify this sets and clears. 8162cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 817*c2906f47SBrandon Wyman // All faults are deglitched up to DEGLITCH_LIMIT 818*c2906f47SBrandon Wyman EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT); 819*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 820*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 821*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 822*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), x >= DEGLITCH_LIMIT); 823*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 824*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 825*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 826*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 827*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), x >= DEGLITCH_LIMIT); 828*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 829*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 830*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 831*c2906f47SBrandon Wyman } 832*c2906f47SBrandon Wyman 833*c2906f47SBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(207000)); 8343f1242f3SBrandon Wyman psu.clearFaults(); 8353f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8363f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 8373f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 8383f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 8393f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 84085c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 8416710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 842b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 8432cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 8447ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 84596893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 8462916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 84739ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 84839ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 84939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 850681b2a36SB. J. Wyman 85182affd94SBrandon Wyman // Faults clear on READ_VIN 0 -> !0 85282affd94SBrandon Wyman // STATUS_WORD with fault bits galore! 85382affd94SBrandon Wyman expectations.statusWordValue = 0xFFFF; 85482affd94SBrandon Wyman // STATUS_INPUT with fault bits on. 85582affd94SBrandon Wyman expectations.statusInputValue = 0xFF; 85682affd94SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 85782affd94SBrandon Wyman expectations.statusMFRValue = 0xFF; 85882affd94SBrandon Wyman // STATUS_CML with bits on. 85982affd94SBrandon Wyman expectations.statusCMLValue = 0xFF; 86082affd94SBrandon Wyman // STATUS_VOUT with bits on. 86182affd94SBrandon Wyman expectations.statusVOUTValue = 0xFF; 86282affd94SBrandon Wyman // STATUS_IOUT with bits on. 86382affd94SBrandon Wyman expectations.statusIOUTValue = 0xFF; 86482affd94SBrandon Wyman // STATUS_FANS_1_2 with bits on. 86582affd94SBrandon Wyman expectations.statusFans12Value = 0xFF; 86682affd94SBrandon Wyman // STATUS_TEMPERATURE with bits on. 86782affd94SBrandon Wyman expectations.statusTempValue = 0xFF; 868*c2906f47SBrandon Wyman 869*c2906f47SBrandon Wyman // All faults degltiched now. Check for false before limit above. 870*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 871*c2906f47SBrandon Wyman { 87282affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 87382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 87482affd94SBrandon Wyman .Times(1) 87582affd94SBrandon Wyman .WillOnce(Return("0")); 87682affd94SBrandon Wyman psu.analyze(); 877*c2906f47SBrandon Wyman } 878*c2906f47SBrandon Wyman 87982affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 88082affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 88182affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 88282affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 88382affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 88482affd94SBrandon Wyman // True due to CML fault bits on 88582affd94SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), true); 88682affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 88782affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), true); 88882affd94SBrandon Wyman // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT. 88982affd94SBrandon Wyman // Rely on HasVoutUVFault() to verify this sets and clears. 89082affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 89182affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), true); 89282affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), true); 893*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 89482affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), true); 89582affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), true); 89682affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), true); 89782affd94SBrandon Wyman // STATUS_WORD with INPUT/VIN_UV fault bits off. 89882affd94SBrandon Wyman expectations.statusWordValue = 0xDFF7; 89982affd94SBrandon Wyman // STATUS_INPUT with VIN_UV_WARNING, VIN_UV_FAULT, and Unit Off For 90082affd94SBrandon Wyman // Insufficient Input Voltage bits off. 90182affd94SBrandon Wyman expectations.statusInputValue = 0xC7; 90282affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 90382affd94SBrandon Wyman // READ_VIN back in range. 90482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 90582affd94SBrandon Wyman .Times(1) 90682affd94SBrandon Wyman .WillOnce(Return("206000")); 907*c2906f47SBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(0)); 90882affd94SBrandon Wyman psu.analyze(); 90982affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 91082affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 91182affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 91282affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 91382affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 91482affd94SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 91582affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 91682affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 91782affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 91882affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 91982affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 92082affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 92182affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 92282affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 92382affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 92482affd94SBrandon Wyman 925681b2a36SB. J. Wyman // TODO: Faults clear on missing/present? 9263f1242f3SBrandon Wyman } 9273f1242f3SBrandon Wyman 9283f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory) 9293f1242f3SBrandon Wyman { 9303f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 9311d7a7df8SBrandon Wyman 9321d7a7df8SBrandon Wyman try 9331d7a7df8SBrandon Wyman { 934681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 9351d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 9361d7a7df8SBrandon Wyman // If it is not present, I should not be trying to read a string 9371d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).Times(0); 9381d7a7df8SBrandon Wyman psu.updateInventory(); 9391d7a7df8SBrandon Wyman } 9401d7a7df8SBrandon Wyman catch (...) 9411d7a7df8SBrandon Wyman { 9421d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 9431d7a7df8SBrandon Wyman } 9441d7a7df8SBrandon Wyman 9451d7a7df8SBrandon Wyman try 9461d7a7df8SBrandon Wyman { 947681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, PSUGPIOLineName}; 9483ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 9493ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 950681b2a36SB. J. Wyman // GPIO read return 1 to indicate present. 951681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 9521d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 953391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 954391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 955391a0690SBrandon Wyman PMBusExpectations expectations; 956391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 95782affd94SBrandon Wyman // Call to analyze will read voltage, trigger clear faults for 0 to 95882affd94SBrandon Wyman // within range. 95982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 96082affd94SBrandon Wyman .Times(1) 96182affd94SBrandon Wyman .WillOnce(Return("123456")); 962391a0690SBrandon Wyman psu.analyze(); 9631d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return("")); 9643f1242f3SBrandon Wyman psu.updateInventory(); 9651d7a7df8SBrandon Wyman 9663c530fbdSBrandon Wyman #if IBM_VPD 9671d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)) 9681d7a7df8SBrandon Wyman .WillOnce(Return("CCIN")) 9691d7a7df8SBrandon Wyman .WillOnce(Return("PN3456")) 9701d7a7df8SBrandon Wyman .WillOnce(Return("FN3456")) 9711d7a7df8SBrandon Wyman .WillOnce(Return("HEADER")) 9721d7a7df8SBrandon Wyman .WillOnce(Return("SN3456")) 9731d7a7df8SBrandon Wyman .WillOnce(Return("FW3456")); 9743c530fbdSBrandon Wyman #endif 9751d7a7df8SBrandon Wyman psu.updateInventory(); 9761d7a7df8SBrandon Wyman // TODO: D-Bus mocking to verify values stored on D-Bus (???) 9771d7a7df8SBrandon Wyman } 9781d7a7df8SBrandon Wyman catch (...) 9791d7a7df8SBrandon Wyman { 9801d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 9811d7a7df8SBrandon Wyman } 9823f1242f3SBrandon Wyman } 9833f1242f3SBrandon Wyman 9843f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent) 9853f1242f3SBrandon Wyman { 9863f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 987681b2a36SB. J. Wyman 988681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 9893ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 9903ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 9913f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 9923f1242f3SBrandon Wyman 993681b2a36SB. J. Wyman // Change GPIO read to return 1 to indicate present. 994681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 995391a0690SBrandon Wyman // Call to analyze() will update to present, that will trigger updating 996391a0690SBrandon Wyman // to the correct/latest HWMON directory, in case it changes. 997391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 998391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 999391a0690SBrandon Wyman // Call to analyze things will trigger read of STATUS_WORD and READ_VIN. 1000391a0690SBrandon Wyman // Default expectations will be on, no faults. 1001391a0690SBrandon Wyman PMBusExpectations expectations; 1002391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 100382affd94SBrandon Wyman // Give it an input voltage in the 100-volt range. 100482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 100582affd94SBrandon Wyman .Times(1) 100682affd94SBrandon Wyman .WillOnce(Return("123456")); 1007681b2a36SB. J. Wyman psu.analyze(); 1008681b2a36SB. J. Wyman EXPECT_EQ(psu.isPresent(), true); 10093f1242f3SBrandon Wyman } 10103f1242f3SBrandon Wyman 10113f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted) 10123f1242f3SBrandon Wyman { 10133f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1014681b2a36SB. J. Wyman 1015681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, PSUGPIOLineName}; 10163ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10173ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1018681b2a36SB. J. Wyman // Always return 1 to indicate present. 1019681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1020391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1021391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1022391a0690SBrandon Wyman // Call to analyze things will trigger read of STATUS_WORD and READ_VIN. 1023391a0690SBrandon Wyman // Default expectations will be on, no faults. 1024391a0690SBrandon Wyman PMBusExpectations expectations; 1025391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 102682affd94SBrandon Wyman // Give it an input voltage in the 100-volt range. 102782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 102882affd94SBrandon Wyman .Times(1) 102982affd94SBrandon Wyman .WillOnce(Return("124680")); 1030681b2a36SB. J. Wyman psu.analyze(); 10313f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 1032f07bc797SBrandon Wyman // STATUS_WORD with fault bits on. 1033b654c619SBrandon Wyman expectations.statusWordValue = 0xFFFF; 1034f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 1035b654c619SBrandon Wyman expectations.statusInputValue = 0xFF; 1036f07bc797SBrandon Wyman // STATUS_MFR_SPECIFIC with faults bits on. 1037b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 103885c7bf41SBrandon Wyman // STATUS_CML with faults bits on. 1039b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 10406710ba2cSBrandon Wyman // STATUS_VOUT with fault bits on. 1041b654c619SBrandon Wyman expectations.statusVOUTValue = 0xFF; 1042b10b3be0SBrandon Wyman // STATUS_IOUT with fault bits on. 1043b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0xFF; 10447ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with bits on. 10457ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xFF; 104696893a46SBrandon Wyman // STATUS_TEMPERATURE with fault bits on. 104796893a46SBrandon Wyman expectations.statusTempValue = 0xFF; 1048*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1049*c2906f47SBrandon Wyman { 1050b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 105182affd94SBrandon Wyman // Also get another read of READ_VIN. 105282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 105382affd94SBrandon Wyman .Times(1) 105482affd94SBrandon Wyman .WillOnce(Return("125790")); 10553f1242f3SBrandon Wyman psu.analyze(); 1056*c2906f47SBrandon Wyman EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT); 1057*c2906f47SBrandon Wyman } 10583f1242f3SBrandon Wyman } 10593f1242f3SBrandon Wyman 10603f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasInputFault) 10613f1242f3SBrandon Wyman { 10623f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1063681b2a36SB. J. Wyman 1064681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 10653ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10663ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1067681b2a36SB. J. Wyman // Always return 1 to indicate present. 1068681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 10693f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1070391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 10718da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1072b654c619SBrandon Wyman PMBusExpectations expectations; 1073b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 107482affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 107582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 107682affd94SBrandon Wyman .Times(1) 107782affd94SBrandon Wyman .WillOnce(Return("201100")); 10783f1242f3SBrandon Wyman psu.analyze(); 10793f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 1080f07bc797SBrandon Wyman // STATUS_WORD with input fault/warn on. 1081b654c619SBrandon Wyman expectations.statusWordValue = (status_word::INPUT_FAULT_WARN); 1082f07bc797SBrandon Wyman // STATUS_INPUT with an input fault bit on. 1083b654c619SBrandon Wyman expectations.statusInputValue = 0x80; 1084*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1085*c2906f47SBrandon Wyman { 1086b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 108782affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 108882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 108982affd94SBrandon Wyman .Times(1) 109082affd94SBrandon Wyman .WillOnce(Return("201200")); 10913f1242f3SBrandon Wyman psu.analyze(); 1092*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 1093*c2906f47SBrandon Wyman } 1094f07bc797SBrandon Wyman // STATUS_WORD with no bits on. 1095b654c619SBrandon Wyman expectations.statusWordValue = 0; 1096b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 109782affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 109882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 109982affd94SBrandon Wyman .Times(1) 110082affd94SBrandon Wyman .WillOnce(Return("201300")); 11013f1242f3SBrandon Wyman psu.analyze(); 11023f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 11033f1242f3SBrandon Wyman } 11043f1242f3SBrandon Wyman 11053f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault) 11063f1242f3SBrandon Wyman { 11073f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1108681b2a36SB. J. Wyman 1109681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 11103ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 11113ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1112681b2a36SB. J. Wyman // Always return 1 to indicate present. 1113681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 11143f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1115391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1116f07bc797SBrandon Wyman // First return STATUS_WORD with no bits on. 11178da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1118b654c619SBrandon Wyman PMBusExpectations expectations; 1119b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 112082affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 112182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 112282affd94SBrandon Wyman .Times(1) 112382affd94SBrandon Wyman .WillOnce(Return("202100")); 11243f1242f3SBrandon Wyman psu.analyze(); 11253f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 1126f07bc797SBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 1127b654c619SBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 1128f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 1129b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 1130*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1131*c2906f47SBrandon Wyman { 1132b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 113382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 113482affd94SBrandon Wyman .Times(1) 113582affd94SBrandon Wyman .WillOnce(Return("202200")); 11363f1242f3SBrandon Wyman psu.analyze(); 1137*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 1138*c2906f47SBrandon Wyman } 1139f07bc797SBrandon Wyman // Back to no bits on in STATUS_WORD 1140b654c619SBrandon Wyman expectations.statusWordValue = 0; 1141b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 114282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 114382affd94SBrandon Wyman .Times(1) 114482affd94SBrandon Wyman .WillOnce(Return("202300")); 11453f1242f3SBrandon Wyman psu.analyze(); 11463f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 11473f1242f3SBrandon Wyman } 11483f1242f3SBrandon Wyman 11493f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault) 11503f1242f3SBrandon Wyman { 11513f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1152681b2a36SB. J. Wyman 1153681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 11543ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 11553ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1156681b2a36SB. J. Wyman // Always return 1 to indicate present. 1157681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 11583f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1159391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 116082affd94SBrandon Wyman 116182affd94SBrandon Wyman // Presence change from missing to present will trigger in1_input read in 116282affd94SBrandon Wyman // an attempt to get CLEAR_FAULTS called. Return value ignored. 116382affd94SBrandon Wyman // Zero to non-zero voltage, for missing/present change, triggers clear 116482affd94SBrandon Wyman // faults call again. Return value ignored. 116582affd94SBrandon Wyman // Fault (low voltage) to not faulted (voltage in range) triggers clear 116682affd94SBrandon Wyman // faults call a third time. 116782affd94SBrandon Wyman 11688da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1169b654c619SBrandon Wyman PMBusExpectations expectations; 1170b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 117182affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 117282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 117382affd94SBrandon Wyman .Times(1) 117482affd94SBrandon Wyman .WillOnce(Return("201100")); 11753f1242f3SBrandon Wyman psu.analyze(); 11763f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 1177f07bc797SBrandon Wyman // Turn fault on. 1178b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VIN_UV_FAULT); 117985c7bf41SBrandon Wyman // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by 118085c7bf41SBrandon Wyman // Figure 16, and assume bits on in STATUS_INPUT. 1181b654c619SBrandon Wyman expectations.statusInputValue = 0x18; 1182*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1183*c2906f47SBrandon Wyman { 1184b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 118582affd94SBrandon Wyman // If there is a VIN_UV fault, fake reading voltage of less than 20V 118682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 118782affd94SBrandon Wyman .Times(1) 118882affd94SBrandon Wyman .WillOnce(Return("19876")); 11893f1242f3SBrandon Wyman psu.analyze(); 1190*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 1191*c2906f47SBrandon Wyman } 1192f07bc797SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1193b654c619SBrandon Wyman expectations.statusWordValue = 0; 1194b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 119582affd94SBrandon Wyman // Updates now result in clearing faults if read voltage goes from below the 119682affd94SBrandon Wyman // minimum, to within a valid range. 119782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 119882affd94SBrandon Wyman .Times(1) 119982affd94SBrandon Wyman .WillOnce(Return("201300")); 120082affd94SBrandon Wyman // Went from below minimum to within range, expect CLEAR_FAULTS. 120182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(3)); 12023f1242f3SBrandon Wyman psu.analyze(); 12033f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 12043f1242f3SBrandon Wyman } 12056710ba2cSBrandon Wyman 12066710ba2cSBrandon Wyman TEST_F(PowerSupplyTests, HasVoutOVFault) 12076710ba2cSBrandon Wyman { 12086710ba2cSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 12096710ba2cSBrandon Wyman 12106710ba2cSBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x69, PSUGPIOLineName}; 12116710ba2cSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 12126710ba2cSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 12136710ba2cSBrandon Wyman // Always return 1 to indicate present. 12146710ba2cSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 12156710ba2cSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1216391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 12176710ba2cSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1218b654c619SBrandon Wyman PMBusExpectations expectations; 1219b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 122082affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 122182affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 122282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 122382affd94SBrandon Wyman .Times(1) 122482affd94SBrandon Wyman .WillOnce(Return("202100")); 12256710ba2cSBrandon Wyman psu.analyze(); 12266710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 12276710ba2cSBrandon Wyman // Turn fault on. 1228b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_OV_FAULT); 12296710ba2cSBrandon Wyman // STATUS_VOUT fault bit(s) 1230b654c619SBrandon Wyman expectations.statusVOUTValue = 0x80; 1231*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1232*c2906f47SBrandon Wyman { 1233b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 123482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 123582affd94SBrandon Wyman .Times(1) 123682affd94SBrandon Wyman .WillOnce(Return("202200")); 12376710ba2cSBrandon Wyman psu.analyze(); 1238*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 1239*c2906f47SBrandon Wyman } 12406710ba2cSBrandon Wyman // Back to no fault bits on in STATUS_WORD 1241b654c619SBrandon Wyman expectations.statusWordValue = 0; 1242b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 124382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 124482affd94SBrandon Wyman .Times(1) 124582affd94SBrandon Wyman .WillOnce(Return("202300")); 12466710ba2cSBrandon Wyman psu.analyze(); 12476710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 12486710ba2cSBrandon Wyman } 124996893a46SBrandon Wyman 1250b10b3be0SBrandon Wyman TEST_F(PowerSupplyTests, HasIoutOCFault) 1251b10b3be0SBrandon Wyman { 1252b10b3be0SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1253b10b3be0SBrandon Wyman 1254b10b3be0SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName}; 1255b10b3be0SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1256b10b3be0SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1257b10b3be0SBrandon Wyman // Always return 1 to indicate present. 1258b10b3be0SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1259b10b3be0SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1260391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1261b10b3be0SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1262b10b3be0SBrandon Wyman PMBusExpectations expectations; 1263b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 126482affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 126582affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 126682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 126782affd94SBrandon Wyman .Times(1) 126882affd94SBrandon Wyman .WillOnce(Return("203100")); 1269b10b3be0SBrandon Wyman psu.analyze(); 1270b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1271b10b3be0SBrandon Wyman // Turn fault on. 1272b10b3be0SBrandon Wyman expectations.statusWordValue = status_word::IOUT_OC_FAULT; 1273b10b3be0SBrandon Wyman // STATUS_IOUT fault bit(s) 1274b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0x88; 1275*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1276*c2906f47SBrandon Wyman { 1277b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 127882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 127982affd94SBrandon Wyman .Times(1) 128082affd94SBrandon Wyman .WillOnce(Return("203200")); 1281b10b3be0SBrandon Wyman psu.analyze(); 1282*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 1283*c2906f47SBrandon Wyman } 1284b10b3be0SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1285b10b3be0SBrandon Wyman expectations.statusWordValue = 0; 1286b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 128782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 128882affd94SBrandon Wyman .Times(1) 128982affd94SBrandon Wyman .WillOnce(Return("203300")); 1290b10b3be0SBrandon Wyman psu.analyze(); 1291b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1292b10b3be0SBrandon Wyman } 1293b10b3be0SBrandon Wyman 12942cf46945SBrandon Wyman TEST_F(PowerSupplyTests, HasVoutUVFault) 12952cf46945SBrandon Wyman { 12962cf46945SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 12972cf46945SBrandon Wyman 12982cf46945SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName}; 12992cf46945SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 13002cf46945SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 13012cf46945SBrandon Wyman // Always return 1 to indicate present. 13022cf46945SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 13032cf46945SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1304391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1305391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 13062cf46945SBrandon Wyman PMBusExpectations expectations; 13072cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 130882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 130982affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 131082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 131182affd94SBrandon Wyman .Times(1) 131282affd94SBrandon Wyman .WillOnce(Return("204100")); 13132cf46945SBrandon Wyman psu.analyze(); 13142cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 13152cf46945SBrandon Wyman // Turn fault on. 13162cf46945SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_FAULT); 13172cf46945SBrandon Wyman // STATUS_VOUT fault bit(s) 13182cf46945SBrandon Wyman expectations.statusVOUTValue = 0x30; 1319*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1320*c2906f47SBrandon Wyman { 13212cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 132282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 132382affd94SBrandon Wyman .Times(1) 132482affd94SBrandon Wyman .WillOnce(Return("204200")); 13252cf46945SBrandon Wyman psu.analyze(); 1326*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), x >= DEGLITCH_LIMIT); 1327*c2906f47SBrandon Wyman } 13282cf46945SBrandon Wyman // Back to no fault bits on in STATUS_WORD 13292cf46945SBrandon Wyman expectations.statusWordValue = 0; 13302cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 133182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 133282affd94SBrandon Wyman .Times(1) 133382affd94SBrandon Wyman .WillOnce(Return("204300")); 13342cf46945SBrandon Wyman psu.analyze(); 13352cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 13362cf46945SBrandon Wyman } 13372cf46945SBrandon Wyman 13387ee4d7e4SBrandon Wyman TEST_F(PowerSupplyTests, HasFanFault) 13397ee4d7e4SBrandon Wyman { 13407ee4d7e4SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 13417ee4d7e4SBrandon Wyman 13427ee4d7e4SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName}; 13437ee4d7e4SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 13447ee4d7e4SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 13457ee4d7e4SBrandon Wyman // Always return 1 to indicate present. 13467ee4d7e4SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 13477ee4d7e4SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1348391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 13497ee4d7e4SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 13507ee4d7e4SBrandon Wyman PMBusExpectations expectations; 13517ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 135282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 135382affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 135482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 135582affd94SBrandon Wyman .Times(1) 135682affd94SBrandon Wyman .WillOnce(Return("205100")); 13577ee4d7e4SBrandon Wyman psu.analyze(); 13587ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 13597ee4d7e4SBrandon Wyman // Turn fault on. 13607ee4d7e4SBrandon Wyman expectations.statusWordValue = (status_word::FAN_FAULT); 13617ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 fault bit on (Fan 1 Fault) 13627ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0x80; 1363*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1364*c2906f47SBrandon Wyman { 13657ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 136682affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 136782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 136882affd94SBrandon Wyman .Times(1) 136982affd94SBrandon Wyman .WillOnce(Return("205200")); 13707ee4d7e4SBrandon Wyman psu.analyze(); 1371*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 1372*c2906f47SBrandon Wyman } 13737ee4d7e4SBrandon Wyman // Back to no fault bits on in STATUS_WORD 13747ee4d7e4SBrandon Wyman expectations.statusWordValue = 0; 13757ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 137682affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 137782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 137882affd94SBrandon Wyman .Times(1) 137982affd94SBrandon Wyman .WillOnce(Return("205300")); 13807ee4d7e4SBrandon Wyman psu.analyze(); 13817ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 13827ee4d7e4SBrandon Wyman } 13837ee4d7e4SBrandon Wyman 138496893a46SBrandon Wyman TEST_F(PowerSupplyTests, HasTempFault) 138596893a46SBrandon Wyman { 138696893a46SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 138796893a46SBrandon Wyman 138896893a46SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName}; 138996893a46SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 139096893a46SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 139196893a46SBrandon Wyman // Always return 1 to indicate present. 139296893a46SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 139396893a46SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1394391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 139596893a46SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 139696893a46SBrandon Wyman PMBusExpectations expectations; 139796893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 139882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 139982affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 140082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 140182affd94SBrandon Wyman .Times(1) 140282affd94SBrandon Wyman .WillOnce(Return("206100")); 140396893a46SBrandon Wyman psu.analyze(); 140496893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 140596893a46SBrandon Wyman // Turn fault on. 140696893a46SBrandon Wyman expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 140796893a46SBrandon Wyman // STATUS_TEMPERATURE fault bit on (OT Fault) 140896893a46SBrandon Wyman expectations.statusTempValue = 0x80; 1409*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1410*c2906f47SBrandon Wyman { 141196893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 141282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 141382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 141482affd94SBrandon Wyman .Times(1) 141582affd94SBrandon Wyman .WillOnce(Return("206200")); 141696893a46SBrandon Wyman psu.analyze(); 1417*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 1418*c2906f47SBrandon Wyman } 141996893a46SBrandon Wyman // Back to no fault bits on in STATUS_WORD 142096893a46SBrandon Wyman expectations.statusWordValue = 0; 142196893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 142282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 142382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 142482affd94SBrandon Wyman .Times(1) 142582affd94SBrandon Wyman .WillOnce(Return("206300")); 142696893a46SBrandon Wyman psu.analyze(); 142796893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 142896893a46SBrandon Wyman } 14292916ea52SBrandon Wyman 14302916ea52SBrandon Wyman TEST_F(PowerSupplyTests, HasPgoodFault) 14312916ea52SBrandon Wyman { 14322916ea52SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 14332916ea52SBrandon Wyman 14342916ea52SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x6b, PSUGPIOLineName}; 14352916ea52SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 14362916ea52SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 14372916ea52SBrandon Wyman // Always return 1 to indicate present. 14382916ea52SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 14392916ea52SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1440391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 14412916ea52SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 14422916ea52SBrandon Wyman PMBusExpectations expectations; 14432916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 144482affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 144582affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 144682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 144782affd94SBrandon Wyman .Times(1) 144882affd94SBrandon Wyman .WillOnce(Return("207100")); 14492916ea52SBrandon Wyman psu.analyze(); 14502916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 1451391a0690SBrandon Wyman // Setup another expectation of no faults. 1452391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 145382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 145482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 145582affd94SBrandon Wyman .Times(1) 145682affd94SBrandon Wyman .WillOnce(Return("207200")); 145782affd94SBrandon Wyman psu.analyze(); 145882affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 145982affd94SBrandon Wyman // Setup another expectation of no faults. 146082affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 146182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 146282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 146382affd94SBrandon Wyman .Times(1) 146482affd94SBrandon Wyman .WillOnce(Return("207300")); 1465391a0690SBrandon Wyman psu.analyze(); 1466391a0690SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 14672916ea52SBrandon Wyman // Turn PGOOD# off (fault on). 14682916ea52SBrandon Wyman expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED); 14692916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 147082affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 147182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 147282affd94SBrandon Wyman .Times(1) 147382affd94SBrandon Wyman .WillOnce(Return("207400")); 14742916ea52SBrandon Wyman psu.analyze(); 147506ca4590SBrandon Wyman // Expect false until reaches DEGLITCH_LIMIT 147606ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 147706ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 147882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 147982affd94SBrandon Wyman .Times(1) 148082affd94SBrandon Wyman .WillOnce(Return("207500")); 148106ca4590SBrandon Wyman psu.analyze(); 148206ca4590SBrandon Wyman // Expect false until reaches DEGLITCH_LIMIT 148306ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 148406ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 148582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 148682affd94SBrandon Wyman .Times(1) 148782affd94SBrandon Wyman .WillOnce(Return("207600")); 148806ca4590SBrandon Wyman psu.analyze(); 148906ca4590SBrandon Wyman // DEGLITCH_LIMIT reached, expect true. 14902916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 14912916ea52SBrandon Wyman // Back to no fault bits on in STATUS_WORD 14922916ea52SBrandon Wyman expectations.statusWordValue = 0; 14932916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 149482affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 149582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 149682affd94SBrandon Wyman .Times(1) 149782affd94SBrandon Wyman .WillOnce(Return("207700")); 14982916ea52SBrandon Wyman psu.analyze(); 14992916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 150082affd94SBrandon Wyman 15012916ea52SBrandon Wyman // Turn OFF bit on 15022916ea52SBrandon Wyman expectations.statusWordValue = (status_word::UNIT_IS_OFF); 15032916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 150482affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 150582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 150682affd94SBrandon Wyman .Times(1) 150782affd94SBrandon Wyman .WillOnce(Return("208100")); 15082916ea52SBrandon Wyman psu.analyze(); 150906ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 151006ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 151182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 151282affd94SBrandon Wyman .Times(1) 151382affd94SBrandon Wyman .WillOnce(Return("208200")); 151406ca4590SBrandon Wyman psu.analyze(); 151506ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 151606ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 151782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 151882affd94SBrandon Wyman .Times(1) 151982affd94SBrandon Wyman .WillOnce(Return("208300")); 152006ca4590SBrandon Wyman psu.analyze(); 15212916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 15222916ea52SBrandon Wyman // Back to no fault bits on in STATUS_WORD 15232916ea52SBrandon Wyman expectations.statusWordValue = 0; 15242916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 152582affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 152682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 152782affd94SBrandon Wyman .Times(1) 152882affd94SBrandon Wyman .WillOnce(Return("208400")); 15292916ea52SBrandon Wyman psu.analyze(); 15302916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 15312916ea52SBrandon Wyman } 153239ea02bcSBrandon Wyman 153339ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSKillFault) 153439ea02bcSBrandon Wyman { 153539ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 153639ea02bcSBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 0x6d, PSUGPIOLineName}; 153739ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 153839ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 153939ea02bcSBrandon Wyman // Always return 1 to indicate present. 154039ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 154139ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 154282affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 154339ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 154439ea02bcSBrandon Wyman PMBusExpectations expectations; 154539ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 154682affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 154782affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 154882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 154982affd94SBrandon Wyman .Times(1) 155082affd94SBrandon Wyman .WillOnce(Return("208100")); 155139ea02bcSBrandon Wyman psu.analyze(); 155239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 155339ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 155439ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 155539ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 155639ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1557*c2906f47SBrandon Wyman 1558*c2906f47SBrandon Wyman // Deglitching faults, false until read the fault bits on up to the limit. 1559*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1560*c2906f47SBrandon Wyman { 156139ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 156282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 156382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 156482affd94SBrandon Wyman .Times(1) 156582affd94SBrandon Wyman .WillOnce(Return("208200")); 156639ea02bcSBrandon Wyman psu.analyze(); 1567*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1568*c2906f47SBrandon Wyman } 1569*c2906f47SBrandon Wyman 157039ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 157139ea02bcSBrandon Wyman expectations.statusWordValue = 0; 157239ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 157382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 157482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 157582affd94SBrandon Wyman .Times(1) 157682affd94SBrandon Wyman .WillOnce(Return("208300")); 157739ea02bcSBrandon Wyman psu.analyze(); 157839ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 157939ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 158039ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 158139ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 4 on. 158239ea02bcSBrandon Wyman expectations.statusMFRValue = 0x10; 1583*c2906f47SBrandon Wyman 1584*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1585*c2906f47SBrandon Wyman { 158639ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 158782affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 158882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 158982affd94SBrandon Wyman .Times(1) 159082affd94SBrandon Wyman .WillOnce(Return("208400")); 159139ea02bcSBrandon Wyman psu.analyze(); 1592*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1593*c2906f47SBrandon Wyman } 1594*c2906f47SBrandon Wyman 159539ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 159639ea02bcSBrandon Wyman expectations.statusWordValue = 0; 159739ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 159882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 159982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 160082affd94SBrandon Wyman .Times(1) 160182affd94SBrandon Wyman .WillOnce(Return("208500")); 160239ea02bcSBrandon Wyman psu.analyze(); 160339ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 160439ea02bcSBrandon Wyman } 160539ea02bcSBrandon Wyman 160639ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPS12VcsFault) 160739ea02bcSBrandon Wyman { 160839ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 160939ea02bcSBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 5, 0x6e, PSUGPIOLineName}; 161039ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 161139ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 161239ea02bcSBrandon Wyman // Always return 1 to indicate present. 161339ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 161439ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 161582affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 161639ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 161739ea02bcSBrandon Wyman PMBusExpectations expectations; 161839ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 161982affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 162082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 162182affd94SBrandon Wyman .Times(1) 162282affd94SBrandon Wyman .WillOnce(Return("209100")); 162339ea02bcSBrandon Wyman psu.analyze(); 162439ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 162539ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 162639ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 162739ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 162839ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1629*c2906f47SBrandon Wyman 1630*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1631*c2906f47SBrandon Wyman { 163239ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 163382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 163482affd94SBrandon Wyman .Times(1) 163582affd94SBrandon Wyman .WillOnce(Return("209200")); 163639ea02bcSBrandon Wyman psu.analyze(); 1637*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1638*c2906f47SBrandon Wyman } 1639*c2906f47SBrandon Wyman 164039ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 164139ea02bcSBrandon Wyman expectations.statusWordValue = 0; 164239ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 164382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 164482affd94SBrandon Wyman .Times(1) 164582affd94SBrandon Wyman .WillOnce(Return("209300")); 164639ea02bcSBrandon Wyman psu.analyze(); 164739ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 164839ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 164939ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 165039ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 6 on. 165139ea02bcSBrandon Wyman expectations.statusMFRValue = 0x40; 1652*c2906f47SBrandon Wyman 1653*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1654*c2906f47SBrandon Wyman { 165539ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 165682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 165782affd94SBrandon Wyman .Times(1) 165882affd94SBrandon Wyman .WillOnce(Return("209400")); 165939ea02bcSBrandon Wyman psu.analyze(); 1660*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1661*c2906f47SBrandon Wyman } 1662*c2906f47SBrandon Wyman 166339ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 166439ea02bcSBrandon Wyman expectations.statusWordValue = 0; 166539ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 166682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 166782affd94SBrandon Wyman .Times(1) 166882affd94SBrandon Wyman .WillOnce(Return("209500")); 166939ea02bcSBrandon Wyman psu.analyze(); 167039ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 167139ea02bcSBrandon Wyman } 167239ea02bcSBrandon Wyman 167339ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSCS12VFault) 167439ea02bcSBrandon Wyman { 167539ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 167639ea02bcSBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f, PSUGPIOLineName}; 167739ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 167839ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 167939ea02bcSBrandon Wyman // Always return 1 to indicate present. 168039ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 168139ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 168282affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 168339ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 168439ea02bcSBrandon Wyman PMBusExpectations expectations; 168539ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 168682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 168782affd94SBrandon Wyman .Times(1) 168882affd94SBrandon Wyman .WillOnce(Return("209100")); 168939ea02bcSBrandon Wyman psu.analyze(); 169039ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 169139ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 169239ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 169339ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 169439ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1695*c2906f47SBrandon Wyman 1696*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1697*c2906f47SBrandon Wyman { 169839ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 169982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 170082affd94SBrandon Wyman .Times(1) 170182affd94SBrandon Wyman .WillOnce(Return("209200")); 170239ea02bcSBrandon Wyman psu.analyze(); 1703*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1704*c2906f47SBrandon Wyman } 1705*c2906f47SBrandon Wyman 170639ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 170739ea02bcSBrandon Wyman expectations.statusWordValue = 0; 170839ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 170982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 171082affd94SBrandon Wyman .Times(1) 171182affd94SBrandon Wyman .WillOnce(Return("209300")); 171239ea02bcSBrandon Wyman psu.analyze(); 171339ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 171439ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 171539ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 171639ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 7 on. 171739ea02bcSBrandon Wyman expectations.statusMFRValue = 0x80; 1718*c2906f47SBrandon Wyman 1719*c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1720*c2906f47SBrandon Wyman { 172139ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 172282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 172382affd94SBrandon Wyman .Times(1) 172482affd94SBrandon Wyman .WillOnce(Return("209400")); 172539ea02bcSBrandon Wyman psu.analyze(); 1726*c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1727*c2906f47SBrandon Wyman } 1728*c2906f47SBrandon Wyman 172939ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 173039ea02bcSBrandon Wyman expectations.statusWordValue = 0; 173139ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 173282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 173382affd94SBrandon Wyman .Times(1) 173482affd94SBrandon Wyman .WillOnce(Return("209500")); 173539ea02bcSBrandon Wyman psu.analyze(); 173639ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 173739ea02bcSBrandon Wyman } 1738