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 { 4132453e9bSBrandon 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. 5032453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _, _)) 518da35c51SBrandon Wyman .Times(1) 52b654c619SBrandon Wyman .WillOnce(Return(expectations.statusInputValue)); 5332453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _, _)) 548da35c51SBrandon Wyman .Times(1) 55b654c619SBrandon Wyman .WillOnce(Return(expectations.statusMFRValue)); 5632453e9bSBrandon 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")); 6332453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read("status0_vout", _, _)) 646710ba2cSBrandon Wyman .Times(1) 65b654c619SBrandon Wyman .WillOnce(Return(expectations.statusVOUTValue)); 6632453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_IOUT, _, _)) 67b10b3be0SBrandon Wyman .Times(1) 68b10b3be0SBrandon Wyman .WillOnce(Return(expectations.statusIOUTValue)); 6932453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_FANS_1_2, _, _)) 707ee4d7e4SBrandon Wyman .Times(1) 717ee4d7e4SBrandon Wyman .WillOnce(Return(expectations.statusFans12Value)); 7232453e9bSBrandon 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 // This READ_VIN for CLEAR_FAULTS does not check the returned value. 107*3225a45cSBrandon Wyman EXPECT_CALL(pmbus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 108*3225a45cSBrandon Wyman // The call for clearing faults includes clearing VIN_UV fault. 109*3225a45cSBrandon Wyman // The voltage defaults to 0, the first call to analyze should update the 110*3225a45cSBrandon Wyman // voltage to the current reading, triggering clearing VIN_UV fault(s) 111*3225a45cSBrandon Wyman // due to below minimum to within range voltage. 112*3225a45cSBrandon Wyman EXPECT_CALL(pmbus, read("in1_lcrit_alarm", _, _)) 11382affd94SBrandon Wyman .Times(2) 114*3225a45cSBrandon Wyman .WillRepeatedly(Return(1)); 115391a0690SBrandon Wyman // Missing/present call will update Presence in inventory. 116391a0690SBrandon Wyman EXPECT_CALL(util, setPresence(_, _, true, _)); 117391a0690SBrandon Wyman } 118391a0690SBrandon Wyman 1193f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Constructor) 1203f1242f3SBrandon Wyman { 1213f1242f3SBrandon Wyman /** 1223f1242f3SBrandon Wyman * @param[in] invpath - String for inventory path to use 1233f1242f3SBrandon Wyman * @param[in] i2cbus - The bus number this power supply is on 1243f1242f3SBrandon Wyman * @param[in] i2caddr - The 16-bit I2C address of the power supply 125681b2a36SB. J. Wyman * @param[in] gpioLineName - The string for the gpio-line-name to read for 126681b2a36SB. J. Wyman * presence. 127681b2a36SB. J. Wyman * @param[in] bindDelay - Time in milliseconds to delay binding the device 128681b2a36SB. J. Wyman * driver after seeing the presence line go active. 1293f1242f3SBrandon Wyman */ 1303f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1311d7a7df8SBrandon Wyman 1321d7a7df8SBrandon Wyman // Try where inventory path is empty, constructor should fail. 1331d7a7df8SBrandon Wyman try 1341d7a7df8SBrandon Wyman { 135681b2a36SB. J. Wyman auto psu = 136681b2a36SB. J. Wyman std::make_unique<PowerSupply>(bus, "", 3, 0x68, PSUGPIOLineName); 1371d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have reached this line."; 1381d7a7df8SBrandon Wyman } 1391d7a7df8SBrandon Wyman catch (const std::invalid_argument& e) 1401d7a7df8SBrandon Wyman { 1411d7a7df8SBrandon Wyman EXPECT_STREQ(e.what(), "Invalid empty inventoryPath"); 1421d7a7df8SBrandon Wyman } 1431d7a7df8SBrandon Wyman catch (...) 1441d7a7df8SBrandon Wyman { 1451d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 1461d7a7df8SBrandon Wyman } 1471d7a7df8SBrandon Wyman 148681b2a36SB. J. Wyman // TODO: Try invalid i2c address? 149681b2a36SB. J. Wyman 150681b2a36SB. J. Wyman // Try where gpioLineName is empty. 1511d7a7df8SBrandon Wyman try 1521d7a7df8SBrandon Wyman { 1531d7a7df8SBrandon Wyman auto psu = 154681b2a36SB. J. Wyman std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, ""); 155681b2a36SB. J. Wyman ADD_FAILURE() 156681b2a36SB. J. Wyman << "Should not have reached this line. Invalid gpioLineName."; 157681b2a36SB. J. Wyman } 158681b2a36SB. J. Wyman catch (const std::invalid_argument& e) 159681b2a36SB. J. Wyman { 160681b2a36SB. J. Wyman EXPECT_STREQ(e.what(), "Invalid empty gpioLineName"); 161681b2a36SB. J. Wyman } 162681b2a36SB. J. Wyman catch (...) 163681b2a36SB. J. Wyman { 164681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 165681b2a36SB. J. Wyman } 166681b2a36SB. J. Wyman 167681b2a36SB. J. Wyman // Test with valid arguments 168681b2a36SB. J. Wyman // NOT using D-Bus inventory path for presence. 169681b2a36SB. J. Wyman try 170681b2a36SB. J. Wyman { 171681b2a36SB. J. Wyman auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, 172681b2a36SB. J. Wyman PSUGPIOLineName); 1733f1242f3SBrandon Wyman 1743f1242f3SBrandon Wyman EXPECT_EQ(psu->isPresent(), false); 1753f1242f3SBrandon Wyman EXPECT_EQ(psu->isFaulted(), false); 1768da35c51SBrandon Wyman EXPECT_EQ(psu->hasCommFault(), false); 1773f1242f3SBrandon Wyman EXPECT_EQ(psu->hasInputFault(), false); 1783f1242f3SBrandon Wyman EXPECT_EQ(psu->hasMFRFault(), false); 1793f1242f3SBrandon Wyman EXPECT_EQ(psu->hasVINUVFault(), false); 1806710ba2cSBrandon Wyman EXPECT_EQ(psu->hasVoutOVFault(), false); 181b10b3be0SBrandon Wyman EXPECT_EQ(psu->hasIoutOCFault(), false); 1822cf46945SBrandon Wyman EXPECT_EQ(psu->hasVoutUVFault(), false); 1837ee4d7e4SBrandon Wyman EXPECT_EQ(psu->hasFanFault(), false); 18496893a46SBrandon Wyman EXPECT_EQ(psu->hasTempFault(), false); 1852916ea52SBrandon Wyman EXPECT_EQ(psu->hasPgoodFault(), false); 18639ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPSKillFault(), false); 18739ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPS12VcsFault(), false); 18839ea02bcSBrandon Wyman EXPECT_EQ(psu->hasPSCS12VFault(), false); 1893f1242f3SBrandon Wyman } 1901d7a7df8SBrandon Wyman catch (...) 1911d7a7df8SBrandon Wyman { 1921d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 1931d7a7df8SBrandon Wyman } 194681b2a36SB. J. Wyman 195681b2a36SB. J. Wyman // Test with valid arguments 196681b2a36SB. J. Wyman // TODO: Using D-Bus inventory path for presence. 197681b2a36SB. J. Wyman try 198681b2a36SB. J. Wyman { 199681b2a36SB. J. Wyman // FIXME: How do I get that presenceGPIO.read() in the startup to throw 200681b2a36SB. J. Wyman // an exception? 201681b2a36SB. J. Wyman 202681b2a36SB. J. Wyman // EXPECT_CALL(mockedUtil, getPresence(_, 203681b2a36SB. J. Wyman // StrEq(PSUInventoryPath))) 204681b2a36SB. J. Wyman // .Times(1); 205681b2a36SB. J. Wyman } 206681b2a36SB. J. Wyman catch (...) 207681b2a36SB. J. Wyman { 208681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 209681b2a36SB. J. Wyman } 2101d7a7df8SBrandon Wyman } 2113f1242f3SBrandon Wyman 2123f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Analyze) 2133f1242f3SBrandon Wyman { 2143f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2153f1242f3SBrandon Wyman 216b654c619SBrandon Wyman { 217681b2a36SB. J. Wyman // If I default to reading the GPIO, I will NOT expect a call to 218681b2a36SB. J. Wyman // getPresence(). 219681b2a36SB. J. Wyman 220681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName}; 2213ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 2223ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 223681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0)); 224681b2a36SB. J. Wyman 2253f1242f3SBrandon Wyman psu.analyze(); 2263f1242f3SBrandon Wyman // By default, nothing should change. 2273f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 2283f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 2293f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 2303f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 2313f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 23285c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 2336710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 234b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 2352cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 2367ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 23796893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 2382916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 23939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 24039ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 24139ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 242b654c619SBrandon Wyman } 2433f1242f3SBrandon Wyman 244681b2a36SB. J. Wyman PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName}; 245681b2a36SB. J. Wyman // In order to get the various faults tested, the power supply needs to 246681b2a36SB. J. Wyman // be present in order to read from the PMBus device(s). 2473ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO2 = 2483ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO()); 24906ca4590SBrandon Wyman // Always return 1 to indicate present. 25006ca4590SBrandon Wyman // Each analyze() call will trigger a read of the presence GPIO. 25106ca4590SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO2, read()).WillRepeatedly(Return(1)); 252681b2a36SB. J. Wyman EXPECT_EQ(psu2.isPresent(), false); 2533f1242f3SBrandon Wyman 2543f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus()); 255391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 256b654c619SBrandon Wyman 257b654c619SBrandon Wyman // STATUS_WORD INPUT fault. 258b654c619SBrandon Wyman { 259b654c619SBrandon Wyman // Start with STATUS_WORD 0x0000. Powered on, no faults. 260b654c619SBrandon Wyman // Set expectations for a no fault 261b654c619SBrandon Wyman PMBusExpectations expectations; 262b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 26382affd94SBrandon Wyman // After reading STATUS_WORD, etc., there will be a READ_VIN check. 26482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 26582affd94SBrandon Wyman .Times(1) 26682affd94SBrandon Wyman .WillOnce(Return("206000")); 2673f1242f3SBrandon Wyman psu2.analyze(); 2683f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2693f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 2703f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 2713f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 2723f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 27385c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 2746710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 275b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 2762cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 2777ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 27896893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 2792916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 28039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 28139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 28239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 2833f1242f3SBrandon Wyman 284b654c619SBrandon Wyman // Update expectations for STATUS_WORD input fault/warn 28596893a46SBrandon Wyman // STATUS_INPUT fault bits ... on. 286b654c619SBrandon Wyman expectations.statusWordValue = (status_word::INPUT_FAULT_WARN); 287*3225a45cSBrandon Wyman // IIN_OC fault. 288*3225a45cSBrandon Wyman expectations.statusInputValue = 0x04; 289c2906f47SBrandon Wyman 290c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 291c2906f47SBrandon Wyman { 292b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 29382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 29482affd94SBrandon Wyman .Times(1) 29582affd94SBrandon Wyman .WillOnce(Return("207000")); 2963f1242f3SBrandon Wyman psu2.analyze(); 2973f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 298c2906f47SBrandon Wyman // Should not be faulted until it reaches the deglitch limit. 299c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 300c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT); 3013f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 3023f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 30385c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 3046710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 305b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 3062cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 3077ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 30896893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 3092916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 31039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 31139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 31239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 313b654c619SBrandon Wyman } 314c2906f47SBrandon Wyman } 315c2906f47SBrandon Wyman 31632453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 317*3225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 318*3225a45cSBrandon Wyman .Times(1) 319*3225a45cSBrandon Wyman .WillOnce(Return(1)); 320c2906f47SBrandon Wyman psu2.clearFaults(); 3213f1242f3SBrandon Wyman 3223f1242f3SBrandon Wyman // STATUS_WORD INPUT/UV fault. 323b654c619SBrandon Wyman { 3243f1242f3SBrandon Wyman // First need it to return good status, then the fault 325b654c619SBrandon Wyman PMBusExpectations expectations; 326b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 32782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 32882affd94SBrandon Wyman .Times(1) 32982affd94SBrandon Wyman .WillOnce(Return("208000")); 3303f1242f3SBrandon Wyman psu2.analyze(); 331c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 332c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 3338da35c51SBrandon Wyman // Now set fault bits in STATUS_WORD 334b654c619SBrandon Wyman expectations.statusWordValue = 3358da35c51SBrandon Wyman (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT); 3368da35c51SBrandon Wyman // STATUS_INPUT fault bits ... on. 337*3225a45cSBrandon Wyman expectations.statusInputValue = 0x18; 338c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 339c2906f47SBrandon Wyman { 340b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 34182affd94SBrandon Wyman // Input/UV fault, so voltage should read back low. 34282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 34382affd94SBrandon Wyman .Times(1) 34482affd94SBrandon Wyman .WillOnce(Return("19123")); 3453f1242f3SBrandon Wyman psu2.analyze(); 3463f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 347c2906f47SBrandon Wyman // Only faulted if hit deglitch limit 348c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 349c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT); 350c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), x >= DEGLITCH_LIMIT); 3513f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 35285c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 3536710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 354b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 3552cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 3567ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 35796893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 3582916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 35939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 36039ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 36139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 362c2906f47SBrandon Wyman } 36382affd94SBrandon Wyman // Turning VIN_UV fault off causes clearing of faults, causing read of 36482affd94SBrandon Wyman // in1_input as an attempt to get CLEAR_FAULTS called. 36582affd94SBrandon Wyman expectations.statusWordValue = 0; 36682affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 36782affd94SBrandon Wyman // The call to read the voltage 36882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 36982affd94SBrandon Wyman .Times(1) 37082affd94SBrandon Wyman .WillOnce(Return("209000")); 371*3225a45cSBrandon Wyman // The call to clear VIN_UV/Off fault(s) 372*3225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 37332453e9bSBrandon Wyman .Times(1) 374*3225a45cSBrandon Wyman .WillOnce(Return(1)); 37582affd94SBrandon Wyman psu2.analyze(); 37682affd94SBrandon Wyman // Should remain present, no longer be faulted, no input fault, no 37782affd94SBrandon Wyman // VIN_UV fault. Nothing else should change. 37882affd94SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 37982affd94SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 38082affd94SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 38182affd94SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 382b654c619SBrandon Wyman } 3833f1242f3SBrandon Wyman 38432453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 385*3225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 386*3225a45cSBrandon Wyman .Times(1) 387*3225a45cSBrandon Wyman .WillOnce(Return(1)); 388c2906f47SBrandon Wyman psu2.clearFaults(); 389c2906f47SBrandon Wyman 3903f1242f3SBrandon Wyman // STATUS_WORD MFR fault. 391b654c619SBrandon Wyman { 392f07bc797SBrandon Wyman // First need it to return good status, then the fault 393b654c619SBrandon Wyman PMBusExpectations expectations; 394b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 39582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 39682affd94SBrandon Wyman .Times(1) 39782affd94SBrandon Wyman .WillOnce(Return("210000")); 3983f1242f3SBrandon Wyman psu2.analyze(); 3998da35c51SBrandon Wyman // Now STATUS_WORD with MFR fault bit on. 400b654c619SBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 4018da35c51SBrandon Wyman // STATUS_MFR bits on. 402b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 403c2906f47SBrandon Wyman 404c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 405c2906f47SBrandon Wyman { 406b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 40782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 40882affd94SBrandon Wyman .Times(1) 40982affd94SBrandon Wyman .WillOnce(Return("211000")); 4103f1242f3SBrandon Wyman psu2.analyze(); 4113f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 412c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 4133f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 414c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), x >= DEGLITCH_LIMIT); 415c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), x >= DEGLITCH_LIMIT); 416c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 417c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 4183f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 41985c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 4206710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 421b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 4222cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 4237ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 42496893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 4252916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 426c2906f47SBrandon Wyman } 427b654c619SBrandon Wyman } 4283f1242f3SBrandon Wyman 42932453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 430*3225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 431*3225a45cSBrandon Wyman .Times(1) 432*3225a45cSBrandon Wyman .WillOnce(Return(1)); 433c2906f47SBrandon Wyman psu2.clearFaults(); 434*3225a45cSBrandon Wyman 43596893a46SBrandon Wyman // Temperature fault. 436b654c619SBrandon Wyman { 437f07bc797SBrandon Wyman // First STATUS_WORD with no bits set, then with temperature fault. 438b654c619SBrandon Wyman PMBusExpectations expectations; 439b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 44082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 44182affd94SBrandon Wyman .Times(1) 44282affd94SBrandon Wyman .WillOnce(Return("212000")); 4433f1242f3SBrandon Wyman psu2.analyze(); 4448da35c51SBrandon Wyman // STATUS_WORD with temperature fault bit on. 445b654c619SBrandon Wyman expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 44696893a46SBrandon Wyman // STATUS_TEMPERATURE with fault bit(s) on. 44796893a46SBrandon Wyman expectations.statusTempValue = 0x10; 448c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 449c2906f47SBrandon Wyman { 450b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 45182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 45282affd94SBrandon Wyman .Times(1) 45382affd94SBrandon Wyman .WillOnce(Return("213000")); 4543f1242f3SBrandon Wyman psu2.analyze(); 4553f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 456c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 4573f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 4583f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 4593f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 46085c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 4616710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 462b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 4632cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 4647ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 465c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), x >= DEGLITCH_LIMIT); 4662916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 46739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 46839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 46939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 470b654c619SBrandon Wyman } 471c2906f47SBrandon Wyman } 47285c7bf41SBrandon Wyman 47332453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 474*3225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 475*3225a45cSBrandon Wyman .Times(1) 476*3225a45cSBrandon Wyman .WillOnce(Return(1)); 477c2906f47SBrandon Wyman psu2.clearFaults(); 478*3225a45cSBrandon Wyman 47985c7bf41SBrandon Wyman // CML fault 480b654c619SBrandon Wyman { 48185c7bf41SBrandon Wyman // First STATUS_WORD wit no bits set, then with CML fault. 482b654c619SBrandon Wyman PMBusExpectations expectations; 483b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 48482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 48582affd94SBrandon Wyman .Times(1) 48682affd94SBrandon Wyman .WillOnce(Return("214000")); 48785c7bf41SBrandon Wyman psu2.analyze(); 4888da35c51SBrandon Wyman // STATUS_WORD with CML fault bit on. 489b654c619SBrandon Wyman expectations.statusWordValue = (status_word::CML_FAULT); 49085c7bf41SBrandon Wyman // Turn on STATUS_CML fault bit(s) 491b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 492c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 493c2906f47SBrandon Wyman { 494b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 49582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 49682affd94SBrandon Wyman .Times(1) 49782affd94SBrandon Wyman .WillOnce(Return("215000")); 49885c7bf41SBrandon Wyman psu2.analyze(); 49985c7bf41SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 500c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 501c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), x >= DEGLITCH_LIMIT); 50285c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 50385c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 50485c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 5056710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 506b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 5072cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 5087ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 50996893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 5102916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 51139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 51239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 51339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 514b654c619SBrandon Wyman } 515c2906f47SBrandon Wyman } 5166710ba2cSBrandon Wyman 51732453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1)); 518*3225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 519*3225a45cSBrandon Wyman .Times(1) 520*3225a45cSBrandon Wyman .WillOnce(Return(1)); 521c2906f47SBrandon Wyman psu2.clearFaults(); 522*3225a45cSBrandon Wyman 5236710ba2cSBrandon Wyman // VOUT_OV_FAULT fault 524b654c619SBrandon Wyman { 5256710ba2cSBrandon Wyman // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault. 526b654c619SBrandon Wyman PMBusExpectations expectations; 527b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 52882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 52982affd94SBrandon Wyman .Times(1) 53082affd94SBrandon Wyman .WillOnce(Return("216000")); 5316710ba2cSBrandon Wyman psu2.analyze(); 5326710ba2cSBrandon Wyman // STATUS_WORD with VOUT/VOUT_OV fault. 533b654c619SBrandon Wyman expectations.statusWordValue = 5346710ba2cSBrandon Wyman ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT)); 5356710ba2cSBrandon Wyman // Turn on STATUS_VOUT fault bit(s) 536b654c619SBrandon Wyman expectations.statusVOUTValue = 0xA0; 537c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 538c2906f47SBrandon Wyman { 53996893a46SBrandon Wyman // STATUS_TEMPERATURE don't care (default) 540b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 54182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 54282affd94SBrandon Wyman .Times(1) 54382affd94SBrandon Wyman .WillOnce(Return("217000")); 5446710ba2cSBrandon Wyman psu2.analyze(); 5456710ba2cSBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 546c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 5476710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 5486710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 5496710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 5506710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 551c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 5522cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 553b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 5547ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 555b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 556b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 55739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 55839ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 55939ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 560b10b3be0SBrandon Wyman } 561c2906f47SBrandon Wyman } 562b10b3be0SBrandon Wyman 563b10b3be0SBrandon Wyman // IOUT_OC_FAULT fault 564b10b3be0SBrandon Wyman { 565b10b3be0SBrandon Wyman // First STATUS_WORD with no bits set, then with IOUT_OC fault. 566b10b3be0SBrandon Wyman PMBusExpectations expectations; 567b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 56882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 56982affd94SBrandon Wyman .Times(1) 57082affd94SBrandon Wyman .WillOnce(Return("218000")); 571b10b3be0SBrandon Wyman psu2.analyze(); 572b10b3be0SBrandon Wyman // STATUS_WORD with IOUT_OC fault. 573b10b3be0SBrandon Wyman expectations.statusWordValue = status_word::IOUT_OC_FAULT; 574b10b3be0SBrandon Wyman // Turn on STATUS_IOUT fault bit(s) 575b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0x88; 576c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 577c2906f47SBrandon Wyman { 578b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 57982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 58082affd94SBrandon Wyman .Times(1) 58182affd94SBrandon Wyman .WillOnce(Return("219000")); 582b10b3be0SBrandon Wyman psu2.analyze(); 583b10b3be0SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 584c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 585b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 586b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 587b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 588b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 589b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 590c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 5912cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 5927ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 5932cf46945SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 5942cf46945SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 59539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 59639ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 59739ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 5982cf46945SBrandon Wyman } 599c2906f47SBrandon Wyman } 6002cf46945SBrandon Wyman 6012cf46945SBrandon Wyman // VOUT_UV_FAULT 6022cf46945SBrandon Wyman { 6032cf46945SBrandon Wyman // First STATUS_WORD with no bits set, then with VOUT fault. 6042cf46945SBrandon Wyman PMBusExpectations expectations; 6052cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 60682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 60782affd94SBrandon Wyman .Times(1) 60882affd94SBrandon Wyman .WillOnce(Return("220000")); 6092cf46945SBrandon Wyman psu2.analyze(); 6102cf46945SBrandon Wyman // Change STATUS_WORD to indicate VOUT fault. 6112cf46945SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_FAULT); 6122cf46945SBrandon Wyman // Turn on STATUS_VOUT fault bit(s) 6132cf46945SBrandon Wyman expectations.statusVOUTValue = 0x30; 614c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 615c2906f47SBrandon Wyman { 6162cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 61782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 61882affd94SBrandon Wyman .Times(1) 61982affd94SBrandon Wyman .WillOnce(Return("221000")); 6202cf46945SBrandon Wyman psu2.analyze(); 6212cf46945SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 622c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 6232cf46945SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 6242cf46945SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 6252cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 6262cf46945SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 6272cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 6282cf46945SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 629c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), x >= DEGLITCH_LIMIT); 6307ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 63196893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6322916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 63339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 63439ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 63539ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 636b654c619SBrandon Wyman } 637c2906f47SBrandon Wyman } 6383f1242f3SBrandon Wyman 6397ee4d7e4SBrandon Wyman // Fan fault 640b654c619SBrandon Wyman { 641b654c619SBrandon Wyman // First STATUS_WORD with no bits set, then with fan fault. 642b654c619SBrandon Wyman PMBusExpectations expectations; 643b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 64482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 64582affd94SBrandon Wyman .Times(1) 64682affd94SBrandon Wyman .WillOnce(Return("222000")); 6473f1242f3SBrandon Wyman psu2.analyze(); 648b654c619SBrandon Wyman expectations.statusWordValue = (status_word::FAN_FAULT); 6497ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with fan 1 warning & fault bits on. 6507ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xA0; 651c2906f47SBrandon Wyman 652c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 653c2906f47SBrandon Wyman { 654b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 65582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 65682affd94SBrandon Wyman .Times(1) 65782affd94SBrandon Wyman .WillOnce(Return("223000")); 6583f1242f3SBrandon Wyman psu2.analyze(); 6593f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 660c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 661c2906f47SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), x >= DEGLITCH_LIMIT); 6623f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 6633f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 6643f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 66585c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 6666710ba2cSBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 667b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 6682cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 66996893a46SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 6702916ea52SBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), false); 67139ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSKillFault(), false); 67239ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPS12VcsFault(), false); 67339ea02bcSBrandon Wyman EXPECT_EQ(psu2.hasPSCS12VFault(), false); 674b654c619SBrandon Wyman } 675c2906f47SBrandon Wyman } 6762916ea52SBrandon Wyman 67706ca4590SBrandon Wyman // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT. 6782cf46945SBrandon Wyman { 6792916ea52SBrandon Wyman // First STATUS_WORD with no bits set. 6802916ea52SBrandon Wyman PMBusExpectations expectations; 6812916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 68282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 68382affd94SBrandon Wyman .Times(1) 68482affd94SBrandon Wyman .WillOnce(Return("123000")); 6852916ea52SBrandon Wyman psu2.analyze(); 6862916ea52SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 6872916ea52SBrandon Wyman // POWER_GOOD# inactive, and OFF bit on. 6882916ea52SBrandon Wyman expectations.statusWordValue = 6892916ea52SBrandon Wyman ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF)); 69006ca4590SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 69106ca4590SBrandon Wyman { 6922916ea52SBrandon Wyman // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and 6932916ea52SBrandon Wyman // STATUS_TEMPERATURE: Don't care if bits set or not (defaults). 6942916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 69582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 69682affd94SBrandon Wyman .Times(1) 69782affd94SBrandon Wyman .WillOnce(Return("124000")); 6982916ea52SBrandon Wyman psu2.analyze(); 6992916ea52SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 700c2906f47SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT); 7012916ea52SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 7022916ea52SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 7032916ea52SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 7042916ea52SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 7052916ea52SBrandon Wyman EXPECT_EQ(psu2.hasVoutOVFault(), false); 7062cf46945SBrandon Wyman EXPECT_EQ(psu2.hasVoutUVFault(), false); 707b10b3be0SBrandon Wyman EXPECT_EQ(psu2.hasIoutOCFault(), false); 7087ee4d7e4SBrandon Wyman EXPECT_EQ(psu2.hasFanFault(), false); 7092916ea52SBrandon Wyman EXPECT_EQ(psu2.hasTempFault(), false); 71032453e9bSBrandon Wyman EXPECT_EQ(psu2.hasPgoodFault(), x >= DEGLITCH_LIMIT); 71106ca4590SBrandon Wyman } 71206ca4590SBrandon Wyman } 7132916ea52SBrandon Wyman 7143f1242f3SBrandon Wyman // TODO: ReadFailure 7153f1242f3SBrandon Wyman } 7163f1242f3SBrandon Wyman 71759a35793SBrandon Wyman TEST_F(PowerSupplyTests, OnOffConfig) 71859a35793SBrandon Wyman { 71959a35793SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 72059a35793SBrandon Wyman uint8_t data = 0x15; 72159a35793SBrandon Wyman 72259a35793SBrandon Wyman // Test where PSU is NOT present 72359a35793SBrandon Wyman try 72459a35793SBrandon Wyman { 725681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 7260975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, _)).Times(0); 727681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName}; 728681b2a36SB. J. Wyman 7293ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7303ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 731681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0)); 73259a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 733681b2a36SB. J. Wyman // Constructor should set initial presence, default read returns 0. 73459a35793SBrandon Wyman // If it is not present, I should not be trying to write to it. 73559a35793SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0); 73659a35793SBrandon Wyman psu.onOffConfig(data); 73759a35793SBrandon Wyman } 73859a35793SBrandon Wyman catch (...) 7390c9a33d6SAdriana Kobylak {} 74059a35793SBrandon Wyman 74159a35793SBrandon Wyman // Test where PSU is present 74259a35793SBrandon Wyman try 74359a35793SBrandon Wyman { 744681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 7450975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 746681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName}; 7473ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7483ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 749391a0690SBrandon Wyman // There will potentially be multiple calls, we want it to continue 750391a0690SBrandon Wyman // returning 1 for the GPIO read to keep the power supply present. 751391a0690SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 75259a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 753391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 754391a0690SBrandon Wyman // If I am calling analyze(), I should probably give it good data. 755391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 756391a0690SBrandon Wyman PMBusExpectations expectations; 757391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 75882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 75982affd94SBrandon Wyman .Times(1) 76082affd94SBrandon Wyman .WillOnce(Return("205000")); 761681b2a36SB. J. Wyman psu.analyze(); 762391a0690SBrandon Wyman // I definitely should be writting ON_OFF_CONFIG if I call the function 763391a0690SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, ElementsAre(0x15), 764391a0690SBrandon Wyman Type::HwmonDeviceDebug)) 76559a35793SBrandon Wyman .Times(1); 76659a35793SBrandon Wyman psu.onOffConfig(data); 76759a35793SBrandon Wyman } 76859a35793SBrandon Wyman catch (...) 7690c9a33d6SAdriana Kobylak {} 77059a35793SBrandon Wyman } 77159a35793SBrandon Wyman 7723f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, ClearFaults) 7733f1242f3SBrandon Wyman { 7743f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 775681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, PSUGPIOLineName}; 7763ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 7773ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 77806ca4590SBrandon Wyman // Always return 1 to indicate present. 77906ca4590SBrandon Wyman // Each analyze() call will trigger a read of the presence GPIO. 78006ca4590SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 781681b2a36SB. J. Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 782391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 7838da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 784b654c619SBrandon Wyman PMBusExpectations expectations; 785b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 78682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 78782affd94SBrandon Wyman .Times(1) 78882affd94SBrandon Wyman .WillOnce(Return("207000")); 789681b2a36SB. J. Wyman psu.analyze(); 7903f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 7913f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 7923f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 7933f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 7943f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 79585c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 7966710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 797b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 7982cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 7997ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 80096893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 8012916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 80239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 80339ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 80439ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 805b654c619SBrandon Wyman 806f07bc797SBrandon Wyman // STATUS_WORD with fault bits galore! 807b654c619SBrandon Wyman expectations.statusWordValue = 0xFFFF; 808f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 809b654c619SBrandon Wyman expectations.statusInputValue = 0xFF; 810f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 811b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 81285c7bf41SBrandon Wyman // STATUS_CML with bits on. 813b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 8146710ba2cSBrandon Wyman // STATUS_VOUT with bits on. 815b654c619SBrandon Wyman expectations.statusVOUTValue = 0xFF; 816b10b3be0SBrandon Wyman // STATUS_IOUT with bits on. 817b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0xFF; 8187ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with bits on. 8197ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xFF; 82096893a46SBrandon Wyman // STATUS_TEMPERATURE with bits on. 82196893a46SBrandon Wyman expectations.statusTempValue = 0xFF; 822c2906f47SBrandon Wyman 823c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 824c2906f47SBrandon Wyman { 825b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 82682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 82782affd94SBrandon Wyman .Times(1) 82882affd94SBrandon Wyman .WillOnce(Return("0")); 8290975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 8300975eaf4SMatt Spinler { 8310975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 8320975eaf4SMatt Spinler } 8333f1242f3SBrandon Wyman psu.analyze(); 8343f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8352cf46945SBrandon Wyman // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT. 8362cf46945SBrandon Wyman // Rely on HasVoutUVFault() to verify this sets and clears. 8372cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 838c2906f47SBrandon Wyman // All faults are deglitched up to DEGLITCH_LIMIT 839c2906f47SBrandon Wyman EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT); 840c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 841c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 842c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 843c2906f47SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), x >= DEGLITCH_LIMIT); 844c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 845c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 846c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 847c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 848c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), x >= DEGLITCH_LIMIT); 849c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 850c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 851c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 852c2906f47SBrandon Wyman } 853c2906f47SBrandon Wyman 85432453e9bSBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)) 85532453e9bSBrandon Wyman .Times(1) 85632453e9bSBrandon Wyman .WillOnce(Return(207000)); 857*3225a45cSBrandon Wyman // Clearing VIN_UV fault via in1_lcrit_alarm 858*3225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 859*3225a45cSBrandon Wyman .Times(1) 860*3225a45cSBrandon Wyman .WillOnce(Return(1)); 8610975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 8623f1242f3SBrandon Wyman psu.clearFaults(); 8633f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 8643f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 8653f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 8663f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 8673f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 86885c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 8696710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 870b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 8712cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 8727ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 87396893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 8742916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 87539ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 87639ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 87739ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 878681b2a36SB. J. Wyman 87982affd94SBrandon Wyman // Faults clear on READ_VIN 0 -> !0 88082affd94SBrandon Wyman // STATUS_WORD with fault bits galore! 88182affd94SBrandon Wyman expectations.statusWordValue = 0xFFFF; 88282affd94SBrandon Wyman // STATUS_INPUT with fault bits on. 88382affd94SBrandon Wyman expectations.statusInputValue = 0xFF; 88482affd94SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 88582affd94SBrandon Wyman expectations.statusMFRValue = 0xFF; 88682affd94SBrandon Wyman // STATUS_CML with bits on. 88782affd94SBrandon Wyman expectations.statusCMLValue = 0xFF; 88882affd94SBrandon Wyman // STATUS_VOUT with bits on. 88982affd94SBrandon Wyman expectations.statusVOUTValue = 0xFF; 89082affd94SBrandon Wyman // STATUS_IOUT with bits on. 89182affd94SBrandon Wyman expectations.statusIOUTValue = 0xFF; 89282affd94SBrandon Wyman // STATUS_FANS_1_2 with bits on. 89382affd94SBrandon Wyman expectations.statusFans12Value = 0xFF; 89482affd94SBrandon Wyman // STATUS_TEMPERATURE with bits on. 89582affd94SBrandon Wyman expectations.statusTempValue = 0xFF; 896c2906f47SBrandon Wyman 897c2906f47SBrandon Wyman // All faults degltiched now. Check for false before limit above. 898c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 899c2906f47SBrandon Wyman { 90082affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 90182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 90282affd94SBrandon Wyman .Times(1) 90382affd94SBrandon Wyman .WillOnce(Return("0")); 9040975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 9050975eaf4SMatt Spinler { 9060975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 9070975eaf4SMatt Spinler } 90882affd94SBrandon Wyman psu.analyze(); 909c2906f47SBrandon Wyman } 910c2906f47SBrandon Wyman 91182affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 91282affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 91382affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 91482affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 91582affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 91682affd94SBrandon Wyman // True due to CML fault bits on 91782affd94SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), true); 91882affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 91982affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), true); 92082affd94SBrandon Wyman // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT. 92182affd94SBrandon Wyman // Rely on HasVoutUVFault() to verify this sets and clears. 92282affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 92382affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), true); 92482affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), true); 925c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 92682affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), true); 92782affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), true); 92882affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), true); 92982affd94SBrandon Wyman // STATUS_WORD with INPUT/VIN_UV fault bits off. 93082affd94SBrandon Wyman expectations.statusWordValue = 0xDFF7; 93182affd94SBrandon Wyman // STATUS_INPUT with VIN_UV_WARNING, VIN_UV_FAULT, and Unit Off For 93282affd94SBrandon Wyman // Insufficient Input Voltage bits off. 93382affd94SBrandon Wyman expectations.statusInputValue = 0xC7; 93482affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 93582affd94SBrandon Wyman // READ_VIN back in range. 93682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 93782affd94SBrandon Wyman .Times(1) 93882affd94SBrandon Wyman .WillOnce(Return("206000")); 939*3225a45cSBrandon Wyman // VIN_UV cleared via in1_lcrit_alarm when voltage back in range. 940*3225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 941*3225a45cSBrandon Wyman .Times(1) 942*3225a45cSBrandon Wyman .WillOnce(Return(1)); 943*3225a45cSBrandon Wyman psu.analyze(); 944*3225a45cSBrandon Wyman // We only cleared the VIN_UV and OFF faults. 945*3225a45cSBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 946*3225a45cSBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 947*3225a45cSBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 948*3225a45cSBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 949*3225a45cSBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 950*3225a45cSBrandon Wyman EXPECT_EQ(psu.hasCommFault(), true); 951*3225a45cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), true); 952*3225a45cSBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), true); 953*3225a45cSBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 954*3225a45cSBrandon Wyman EXPECT_EQ(psu.hasFanFault(), true); 955*3225a45cSBrandon Wyman EXPECT_EQ(psu.hasTempFault(), true); 956*3225a45cSBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 957*3225a45cSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), true); 958*3225a45cSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), true); 959*3225a45cSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), true); 960*3225a45cSBrandon Wyman 961*3225a45cSBrandon Wyman // All faults cleared 962*3225a45cSBrandon Wyman expectations = {0}; 963*3225a45cSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 964*3225a45cSBrandon Wyman // READ_VIN back in range. 965*3225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 966*3225a45cSBrandon Wyman .Times(1) 967*3225a45cSBrandon Wyman .WillOnce(Return("206000")); 9680975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 96982affd94SBrandon Wyman psu.analyze(); 97082affd94SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 97182affd94SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 97282affd94SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 97382affd94SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 97482affd94SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 97582affd94SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 97682affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 97782affd94SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 97882affd94SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 97982affd94SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 98082affd94SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 98182affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 98282affd94SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 98382affd94SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 98482affd94SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 98582affd94SBrandon Wyman 986681b2a36SB. J. Wyman // TODO: Faults clear on missing/present? 9873f1242f3SBrandon Wyman } 9883f1242f3SBrandon Wyman 9893f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory) 9903f1242f3SBrandon Wyman { 9913f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 9921d7a7df8SBrandon Wyman 9931d7a7df8SBrandon Wyman try 9941d7a7df8SBrandon Wyman { 995681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 9961d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 9971d7a7df8SBrandon Wyman // If it is not present, I should not be trying to read a string 9981d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).Times(0); 9991d7a7df8SBrandon Wyman psu.updateInventory(); 10001d7a7df8SBrandon Wyman } 10011d7a7df8SBrandon Wyman catch (...) 10021d7a7df8SBrandon Wyman { 10031d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 10041d7a7df8SBrandon Wyman } 10051d7a7df8SBrandon Wyman 10061d7a7df8SBrandon Wyman try 10071d7a7df8SBrandon Wyman { 1008681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, PSUGPIOLineName}; 10093ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10103ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1011681b2a36SB. J. Wyman // GPIO read return 1 to indicate present. 1012681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 10131d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1014391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1015391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1016391a0690SBrandon Wyman PMBusExpectations expectations; 1017391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 101882affd94SBrandon Wyman // Call to analyze will read voltage, trigger clear faults for 0 to 101982affd94SBrandon Wyman // within range. 102082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 102182affd94SBrandon Wyman .Times(1) 102282affd94SBrandon Wyman .WillOnce(Return("123456")); 1023391a0690SBrandon Wyman psu.analyze(); 10241d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return("")); 10253f1242f3SBrandon Wyman psu.updateInventory(); 10261d7a7df8SBrandon Wyman 10273c530fbdSBrandon Wyman #if IBM_VPD 10281d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)) 10291d7a7df8SBrandon Wyman .WillOnce(Return("CCIN")) 10301d7a7df8SBrandon Wyman .WillOnce(Return("PN3456")) 10311d7a7df8SBrandon Wyman .WillOnce(Return("FN3456")) 10321d7a7df8SBrandon Wyman .WillOnce(Return("HEADER")) 10331d7a7df8SBrandon Wyman .WillOnce(Return("SN3456")) 10341d7a7df8SBrandon Wyman .WillOnce(Return("FW3456")); 10353c530fbdSBrandon Wyman #endif 10361d7a7df8SBrandon Wyman psu.updateInventory(); 10371d7a7df8SBrandon Wyman // TODO: D-Bus mocking to verify values stored on D-Bus (???) 10381d7a7df8SBrandon Wyman } 10391d7a7df8SBrandon Wyman catch (...) 10401d7a7df8SBrandon Wyman { 10411d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 10421d7a7df8SBrandon Wyman } 10433f1242f3SBrandon Wyman } 10443f1242f3SBrandon Wyman 10453f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent) 10463f1242f3SBrandon Wyman { 10473f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1048681b2a36SB. J. Wyman 1049681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 10503ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10513ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 10523f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 10533f1242f3SBrandon Wyman 1054681b2a36SB. J. Wyman // Change GPIO read to return 1 to indicate present. 1055681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 1056391a0690SBrandon Wyman // Call to analyze() will update to present, that will trigger updating 1057391a0690SBrandon Wyman // to the correct/latest HWMON directory, in case it changes. 1058391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1059391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1060391a0690SBrandon Wyman // Call to analyze things will trigger read of STATUS_WORD and READ_VIN. 1061391a0690SBrandon Wyman // Default expectations will be on, no faults. 1062391a0690SBrandon Wyman PMBusExpectations expectations; 1063391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 106482affd94SBrandon Wyman // Give it an input voltage in the 100-volt range. 106582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 106682affd94SBrandon Wyman .Times(1) 106782affd94SBrandon Wyman .WillOnce(Return("123456")); 10680975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1069681b2a36SB. J. Wyman psu.analyze(); 1070681b2a36SB. J. Wyman EXPECT_EQ(psu.isPresent(), true); 10713f1242f3SBrandon Wyman } 10723f1242f3SBrandon Wyman 10733f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted) 10743f1242f3SBrandon Wyman { 10753f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1076681b2a36SB. J. Wyman 1077681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, PSUGPIOLineName}; 10783ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 10793ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1080681b2a36SB. J. Wyman // Always return 1 to indicate present. 1081681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1082391a0690SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1083391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1084391a0690SBrandon Wyman // Call to analyze things will trigger read of STATUS_WORD and READ_VIN. 1085391a0690SBrandon Wyman // Default expectations will be on, no faults. 1086391a0690SBrandon Wyman PMBusExpectations expectations; 1087391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 108882affd94SBrandon Wyman // Give it an input voltage in the 100-volt range. 108982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 109082affd94SBrandon Wyman .Times(1) 109182affd94SBrandon Wyman .WillOnce(Return("124680")); 1092681b2a36SB. J. Wyman psu.analyze(); 10933f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 1094f07bc797SBrandon Wyman // STATUS_WORD with fault bits on. 1095b654c619SBrandon Wyman expectations.statusWordValue = 0xFFFF; 1096f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 1097b654c619SBrandon Wyman expectations.statusInputValue = 0xFF; 1098f07bc797SBrandon Wyman // STATUS_MFR_SPECIFIC with faults bits on. 1099b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 110085c7bf41SBrandon Wyman // STATUS_CML with faults bits on. 1101b654c619SBrandon Wyman expectations.statusCMLValue = 0xFF; 11026710ba2cSBrandon Wyman // STATUS_VOUT with fault bits on. 1103b654c619SBrandon Wyman expectations.statusVOUTValue = 0xFF; 1104b10b3be0SBrandon Wyman // STATUS_IOUT with fault bits on. 1105b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0xFF; 11067ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 with bits on. 11077ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0xFF; 110896893a46SBrandon Wyman // STATUS_TEMPERATURE with fault bits on. 110996893a46SBrandon Wyman expectations.statusTempValue = 0xFF; 1110c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1111c2906f47SBrandon Wyman { 1112b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 11134fc191f0SBrandon Wyman // Also get another read of READ_VIN, faulted, so not in 100-volt range 111482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 111582affd94SBrandon Wyman .Times(1) 11164fc191f0SBrandon Wyman .WillOnce(Return("19000")); 11170975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 11180975eaf4SMatt Spinler { 11190975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 11200975eaf4SMatt Spinler } 11213f1242f3SBrandon Wyman psu.analyze(); 1122c2906f47SBrandon Wyman EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT); 1123c2906f47SBrandon Wyman } 11243f1242f3SBrandon Wyman } 11253f1242f3SBrandon Wyman 11263f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasInputFault) 11273f1242f3SBrandon Wyman { 11283f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1129681b2a36SB. J. Wyman 1130681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 11313ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 11323ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1133681b2a36SB. J. Wyman // Always return 1 to indicate present. 1134681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 11353f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1136391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 11378da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1138b654c619SBrandon Wyman PMBusExpectations expectations; 1139b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 114082affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 114182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 114282affd94SBrandon Wyman .Times(1) 114382affd94SBrandon Wyman .WillOnce(Return("201100")); 11443f1242f3SBrandon Wyman psu.analyze(); 11453f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 1146f07bc797SBrandon Wyman // STATUS_WORD with input fault/warn on. 1147b654c619SBrandon Wyman expectations.statusWordValue = (status_word::INPUT_FAULT_WARN); 1148f07bc797SBrandon Wyman // STATUS_INPUT with an input fault bit on. 1149b654c619SBrandon Wyman expectations.statusInputValue = 0x80; 1150c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1151c2906f47SBrandon Wyman { 1152b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 115382affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 115482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 115582affd94SBrandon Wyman .Times(1) 115682affd94SBrandon Wyman .WillOnce(Return("201200")); 11570975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 11580975eaf4SMatt Spinler { 11590975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 11600975eaf4SMatt Spinler } 11613f1242f3SBrandon Wyman psu.analyze(); 1162c2906f47SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT); 1163c2906f47SBrandon Wyman } 1164f07bc797SBrandon Wyman // STATUS_WORD with no bits on. 1165b654c619SBrandon Wyman expectations.statusWordValue = 0; 1166b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 116782affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 116882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 116982affd94SBrandon Wyman .Times(1) 117082affd94SBrandon Wyman .WillOnce(Return("201300")); 11710975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 11723f1242f3SBrandon Wyman psu.analyze(); 11733f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 11743f1242f3SBrandon Wyman } 11753f1242f3SBrandon Wyman 11763f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault) 11773f1242f3SBrandon Wyman { 11783f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1179681b2a36SB. J. Wyman 1180681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 11813ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 11823ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1183681b2a36SB. J. Wyman // Always return 1 to indicate present. 1184681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 11853f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1186391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1187f07bc797SBrandon Wyman // First return STATUS_WORD with no bits on. 11888da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1189b654c619SBrandon Wyman PMBusExpectations expectations; 1190b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 119182affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 119282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 119382affd94SBrandon Wyman .Times(1) 119482affd94SBrandon Wyman .WillOnce(Return("202100")); 11953f1242f3SBrandon Wyman psu.analyze(); 11963f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 1197f07bc797SBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 1198b654c619SBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 1199f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 1200b654c619SBrandon Wyman expectations.statusMFRValue = 0xFF; 1201c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1202c2906f47SBrandon Wyman { 1203b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 120482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 120582affd94SBrandon Wyman .Times(1) 120682affd94SBrandon Wyman .WillOnce(Return("202200")); 12073f1242f3SBrandon Wyman psu.analyze(); 1208c2906f47SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT); 1209c2906f47SBrandon Wyman } 1210f07bc797SBrandon Wyman // Back to no bits on in STATUS_WORD 1211b654c619SBrandon Wyman expectations.statusWordValue = 0; 1212b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 121382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 121482affd94SBrandon Wyman .Times(1) 121582affd94SBrandon Wyman .WillOnce(Return("202300")); 12163f1242f3SBrandon Wyman psu.analyze(); 12173f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 12183f1242f3SBrandon Wyman } 12193f1242f3SBrandon Wyman 12203f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault) 12213f1242f3SBrandon Wyman { 12223f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1223681b2a36SB. J. Wyman 1224681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 12253ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 12263ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1227681b2a36SB. J. Wyman // Always return 1 to indicate present. 1228681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 12293f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1230391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 123182affd94SBrandon Wyman 123282affd94SBrandon Wyman // Presence change from missing to present will trigger in1_input read in 123382affd94SBrandon Wyman // an attempt to get CLEAR_FAULTS called. Return value ignored. 123482affd94SBrandon Wyman // Zero to non-zero voltage, for missing/present change, triggers clear 123582affd94SBrandon Wyman // faults call again. Return value ignored. 123682affd94SBrandon Wyman // Fault (low voltage) to not faulted (voltage in range) triggers clear 123782affd94SBrandon Wyman // faults call a third time. 123882affd94SBrandon Wyman 12398da35c51SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1240b654c619SBrandon Wyman PMBusExpectations expectations; 1241b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 124282affd94SBrandon Wyman // Analyze call will also need good READ_VIN value to check. 124382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 124482affd94SBrandon Wyman .Times(1) 124582affd94SBrandon Wyman .WillOnce(Return("201100")); 12463f1242f3SBrandon Wyman psu.analyze(); 12473f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 1248f07bc797SBrandon Wyman // Turn fault on. 1249b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VIN_UV_FAULT); 125085c7bf41SBrandon Wyman // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by 125185c7bf41SBrandon Wyman // Figure 16, and assume bits on in STATUS_INPUT. 1252b654c619SBrandon Wyman expectations.statusInputValue = 0x18; 1253c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1254c2906f47SBrandon Wyman { 1255b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 125682affd94SBrandon Wyman // If there is a VIN_UV fault, fake reading voltage of less than 20V 125782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 125882affd94SBrandon Wyman .Times(1) 125982affd94SBrandon Wyman .WillOnce(Return("19876")); 12600975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 12610975eaf4SMatt Spinler { 12620975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 12630975eaf4SMatt Spinler } 12643f1242f3SBrandon Wyman psu.analyze(); 1265c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT); 1266c2906f47SBrandon Wyman } 1267f07bc797SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1268b654c619SBrandon Wyman expectations.statusWordValue = 0; 1269b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 127082affd94SBrandon Wyman // Updates now result in clearing faults if read voltage goes from below the 127182affd94SBrandon Wyman // minimum, to within a valid range. 127282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 127382affd94SBrandon Wyman .Times(1) 127482affd94SBrandon Wyman .WillOnce(Return("201300")); 1275*3225a45cSBrandon Wyman // Went from below minimum to within range, expect clearVinUVFault(). 1276*3225a45cSBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _)) 1277*3225a45cSBrandon Wyman .Times(1) 1278*3225a45cSBrandon Wyman .WillOnce(Return(1)); 12790975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 12803f1242f3SBrandon Wyman psu.analyze(); 12813f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 12823f1242f3SBrandon Wyman } 12836710ba2cSBrandon Wyman 12846710ba2cSBrandon Wyman TEST_F(PowerSupplyTests, HasVoutOVFault) 12856710ba2cSBrandon Wyman { 12866710ba2cSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 12876710ba2cSBrandon Wyman 12886710ba2cSBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x69, PSUGPIOLineName}; 12896710ba2cSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 12906710ba2cSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 12916710ba2cSBrandon Wyman // Always return 1 to indicate present. 12926710ba2cSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 12936710ba2cSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1294391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 12956710ba2cSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1296b654c619SBrandon Wyman PMBusExpectations expectations; 1297b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 129882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 129982affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 130082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 130182affd94SBrandon Wyman .Times(1) 130282affd94SBrandon Wyman .WillOnce(Return("202100")); 13036710ba2cSBrandon Wyman psu.analyze(); 13046710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 13056710ba2cSBrandon Wyman // Turn fault on. 1306b654c619SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_OV_FAULT); 13076710ba2cSBrandon Wyman // STATUS_VOUT fault bit(s) 1308b654c619SBrandon Wyman expectations.statusVOUTValue = 0x80; 1309c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1310c2906f47SBrandon Wyman { 1311b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 131282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 131382affd94SBrandon Wyman .Times(1) 131482affd94SBrandon Wyman .WillOnce(Return("202200")); 13156710ba2cSBrandon Wyman psu.analyze(); 1316c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT); 1317c2906f47SBrandon Wyman } 13186710ba2cSBrandon Wyman // Back to no fault bits on in STATUS_WORD 1319b654c619SBrandon Wyman expectations.statusWordValue = 0; 1320b654c619SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 132182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 132282affd94SBrandon Wyman .Times(1) 132382affd94SBrandon Wyman .WillOnce(Return("202300")); 13246710ba2cSBrandon Wyman psu.analyze(); 13256710ba2cSBrandon Wyman EXPECT_EQ(psu.hasVoutOVFault(), false); 13266710ba2cSBrandon Wyman } 132796893a46SBrandon Wyman 1328b10b3be0SBrandon Wyman TEST_F(PowerSupplyTests, HasIoutOCFault) 1329b10b3be0SBrandon Wyman { 1330b10b3be0SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1331b10b3be0SBrandon Wyman 1332b10b3be0SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName}; 1333b10b3be0SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 1334b10b3be0SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 1335b10b3be0SBrandon Wyman // Always return 1 to indicate present. 1336b10b3be0SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 1337b10b3be0SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1338391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1339b10b3be0SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 1340b10b3be0SBrandon Wyman PMBusExpectations expectations; 1341b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 134282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 134382affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 134482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 134582affd94SBrandon Wyman .Times(1) 134682affd94SBrandon Wyman .WillOnce(Return("203100")); 1347b10b3be0SBrandon Wyman psu.analyze(); 1348b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1349b10b3be0SBrandon Wyman // Turn fault on. 1350b10b3be0SBrandon Wyman expectations.statusWordValue = status_word::IOUT_OC_FAULT; 1351b10b3be0SBrandon Wyman // STATUS_IOUT fault bit(s) 1352b10b3be0SBrandon Wyman expectations.statusIOUTValue = 0x88; 1353c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1354c2906f47SBrandon Wyman { 1355b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 135682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 135782affd94SBrandon Wyman .Times(1) 135882affd94SBrandon Wyman .WillOnce(Return("203200")); 13590975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 13600975eaf4SMatt Spinler { 13610975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 13620975eaf4SMatt Spinler } 1363b10b3be0SBrandon Wyman psu.analyze(); 1364c2906f47SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT); 1365c2906f47SBrandon Wyman } 1366b10b3be0SBrandon Wyman // Back to no fault bits on in STATUS_WORD 1367b10b3be0SBrandon Wyman expectations.statusWordValue = 0; 1368b10b3be0SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 136982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 137082affd94SBrandon Wyman .Times(1) 137182affd94SBrandon Wyman .WillOnce(Return("203300")); 13720975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 1373b10b3be0SBrandon Wyman psu.analyze(); 1374b10b3be0SBrandon Wyman EXPECT_EQ(psu.hasIoutOCFault(), false); 1375b10b3be0SBrandon Wyman } 1376b10b3be0SBrandon Wyman 13772cf46945SBrandon Wyman TEST_F(PowerSupplyTests, HasVoutUVFault) 13782cf46945SBrandon Wyman { 13792cf46945SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 13802cf46945SBrandon Wyman 13812cf46945SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName}; 13822cf46945SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 13832cf46945SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 13842cf46945SBrandon Wyman // Always return 1 to indicate present. 13852cf46945SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 13862cf46945SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1387391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 1388391a0690SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 13892cf46945SBrandon Wyman PMBusExpectations expectations; 13902cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 139182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 139282affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 139382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 139482affd94SBrandon Wyman .Times(1) 139582affd94SBrandon Wyman .WillOnce(Return("204100")); 13962cf46945SBrandon Wyman psu.analyze(); 13972cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 13982cf46945SBrandon Wyman // Turn fault on. 13992cf46945SBrandon Wyman expectations.statusWordValue = (status_word::VOUT_FAULT); 14002cf46945SBrandon Wyman // STATUS_VOUT fault bit(s) 14012cf46945SBrandon Wyman expectations.statusVOUTValue = 0x30; 1402c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1403c2906f47SBrandon Wyman { 14042cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 140582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 140682affd94SBrandon Wyman .Times(1) 140782affd94SBrandon Wyman .WillOnce(Return("204200")); 14082cf46945SBrandon Wyman psu.analyze(); 1409c2906f47SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), x >= DEGLITCH_LIMIT); 1410c2906f47SBrandon Wyman } 14112cf46945SBrandon Wyman // Back to no fault bits on in STATUS_WORD 14122cf46945SBrandon Wyman expectations.statusWordValue = 0; 14132cf46945SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 141482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 141582affd94SBrandon Wyman .Times(1) 141682affd94SBrandon Wyman .WillOnce(Return("204300")); 14172cf46945SBrandon Wyman psu.analyze(); 14182cf46945SBrandon Wyman EXPECT_EQ(psu.hasVoutUVFault(), false); 14192cf46945SBrandon Wyman } 14202cf46945SBrandon Wyman 14217ee4d7e4SBrandon Wyman TEST_F(PowerSupplyTests, HasFanFault) 14227ee4d7e4SBrandon Wyman { 14237ee4d7e4SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 14247ee4d7e4SBrandon Wyman 14250975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1); 14260975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0); 14270975eaf4SMatt Spinler 14287ee4d7e4SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName}; 14297ee4d7e4SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 14307ee4d7e4SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 14317ee4d7e4SBrandon Wyman // Always return 1 to indicate present. 14327ee4d7e4SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 14337ee4d7e4SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1434391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 14357ee4d7e4SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 14367ee4d7e4SBrandon Wyman PMBusExpectations expectations; 14377ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 143882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 143982affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 144082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 144182affd94SBrandon Wyman .Times(1) 144282affd94SBrandon Wyman .WillOnce(Return("205100")); 14437ee4d7e4SBrandon Wyman psu.analyze(); 14447ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 14457ee4d7e4SBrandon Wyman // Turn fault on. 14467ee4d7e4SBrandon Wyman expectations.statusWordValue = (status_word::FAN_FAULT); 14477ee4d7e4SBrandon Wyman // STATUS_FANS_1_2 fault bit on (Fan 1 Fault) 14487ee4d7e4SBrandon Wyman expectations.statusFans12Value = 0x80; 1449c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1450c2906f47SBrandon Wyman { 14517ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 145282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 145382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 145482affd94SBrandon Wyman .Times(1) 145582affd94SBrandon Wyman .WillOnce(Return("205200")); 14567ee4d7e4SBrandon Wyman psu.analyze(); 1457c2906f47SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT); 1458c2906f47SBrandon Wyman } 14597ee4d7e4SBrandon Wyman // Back to no fault bits on in STATUS_WORD 14607ee4d7e4SBrandon Wyman expectations.statusWordValue = 0; 14617ee4d7e4SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 146282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 146382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 146482affd94SBrandon Wyman .Times(1) 146582affd94SBrandon Wyman .WillOnce(Return("205300")); 14667ee4d7e4SBrandon Wyman psu.analyze(); 14677ee4d7e4SBrandon Wyman EXPECT_EQ(psu.hasFanFault(), false); 14687ee4d7e4SBrandon Wyman } 14697ee4d7e4SBrandon Wyman 147096893a46SBrandon Wyman TEST_F(PowerSupplyTests, HasTempFault) 147196893a46SBrandon Wyman { 147296893a46SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 147396893a46SBrandon Wyman 14740975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1); 14750975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0); 14760975eaf4SMatt Spinler 147796893a46SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName}; 147896893a46SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 147996893a46SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 148096893a46SBrandon Wyman // Always return 1 to indicate present. 148196893a46SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 148296893a46SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1483391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 148496893a46SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 148596893a46SBrandon Wyman PMBusExpectations expectations; 148696893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 148782affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 148882affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 148982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 149082affd94SBrandon Wyman .Times(1) 149182affd94SBrandon Wyman .WillOnce(Return("206100")); 149296893a46SBrandon Wyman psu.analyze(); 149396893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 149496893a46SBrandon Wyman // Turn fault on. 149596893a46SBrandon Wyman expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN); 149696893a46SBrandon Wyman // STATUS_TEMPERATURE fault bit on (OT Fault) 149796893a46SBrandon Wyman expectations.statusTempValue = 0x80; 1498c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1499c2906f47SBrandon Wyman { 150096893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 150182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 150282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 150382affd94SBrandon Wyman .Times(1) 150482affd94SBrandon Wyman .WillOnce(Return("206200")); 150596893a46SBrandon Wyman psu.analyze(); 1506c2906f47SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT); 1507c2906f47SBrandon Wyman } 150896893a46SBrandon Wyman // Back to no fault bits on in STATUS_WORD 150996893a46SBrandon Wyman expectations.statusWordValue = 0; 151096893a46SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 151182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 151282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 151382affd94SBrandon Wyman .Times(1) 151482affd94SBrandon Wyman .WillOnce(Return("206300")); 151596893a46SBrandon Wyman psu.analyze(); 151696893a46SBrandon Wyman EXPECT_EQ(psu.hasTempFault(), false); 151796893a46SBrandon Wyman } 15182916ea52SBrandon Wyman 15192916ea52SBrandon Wyman TEST_F(PowerSupplyTests, HasPgoodFault) 15202916ea52SBrandon Wyman { 15212916ea52SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 15222916ea52SBrandon Wyman 15232916ea52SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x6b, PSUGPIOLineName}; 15242916ea52SBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 15252916ea52SBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 15262916ea52SBrandon Wyman // Always return 1 to indicate present. 15272916ea52SBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 15282916ea52SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1529391a0690SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 15302916ea52SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 15312916ea52SBrandon Wyman PMBusExpectations expectations; 15322916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 153382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 153482affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 153582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 153682affd94SBrandon Wyman .Times(1) 153782affd94SBrandon Wyman .WillOnce(Return("207100")); 15382916ea52SBrandon Wyman psu.analyze(); 15392916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 1540391a0690SBrandon Wyman // Setup another expectation of no faults. 1541391a0690SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 154282affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 154382affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 154482affd94SBrandon Wyman .Times(1) 154582affd94SBrandon Wyman .WillOnce(Return("207200")); 154682affd94SBrandon Wyman psu.analyze(); 154782affd94SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 154882affd94SBrandon Wyman // Setup another expectation of no faults. 154982affd94SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 155082affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 155182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 155282affd94SBrandon Wyman .Times(1) 155382affd94SBrandon Wyman .WillOnce(Return("207300")); 1554391a0690SBrandon Wyman psu.analyze(); 1555391a0690SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 15562916ea52SBrandon Wyman // Turn PGOOD# off (fault on). 15572916ea52SBrandon Wyman expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED); 15582916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 155982affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 156082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 156182affd94SBrandon Wyman .Times(1) 156282affd94SBrandon Wyman .WillOnce(Return("207400")); 15632916ea52SBrandon Wyman psu.analyze(); 156406ca4590SBrandon Wyman // Expect false until reaches DEGLITCH_LIMIT 156506ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 156606ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 156782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 156882affd94SBrandon Wyman .Times(1) 156982affd94SBrandon Wyman .WillOnce(Return("207500")); 157006ca4590SBrandon Wyman psu.analyze(); 157106ca4590SBrandon Wyman // Expect false until reaches DEGLITCH_LIMIT 157206ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 157306ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 157482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 157582affd94SBrandon Wyman .Times(1) 157682affd94SBrandon Wyman .WillOnce(Return("207600")); 157706ca4590SBrandon Wyman psu.analyze(); 157806ca4590SBrandon Wyman // DEGLITCH_LIMIT reached, expect true. 15792916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 15802916ea52SBrandon Wyman // Back to no fault bits on in STATUS_WORD 15812916ea52SBrandon Wyman expectations.statusWordValue = 0; 15822916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 158382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 158482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 158582affd94SBrandon Wyman .Times(1) 158682affd94SBrandon Wyman .WillOnce(Return("207700")); 15872916ea52SBrandon Wyman psu.analyze(); 15882916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 158982affd94SBrandon Wyman 15902916ea52SBrandon Wyman // Turn OFF bit on 15912916ea52SBrandon Wyman expectations.statusWordValue = (status_word::UNIT_IS_OFF); 15922916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 159382affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 159482affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 159582affd94SBrandon Wyman .Times(1) 159682affd94SBrandon Wyman .WillOnce(Return("208100")); 15972916ea52SBrandon Wyman psu.analyze(); 159806ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 159906ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 160082affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 160182affd94SBrandon Wyman .Times(1) 160282affd94SBrandon Wyman .WillOnce(Return("208200")); 160306ca4590SBrandon Wyman psu.analyze(); 160406ca4590SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 160506ca4590SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 160682affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 160782affd94SBrandon Wyman .Times(1) 160882affd94SBrandon Wyman .WillOnce(Return("208300")); 160906ca4590SBrandon Wyman psu.analyze(); 16102916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), true); 16112916ea52SBrandon Wyman // Back to no fault bits on in STATUS_WORD 16122916ea52SBrandon Wyman expectations.statusWordValue = 0; 16132916ea52SBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 161482affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 161582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 161682affd94SBrandon Wyman .Times(1) 161782affd94SBrandon Wyman .WillOnce(Return("208400")); 16182916ea52SBrandon Wyman psu.analyze(); 16192916ea52SBrandon Wyman EXPECT_EQ(psu.hasPgoodFault(), false); 16202916ea52SBrandon Wyman } 162139ea02bcSBrandon Wyman 162239ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSKillFault) 162339ea02bcSBrandon Wyman { 162439ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 162539ea02bcSBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 0x6d, PSUGPIOLineName}; 162639ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 162739ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 162839ea02bcSBrandon Wyman // Always return 1 to indicate present. 162939ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 163039ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 163182affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 163239ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 163339ea02bcSBrandon Wyman PMBusExpectations expectations; 163439ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 163582affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 163682affd94SBrandon Wyman // Initial value would be 0, so this read updates it to non-zero. 163782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 163882affd94SBrandon Wyman .Times(1) 163982affd94SBrandon Wyman .WillOnce(Return("208100")); 164039ea02bcSBrandon Wyman psu.analyze(); 164139ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 164239ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 164339ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 164439ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 164539ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1646c2906f47SBrandon Wyman 1647c2906f47SBrandon Wyman // Deglitching faults, false until read the fault bits on up to the limit. 1648c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1649c2906f47SBrandon Wyman { 165039ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 165182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 165282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 165382affd94SBrandon Wyman .Times(1) 165482affd94SBrandon Wyman .WillOnce(Return("208200")); 16550975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 16560975eaf4SMatt Spinler { 16570975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 16580975eaf4SMatt Spinler } 165939ea02bcSBrandon Wyman psu.analyze(); 1660c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1661c2906f47SBrandon Wyman } 1662c2906f47SBrandon Wyman 166339ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 166439ea02bcSBrandon Wyman expectations.statusWordValue = 0; 166539ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 166682affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 166782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 166882affd94SBrandon Wyman .Times(1) 166982affd94SBrandon Wyman .WillOnce(Return("208300")); 16700975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 167139ea02bcSBrandon Wyman psu.analyze(); 167239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 167339ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 167439ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 167539ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 4 on. 167639ea02bcSBrandon Wyman expectations.statusMFRValue = 0x10; 1677c2906f47SBrandon Wyman 1678c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1679c2906f47SBrandon Wyman { 168039ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 168182affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 168282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 168382affd94SBrandon Wyman .Times(1) 168482affd94SBrandon Wyman .WillOnce(Return("208400")); 16850975eaf4SMatt Spinler if (x == DEGLITCH_LIMIT) 16860975eaf4SMatt Spinler { 16870975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, false)); 16880975eaf4SMatt Spinler } 168939ea02bcSBrandon Wyman psu.analyze(); 1690c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT); 1691c2906f47SBrandon Wyman } 1692c2906f47SBrandon Wyman 169339ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 169439ea02bcSBrandon Wyman expectations.statusWordValue = 0; 169539ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 169682affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 169782affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 169882affd94SBrandon Wyman .Times(1) 169982affd94SBrandon Wyman .WillOnce(Return("208500")); 17000975eaf4SMatt Spinler EXPECT_CALL(mockedUtil, setAvailable(_, _, true)); 170139ea02bcSBrandon Wyman psu.analyze(); 170239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSKillFault(), false); 170339ea02bcSBrandon Wyman } 170439ea02bcSBrandon Wyman 170539ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPS12VcsFault) 170639ea02bcSBrandon Wyman { 170739ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 170839ea02bcSBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 5, 0x6e, PSUGPIOLineName}; 170939ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 171039ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 171139ea02bcSBrandon Wyman // Always return 1 to indicate present. 171239ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 171339ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 171482affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 171539ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 171639ea02bcSBrandon Wyman PMBusExpectations expectations; 171739ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 171882affd94SBrandon Wyman // Call to analyze will trigger read of "in1_input" to check voltage. 171982affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 172082affd94SBrandon Wyman .Times(1) 172182affd94SBrandon Wyman .WillOnce(Return("209100")); 172239ea02bcSBrandon Wyman psu.analyze(); 172339ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 172439ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 172539ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 172639ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 172739ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1728c2906f47SBrandon Wyman 1729c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1730c2906f47SBrandon Wyman { 173139ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 173282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 173382affd94SBrandon Wyman .Times(1) 173482affd94SBrandon Wyman .WillOnce(Return("209200")); 173539ea02bcSBrandon Wyman psu.analyze(); 1736c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1737c2906f47SBrandon Wyman } 1738c2906f47SBrandon Wyman 173939ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 174039ea02bcSBrandon Wyman expectations.statusWordValue = 0; 174139ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 174282affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 174382affd94SBrandon Wyman .Times(1) 174482affd94SBrandon Wyman .WillOnce(Return("209300")); 174539ea02bcSBrandon Wyman psu.analyze(); 174639ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 174739ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 174839ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 174939ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 6 on. 175039ea02bcSBrandon Wyman expectations.statusMFRValue = 0x40; 1751c2906f47SBrandon Wyman 1752c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1753c2906f47SBrandon Wyman { 175439ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 175582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 175682affd94SBrandon Wyman .Times(1) 175782affd94SBrandon Wyman .WillOnce(Return("209400")); 175839ea02bcSBrandon Wyman psu.analyze(); 1759c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT); 1760c2906f47SBrandon Wyman } 1761c2906f47SBrandon Wyman 176239ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 176339ea02bcSBrandon Wyman expectations.statusWordValue = 0; 176439ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 176582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 176682affd94SBrandon Wyman .Times(1) 176782affd94SBrandon Wyman .WillOnce(Return("209500")); 176839ea02bcSBrandon Wyman psu.analyze(); 176939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPS12VcsFault(), false); 177039ea02bcSBrandon Wyman } 177139ea02bcSBrandon Wyman 177239ea02bcSBrandon Wyman TEST_F(PowerSupplyTests, HasPSCS12VFault) 177339ea02bcSBrandon Wyman { 177439ea02bcSBrandon Wyman auto bus = sdbusplus::bus::new_default(); 177539ea02bcSBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f, PSUGPIOLineName}; 177639ea02bcSBrandon Wyman MockedGPIOInterface* mockPresenceGPIO = 177739ea02bcSBrandon Wyman static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 177839ea02bcSBrandon Wyman // Always return 1 to indicate present. 177939ea02bcSBrandon Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 178039ea02bcSBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 178182affd94SBrandon Wyman setMissingToPresentExpects(mockPMBus, mockedUtil); 178239ea02bcSBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 178339ea02bcSBrandon Wyman PMBusExpectations expectations; 178439ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 178582affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 178682affd94SBrandon Wyman .Times(1) 178782affd94SBrandon Wyman .WillOnce(Return("209100")); 178839ea02bcSBrandon Wyman psu.analyze(); 178939ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 179039ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 179139ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 179239ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 179339ea02bcSBrandon Wyman expectations.statusMFRValue = 0xFF; 1794c2906f47SBrandon Wyman 1795c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1796c2906f47SBrandon Wyman { 179739ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 179882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 179982affd94SBrandon Wyman .Times(1) 180082affd94SBrandon Wyman .WillOnce(Return("209200")); 180139ea02bcSBrandon Wyman psu.analyze(); 1802c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1803c2906f47SBrandon Wyman } 1804c2906f47SBrandon Wyman 180539ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 180639ea02bcSBrandon Wyman expectations.statusWordValue = 0; 180739ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 180882affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 180982affd94SBrandon Wyman .Times(1) 181082affd94SBrandon Wyman .WillOnce(Return("209300")); 181139ea02bcSBrandon Wyman psu.analyze(); 181239ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 181339ea02bcSBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 181439ea02bcSBrandon Wyman expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT); 181539ea02bcSBrandon Wyman // STATUS_MFR_SPEFIC with bit 7 on. 181639ea02bcSBrandon Wyman expectations.statusMFRValue = 0x80; 1817c2906f47SBrandon Wyman 1818c2906f47SBrandon Wyman for (auto x = 1; x <= DEGLITCH_LIMIT; x++) 1819c2906f47SBrandon Wyman { 182039ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 182182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 182282affd94SBrandon Wyman .Times(1) 182382affd94SBrandon Wyman .WillOnce(Return("209400")); 182439ea02bcSBrandon Wyman psu.analyze(); 1825c2906f47SBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT); 1826c2906f47SBrandon Wyman } 1827c2906f47SBrandon Wyman 182839ea02bcSBrandon Wyman // Back to no bits on in STATUS_WORD 182939ea02bcSBrandon Wyman expectations.statusWordValue = 0; 183039ea02bcSBrandon Wyman setPMBusExpectations(mockPMBus, expectations); 183182affd94SBrandon Wyman EXPECT_CALL(mockPMBus, readString(READ_VIN, _)) 183282affd94SBrandon Wyman .Times(1) 183382affd94SBrandon Wyman .WillOnce(Return("209500")); 183439ea02bcSBrandon Wyman psu.analyze(); 183539ea02bcSBrandon Wyman EXPECT_EQ(psu.hasPSCS12VFault(), false); 183639ea02bcSBrandon Wyman } 1837