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 253f1242f3SBrandon Wyman class PowerSupplyTests : public ::testing::Test 263f1242f3SBrandon Wyman { 273f1242f3SBrandon Wyman public: 283f1242f3SBrandon Wyman PowerSupplyTests() : 293f1242f3SBrandon Wyman mockedUtil(reinterpret_cast<const MockedUtil&>(getUtils())) 303f1242f3SBrandon Wyman { 313f1242f3SBrandon Wyman ON_CALL(mockedUtil, getPresence(_, _)).WillByDefault(Return(false)); 323f1242f3SBrandon Wyman } 333f1242f3SBrandon Wyman 343f1242f3SBrandon Wyman ~PowerSupplyTests() override 353f1242f3SBrandon Wyman { 363f1242f3SBrandon Wyman freeUtils(); 373f1242f3SBrandon Wyman } 383f1242f3SBrandon Wyman 393f1242f3SBrandon Wyman const MockedUtil& mockedUtil; 403f1242f3SBrandon Wyman }; 413f1242f3SBrandon Wyman 423f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Constructor) 433f1242f3SBrandon Wyman { 443f1242f3SBrandon Wyman /** 453f1242f3SBrandon Wyman * @param[in] invpath - String for inventory path to use 463f1242f3SBrandon Wyman * @param[in] i2cbus - The bus number this power supply is on 473f1242f3SBrandon Wyman * @param[in] i2caddr - The 16-bit I2C address of the power supply 48681b2a36SB. J. Wyman * @param[in] gpioLineName - The string for the gpio-line-name to read for 49681b2a36SB. J. Wyman * presence. 50681b2a36SB. J. Wyman * @param[in] bindDelay - Time in milliseconds to delay binding the device 51681b2a36SB. J. Wyman * driver after seeing the presence line go active. 523f1242f3SBrandon Wyman */ 533f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 541d7a7df8SBrandon Wyman 551d7a7df8SBrandon Wyman // Try where inventory path is empty, constructor should fail. 561d7a7df8SBrandon Wyman try 571d7a7df8SBrandon Wyman { 58681b2a36SB. J. Wyman auto psu = 59681b2a36SB. J. Wyman std::make_unique<PowerSupply>(bus, "", 3, 0x68, PSUGPIOLineName); 601d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have reached this line."; 611d7a7df8SBrandon Wyman } 621d7a7df8SBrandon Wyman catch (const std::invalid_argument& e) 631d7a7df8SBrandon Wyman { 641d7a7df8SBrandon Wyman EXPECT_STREQ(e.what(), "Invalid empty inventoryPath"); 651d7a7df8SBrandon Wyman } 661d7a7df8SBrandon Wyman catch (...) 671d7a7df8SBrandon Wyman { 681d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 691d7a7df8SBrandon Wyman } 701d7a7df8SBrandon Wyman 71681b2a36SB. J. Wyman // TODO: Try invalid i2c address? 72681b2a36SB. J. Wyman 73681b2a36SB. J. Wyman // Try where gpioLineName is empty. 741d7a7df8SBrandon Wyman try 751d7a7df8SBrandon Wyman { 761d7a7df8SBrandon Wyman auto psu = 77681b2a36SB. J. Wyman std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, ""); 78681b2a36SB. J. Wyman ADD_FAILURE() 79681b2a36SB. J. Wyman << "Should not have reached this line. Invalid gpioLineName."; 80681b2a36SB. J. Wyman } 81681b2a36SB. J. Wyman catch (const std::invalid_argument& e) 82681b2a36SB. J. Wyman { 83681b2a36SB. J. Wyman EXPECT_STREQ(e.what(), "Invalid empty gpioLineName"); 84681b2a36SB. J. Wyman } 85681b2a36SB. J. Wyman catch (...) 86681b2a36SB. J. Wyman { 87681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 88681b2a36SB. J. Wyman } 89681b2a36SB. J. Wyman 90681b2a36SB. J. Wyman // Test with valid arguments 91681b2a36SB. J. Wyman // NOT using D-Bus inventory path for presence. 92681b2a36SB. J. Wyman try 93681b2a36SB. J. Wyman { 94681b2a36SB. J. Wyman auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, 95681b2a36SB. J. Wyman PSUGPIOLineName); 963f1242f3SBrandon Wyman 973f1242f3SBrandon Wyman EXPECT_EQ(psu->isPresent(), false); 983f1242f3SBrandon Wyman EXPECT_EQ(psu->isFaulted(), false); 993f1242f3SBrandon Wyman EXPECT_EQ(psu->hasInputFault(), false); 1003f1242f3SBrandon Wyman EXPECT_EQ(psu->hasMFRFault(), false); 1013f1242f3SBrandon Wyman EXPECT_EQ(psu->hasVINUVFault(), false); 1023f1242f3SBrandon Wyman } 1031d7a7df8SBrandon Wyman catch (...) 1041d7a7df8SBrandon Wyman { 1051d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 1061d7a7df8SBrandon Wyman } 107681b2a36SB. J. Wyman 108681b2a36SB. J. Wyman // Test with valid arguments 109681b2a36SB. J. Wyman // TODO: Using D-Bus inventory path for presence. 110681b2a36SB. J. Wyman try 111681b2a36SB. J. Wyman { 112681b2a36SB. J. Wyman // FIXME: How do I get that presenceGPIO.read() in the startup to throw 113681b2a36SB. J. Wyman // an exception? 114681b2a36SB. J. Wyman 115681b2a36SB. J. Wyman // EXPECT_CALL(mockedUtil, getPresence(_, 116681b2a36SB. J. Wyman // StrEq(PSUInventoryPath))) 117681b2a36SB. J. Wyman // .Times(1); 118681b2a36SB. J. Wyman } 119681b2a36SB. J. Wyman catch (...) 120681b2a36SB. J. Wyman { 121681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 122681b2a36SB. J. Wyman } 1231d7a7df8SBrandon Wyman } 1243f1242f3SBrandon Wyman 1253f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Analyze) 1263f1242f3SBrandon Wyman { 1273f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1283f1242f3SBrandon Wyman 129681b2a36SB. J. Wyman // If I default to reading the GPIO, I will NOT expect a call to 130681b2a36SB. J. Wyman // getPresence(). 131681b2a36SB. J. Wyman 132681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName}; 1333ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 1343ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 135681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0)); 136681b2a36SB. J. Wyman 1373f1242f3SBrandon Wyman psu.analyze(); 1383f1242f3SBrandon Wyman // By default, nothing should change. 1393f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 1403f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 1413f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 1423f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 1433f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 144*85c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 1453f1242f3SBrandon Wyman 146681b2a36SB. J. Wyman PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName}; 147681b2a36SB. J. Wyman // In order to get the various faults tested, the power supply needs to 148681b2a36SB. J. Wyman // be present in order to read from the PMBus device(s). 1493ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO2 = 1503ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO()); 151681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO2, read()).WillByDefault(Return(1)); 152681b2a36SB. J. Wyman 153681b2a36SB. J. Wyman EXPECT_EQ(psu2.isPresent(), false); 1543f1242f3SBrandon Wyman 1553f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus()); 156f07bc797SBrandon Wyman // Presence change from missing to present will trigger in1_input read in 157f07bc797SBrandon Wyman // an attempt to get CLEAR_FAULTS called. 158f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(206000)); 159*85c7bf41SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 160f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 161f07bc797SBrandon Wyman .Times(1) 162f07bc797SBrandon Wyman .WillOnce(Return(0x0000)); 1633f1242f3SBrandon Wyman psu2.analyze(); 1643f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 1653f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 1663f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 1673f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 1683f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 169*85c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 1703f1242f3SBrandon Wyman 1713f1242f3SBrandon Wyman // STATUS_WORD input fault/warn 172f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 173f07bc797SBrandon Wyman .Times(1) 174f07bc797SBrandon Wyman .WillOnce(Return(status_word::INPUT_FAULT_WARN)); 175f07bc797SBrandon Wyman // Due to the fault bit on in STATUS_WORD, there will also be a read of 176*85c7bf41SBrandon Wyman // STATUS_INPUT, STATUS_MFR, and STATUS_CML, so there should be 4 reads 177*85c7bf41SBrandon Wyman // total expected. 178f07bc797SBrandon Wyman // STATUS_INPUT fault bits ... on. 179f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _)) 180f07bc797SBrandon Wyman .Times(1) 181f07bc797SBrandon Wyman .WillOnce(Return(0x38)); 182f07bc797SBrandon Wyman // STATUS_MFR don't care 183f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _)).Times(1).WillOnce(Return(0)); 184*85c7bf41SBrandon Wyman // STATUS_CML don't care 185*85c7bf41SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _)).Times(1).WillOnce(Return(0)); 1863f1242f3SBrandon Wyman psu2.analyze(); 1873f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 1883f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), true); 1893f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), true); 1903f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 1913f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 192*85c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 1933f1242f3SBrandon Wyman 1943f1242f3SBrandon Wyman // STATUS_WORD INPUT/UV fault. 1953f1242f3SBrandon Wyman // First need it to return good status, then the fault 196f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 197f07bc797SBrandon Wyman .Times(2) 1983f1242f3SBrandon Wyman .WillOnce(Return(0x0000)) 199f07bc797SBrandon Wyman .WillOnce(Return( 200f07bc797SBrandon Wyman (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT))); 201f07bc797SBrandon Wyman // STATUS_INPUT fault bits ... on. 202f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _)) 203f07bc797SBrandon Wyman .Times(1) 204f07bc797SBrandon Wyman .WillOnce(Return(0x38)); 205f07bc797SBrandon Wyman // STATUS_MFR don't care 206f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _)).Times(1).WillOnce(Return(0)); 207*85c7bf41SBrandon Wyman // STATUS_CML don't care 208*85c7bf41SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _)).Times(1).WillOnce(Return(0)); 2093f1242f3SBrandon Wyman psu2.analyze(); 2103f1242f3SBrandon Wyman psu2.analyze(); 2113f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2123f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), true); 213f07bc797SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), true); 2143f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 2153f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), true); 216*85c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 2173f1242f3SBrandon Wyman 2183f1242f3SBrandon Wyman // STATUS_WORD MFR fault. 219f07bc797SBrandon Wyman // First need it to return good status, then the fault 220f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 221f07bc797SBrandon Wyman .Times(2) 2223f1242f3SBrandon Wyman .WillOnce(Return(0x0000)) 223f07bc797SBrandon Wyman .WillOnce(Return(status_word::MFR_SPECIFIC_FAULT)); 224f07bc797SBrandon Wyman // STATUS_INPUT fault bits ... don't care. 225f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _)) 226f07bc797SBrandon Wyman .Times(1) 227f07bc797SBrandon Wyman .WillOnce(Return(0x00)); 228f07bc797SBrandon Wyman // STATUS_MFR bits on. 229f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _)).Times(1).WillOnce(Return(0xFF)); 230*85c7bf41SBrandon Wyman // STATUS_CML don't care 231*85c7bf41SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _)).Times(1).WillOnce(Return(0)); 2323f1242f3SBrandon Wyman psu2.analyze(); 2333f1242f3SBrandon Wyman psu2.analyze(); 2343f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2353f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), true); 2363f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 2373f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), true); 2383f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 239*85c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 2403f1242f3SBrandon Wyman 2413f1242f3SBrandon Wyman // Ignore Temperature fault. 242f07bc797SBrandon Wyman // First STATUS_WORD with no bits set, then with temperature fault. 243f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 244f07bc797SBrandon Wyman .Times(2) 2453f1242f3SBrandon Wyman .WillOnce(Return(0x0000)) 246f07bc797SBrandon Wyman .WillOnce(Return(status_word::TEMPERATURE_FAULT_WARN)); 247*85c7bf41SBrandon Wyman // If the STATUS_WORD has bits on, STATUS_MFR_SPECIFIC, STATUS_INPUT, and 248*85c7bf41SBrandon Wyman // STATUS_CML will also be read. 249f07bc797SBrandon Wyman // STATUS_INPUT fault bits ... don't care. 250f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _)) 251f07bc797SBrandon Wyman .Times(1) 252f07bc797SBrandon Wyman .WillOnce(Return(0x00)); 253f07bc797SBrandon Wyman // STATUS_MFR don't care 254f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _)).Times(1).WillOnce(Return(0)); 255*85c7bf41SBrandon Wyman // STATUS_CML don't care 256*85c7bf41SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _)).Times(1).WillOnce(Return(0)); 2573f1242f3SBrandon Wyman psu2.analyze(); 2583f1242f3SBrandon Wyman psu2.analyze(); 2593f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2603f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 2613f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 2623f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 2633f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 264*85c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 265*85c7bf41SBrandon Wyman 266*85c7bf41SBrandon Wyman // CML fault 267*85c7bf41SBrandon Wyman // First STATUS_WORD wit no bits set, then with CML fault. 268*85c7bf41SBrandon Wyman // STATUS_WORD with CML fault bit on. 269*85c7bf41SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 270*85c7bf41SBrandon Wyman .Times(2) 271*85c7bf41SBrandon Wyman .WillOnce(Return(0x0000)) 272*85c7bf41SBrandon Wyman .WillOnce(Return(status_word::CML_FAULT)); 273*85c7bf41SBrandon Wyman psu2.analyze(); 274*85c7bf41SBrandon Wyman // If the STATUS_WORD has bits on, STATUS_MFR_SPECIFIC, STATUS_INPUT, and 275*85c7bf41SBrandon Wyman // STATUS_CML will also be read. 276*85c7bf41SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _)) 277*85c7bf41SBrandon Wyman .Times(1) 278*85c7bf41SBrandon Wyman .WillOnce(Return(0x00)); 279*85c7bf41SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _)).Times(1).WillOnce(Return(0x00)); 280*85c7bf41SBrandon Wyman // Turn on STATUS_CML fault bit(s) 281*85c7bf41SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _)).Times(1).WillOnce(Return(0xFF)); 282*85c7bf41SBrandon Wyman psu2.analyze(); 283*85c7bf41SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 284*85c7bf41SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), true); 285*85c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 286*85c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 287*85c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 288*85c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), true); 2893f1242f3SBrandon Wyman 2903f1242f3SBrandon Wyman // Ignore fan fault 291f07bc797SBrandon Wyman // First STATUS_WORD with no bits set, then with fan fault. 292f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 293f07bc797SBrandon Wyman .Times(2) 2943f1242f3SBrandon Wyman .WillOnce(Return(0x0000)) 295f07bc797SBrandon Wyman .WillOnce(Return(status_word::FAN_FAULT)); 296*85c7bf41SBrandon Wyman // If the STATUS_WORD has bits on, STATUS_MFR_SPECIFIC, STATUS_INPUT, and 297*85c7bf41SBrandon Wyman // STATUS_CML will also be read. 298f07bc797SBrandon Wyman // Don't care if bits set or not. 299f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _)) 300f07bc797SBrandon Wyman .Times(1) 301f07bc797SBrandon Wyman .WillOnce(Return(0x00)); 302f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _)).Times(1).WillOnce(Return(0)); 303*85c7bf41SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _)).Times(1).WillOnce(Return(0)); 3043f1242f3SBrandon Wyman psu2.analyze(); 3053f1242f3SBrandon Wyman psu2.analyze(); 3063f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 3073f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 3083f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 3093f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 3103f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 311*85c7bf41SBrandon Wyman EXPECT_EQ(psu2.hasCommFault(), false); 3123f1242f3SBrandon Wyman 3133f1242f3SBrandon Wyman // TODO: ReadFailure 3143f1242f3SBrandon Wyman } 3153f1242f3SBrandon Wyman 31659a35793SBrandon Wyman TEST_F(PowerSupplyTests, OnOffConfig) 31759a35793SBrandon Wyman { 31859a35793SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 31959a35793SBrandon Wyman uint8_t data = 0x15; 32059a35793SBrandon Wyman 32159a35793SBrandon Wyman // Test where PSU is NOT present 32259a35793SBrandon Wyman try 32359a35793SBrandon Wyman { 324681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 325681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName}; 326681b2a36SB. J. Wyman 3273ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 3283ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 329681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0)); 33059a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 331681b2a36SB. J. Wyman // Constructor should set initial presence, default read returns 0. 33259a35793SBrandon Wyman // If it is not present, I should not be trying to write to it. 33359a35793SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0); 33459a35793SBrandon Wyman psu.onOffConfig(data); 33559a35793SBrandon Wyman } 33659a35793SBrandon Wyman catch (...) 3370c9a33d6SAdriana Kobylak {} 33859a35793SBrandon Wyman 33959a35793SBrandon Wyman // Test where PSU is present 34059a35793SBrandon Wyman try 34159a35793SBrandon Wyman { 342681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 343681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName}; 3443ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 3453ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 346681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(1)); 34759a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 348681b2a36SB. J. Wyman // TODO: expect setPresence call? 349681b2a36SB. J. Wyman // updatePresence() private function reads gpio, called by analyze(). 350681b2a36SB. J. Wyman psu.analyze(); 35159a35793SBrandon Wyman // TODO: ???should I check the filename? 35259a35793SBrandon Wyman EXPECT_CALL(mockPMBus, 35359a35793SBrandon Wyman writeBinary(_, ElementsAre(0x15), Type::HwmonDeviceDebug)) 35459a35793SBrandon Wyman .Times(1); 35559a35793SBrandon Wyman psu.onOffConfig(data); 35659a35793SBrandon Wyman } 35759a35793SBrandon Wyman catch (...) 3580c9a33d6SAdriana Kobylak {} 35959a35793SBrandon Wyman } 36059a35793SBrandon Wyman 3613f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, ClearFaults) 3623f1242f3SBrandon Wyman { 3633f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 364681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, PSUGPIOLineName}; 3653ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 3663ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 367681b2a36SB. J. Wyman // GPIO read return 1 to indicate present. 368681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(1)); 369681b2a36SB. J. Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 370f07bc797SBrandon Wyman ON_CALL(mockPMBus, read(STATUS_WORD, _)).WillByDefault(Return(0)); 371681b2a36SB. J. Wyman psu.analyze(); 3723f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 3733f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 3743f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 3753f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 3763f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 377*85c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 378f07bc797SBrandon Wyman // STATUS_WORD with fault bits galore! 379f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 380f07bc797SBrandon Wyman .Times(1) 381f07bc797SBrandon Wyman .WillOnce(Return(0xFFFF)); 382*85c7bf41SBrandon Wyman // If STATUS_WORD has any fault bits on, STATUS_MFR_SPECIFIC, STATUS_INPUT 383*85c7bf41SBrandon Wyman // and STATUS_CML will be read. 384f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 385f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _)) 386f07bc797SBrandon Wyman .Times(1) 387f07bc797SBrandon Wyman .WillOnce(Return(0xFF)); 388f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bits on. 389f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _)).Times(1).WillOnce(Return(0xFF)); 390*85c7bf41SBrandon Wyman // STATUS_CML with bits on. 391*85c7bf41SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _)).Times(1).WillOnce(Return(0xFF)); 3923f1242f3SBrandon Wyman psu.analyze(); 3933f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 3943f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 3953f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 3963f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 3973f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 398*85c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), true); 3993c208464SBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_input", _)) 4003c208464SBrandon Wyman .Times(1) 4013c208464SBrandon Wyman .WillOnce(Return(209000)); 4023f1242f3SBrandon Wyman psu.clearFaults(); 4033f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 4043f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 4053f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 4063f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 4073f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 408*85c7bf41SBrandon Wyman EXPECT_EQ(psu.hasCommFault(), false); 409681b2a36SB. J. Wyman 410681b2a36SB. J. Wyman // TODO: Faults clear on missing/present? 4113f1242f3SBrandon Wyman } 4123f1242f3SBrandon Wyman 4133f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory) 4143f1242f3SBrandon Wyman { 4153f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 4161d7a7df8SBrandon Wyman 4171d7a7df8SBrandon Wyman try 4181d7a7df8SBrandon Wyman { 419681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 4201d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 4211d7a7df8SBrandon Wyman // If it is not present, I should not be trying to read a string 4221d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).Times(0); 4231d7a7df8SBrandon Wyman psu.updateInventory(); 4241d7a7df8SBrandon Wyman } 4251d7a7df8SBrandon Wyman catch (...) 4261d7a7df8SBrandon Wyman { 4271d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 4281d7a7df8SBrandon Wyman } 4291d7a7df8SBrandon Wyman 4301d7a7df8SBrandon Wyman try 4311d7a7df8SBrandon Wyman { 432681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, PSUGPIOLineName}; 4333ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 4343ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 435681b2a36SB. J. Wyman // GPIO read return 1 to indicate present. 436681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 437681b2a36SB. J. Wyman psu.analyze(); 4381d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 4391d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return("")); 4403f1242f3SBrandon Wyman psu.updateInventory(); 4411d7a7df8SBrandon Wyman 4423c530fbdSBrandon Wyman #if IBM_VPD 4431d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)) 4441d7a7df8SBrandon Wyman .WillOnce(Return("CCIN")) 4451d7a7df8SBrandon Wyman .WillOnce(Return("PN3456")) 4461d7a7df8SBrandon Wyman .WillOnce(Return("FN3456")) 4471d7a7df8SBrandon Wyman .WillOnce(Return("HEADER")) 4481d7a7df8SBrandon Wyman .WillOnce(Return("SN3456")) 4491d7a7df8SBrandon Wyman .WillOnce(Return("FW3456")); 4503c530fbdSBrandon Wyman #endif 4511d7a7df8SBrandon Wyman psu.updateInventory(); 4521d7a7df8SBrandon Wyman // TODO: D-Bus mocking to verify values stored on D-Bus (???) 4531d7a7df8SBrandon Wyman } 4541d7a7df8SBrandon Wyman catch (...) 4551d7a7df8SBrandon Wyman { 4561d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 4571d7a7df8SBrandon Wyman } 4583f1242f3SBrandon Wyman } 4593f1242f3SBrandon Wyman 4603f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent) 4613f1242f3SBrandon Wyman { 4623f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 463681b2a36SB. J. Wyman 464681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 4653ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 4663ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 4673f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 4683f1242f3SBrandon Wyman 469681b2a36SB. J. Wyman // Change GPIO read to return 1 to indicate present. 470681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 471681b2a36SB. J. Wyman psu.analyze(); 472681b2a36SB. J. Wyman EXPECT_EQ(psu.isPresent(), true); 4733f1242f3SBrandon Wyman } 4743f1242f3SBrandon Wyman 4753f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted) 4763f1242f3SBrandon Wyman { 4773f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 478681b2a36SB. J. Wyman 479681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, PSUGPIOLineName}; 4803ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 4813ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 482681b2a36SB. J. Wyman // Always return 1 to indicate present. 483681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 484681b2a36SB. J. Wyman psu.analyze(); 4853f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 4863f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 487f07bc797SBrandon Wyman // STATUS_WORD with fault bits on. 488f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 489f07bc797SBrandon Wyman .Times(1) 490f07bc797SBrandon Wyman .WillOnce(Return(0xFFFF)); 491*85c7bf41SBrandon Wyman // Fault bit(s) on in STATUS_WORD causes read of STATUS_MFR_SPECIFIC, 492*85c7bf41SBrandon Wyman // STATUS_INPUT, and STATUS_CML. 493f07bc797SBrandon Wyman // STATUS_INPUT with fault bits on. 494f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _)) 495f07bc797SBrandon Wyman .Times(1) 496f07bc797SBrandon Wyman .WillOnce(Return(0xFF)); 497f07bc797SBrandon Wyman // STATUS_MFR_SPECIFIC with faults bits on. 498f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _)).Times(1).WillOnce(Return(0xFF)); 499*85c7bf41SBrandon Wyman // STATUS_CML with faults bits on. 500*85c7bf41SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _)).Times(1).WillOnce(Return(0xFF)); 5013f1242f3SBrandon Wyman psu.analyze(); 5023f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 5033f1242f3SBrandon Wyman } 5043f1242f3SBrandon Wyman 5053f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasInputFault) 5063f1242f3SBrandon Wyman { 5073f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 508681b2a36SB. J. Wyman 509681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 5103ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 5113ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 512681b2a36SB. J. Wyman // Always return 1 to indicate present. 513681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 514681b2a36SB. J. Wyman psu.analyze(); 5153f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 5163f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 5173f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000)); 5183f1242f3SBrandon Wyman psu.analyze(); 5193f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 520f07bc797SBrandon Wyman // STATUS_WORD with input fault/warn on. 521f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 522f07bc797SBrandon Wyman .Times(1) 523f07bc797SBrandon Wyman .WillOnce(Return(status_word::INPUT_FAULT_WARN)); 524*85c7bf41SBrandon Wyman // Fault bit(s) on in STATUS_WORD causes read of STATUS_MFR_SPECIFIC, 525*85c7bf41SBrandon Wyman // STATUS_INPUT, and STATUS_CML. 526f07bc797SBrandon Wyman // STATUS_INPUT with an input fault bit on. 527f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _)) 528f07bc797SBrandon Wyman .Times(1) 529f07bc797SBrandon Wyman .WillOnce(Return(0x80)); 530f07bc797SBrandon Wyman // STATUS_MFR don't care. 531f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _)).Times(1).WillOnce(Return(0x00)); 532*85c7bf41SBrandon Wyman // STATUS_CML don't care. 533*85c7bf41SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _)).Times(1).WillOnce(Return(0x00)); 5343f1242f3SBrandon Wyman psu.analyze(); 5353f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 536f07bc797SBrandon Wyman // STATUS_WORD with no bits on. 537f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 538f07bc797SBrandon Wyman .Times(1) 539f07bc797SBrandon Wyman .WillOnce(Return(0x0000)); 5403f1242f3SBrandon Wyman psu.analyze(); 5413f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 5423f1242f3SBrandon Wyman } 5433f1242f3SBrandon Wyman 5443f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault) 5453f1242f3SBrandon Wyman { 5463f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 547681b2a36SB. J. Wyman 548681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 5493ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 5503ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 551681b2a36SB. J. Wyman // Always return 1 to indicate present. 552681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 553681b2a36SB. J. Wyman psu.analyze(); 5543f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 5553f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 556f07bc797SBrandon Wyman // First return STATUS_WORD with no bits on. 557f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 558f07bc797SBrandon Wyman .Times(1) 559f07bc797SBrandon Wyman .WillOnce(Return(0x0000)); 5603f1242f3SBrandon Wyman psu.analyze(); 5613f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 562f07bc797SBrandon Wyman // Next return STATUS_WORD with MFR fault bit on. 563f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 564f07bc797SBrandon Wyman .Times(1) 565f07bc797SBrandon Wyman .WillOnce(Return(status_word::MFR_SPECIFIC_FAULT)); 566*85c7bf41SBrandon Wyman // Fault bit(s) on in STATUS_WORD causes read of STATUS_MFR_SPECIFIC, 567*85c7bf41SBrandon Wyman // STATUS_INPUT, and STATUS_CML. 568f07bc797SBrandon Wyman // STATUS_INPUT don't care 569f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _)) 570f07bc797SBrandon Wyman .Times(1) 571f07bc797SBrandon Wyman .WillOnce(Return(0x00)); 572f07bc797SBrandon Wyman // STATUS_MFR_SPEFIC with bit(s) on. 573f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _)).Times(1).WillOnce(Return(0xFF)); 574*85c7bf41SBrandon Wyman // STATUS_CML don't care. 575*85c7bf41SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _)).Times(1).WillOnce(Return(0x00)); 5763f1242f3SBrandon Wyman psu.analyze(); 5773f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 578f07bc797SBrandon Wyman // Back to no bits on in STATUS_WORD 579f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 580f07bc797SBrandon Wyman .Times(1) 581f07bc797SBrandon Wyman .WillOnce(Return(0x0000)); 5823f1242f3SBrandon Wyman psu.analyze(); 5833f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 5843f1242f3SBrandon Wyman } 5853f1242f3SBrandon Wyman 5863f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault) 5873f1242f3SBrandon Wyman { 5883f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 589681b2a36SB. J. Wyman 590681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 5913ca062aeSAdriana Kobylak MockedGPIOInterface* mockPresenceGPIO = 5923ca062aeSAdriana Kobylak static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO()); 593681b2a36SB. J. Wyman // Always return 1 to indicate present. 594681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 595681b2a36SB. J. Wyman psu.analyze(); 5963f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 5973f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 598f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 599f07bc797SBrandon Wyman .Times(1) 600f07bc797SBrandon Wyman .WillOnce(Return(0x0000)); 6013f1242f3SBrandon Wyman psu.analyze(); 6023f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 603f07bc797SBrandon Wyman // Turn fault on. 604f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 605f07bc797SBrandon Wyman .Times(1) 606f07bc797SBrandon Wyman .WillOnce(Return(status_word::VIN_UV_FAULT)); 607*85c7bf41SBrandon Wyman // Fault bit(s) on in STATUS_WORD causes read of STATUS_MFR_SPECIFIC, 608*85c7bf41SBrandon Wyman // STATUS_INPUT, and STATUS_CML. 609*85c7bf41SBrandon Wyman // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by 610*85c7bf41SBrandon Wyman // Figure 16, and assume bits on in STATUS_INPUT. 611f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _)) 612f07bc797SBrandon Wyman .Times(1) 613f07bc797SBrandon Wyman .WillOnce(Return(0x18)); 614f07bc797SBrandon Wyman // STATUS_MFR don't care. 615f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_MFR, _)).Times(1).WillOnce(Return(0x00)); 616*85c7bf41SBrandon Wyman // STATUS_CML don't care. 617*85c7bf41SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_CML, _)).Times(1).WillOnce(Return(0x00)); 618f07bc797SBrandon Wyman 6193f1242f3SBrandon Wyman psu.analyze(); 6203f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 621f07bc797SBrandon Wyman // Back to no fault bits on in STATUS_WORD 622f07bc797SBrandon Wyman EXPECT_CALL(mockPMBus, read(STATUS_WORD, _)) 623f07bc797SBrandon Wyman .Times(1) 624f07bc797SBrandon Wyman .WillOnce(Return(0x0000)); 6253f1242f3SBrandon Wyman psu.analyze(); 6263f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 6273f1242f3SBrandon Wyman } 628