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"; 23*681b2a36SB. 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 48*681b2a36SB. J. Wyman * @param[in] gpioLineName - The string for the gpio-line-name to read for 49*681b2a36SB. J. Wyman * presence. 50*681b2a36SB. J. Wyman * @param[in] bindDelay - Time in milliseconds to delay binding the device 51*681b2a36SB. 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 { 58*681b2a36SB. J. Wyman auto psu = 59*681b2a36SB. 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 71*681b2a36SB. J. Wyman // TODO: Try invalid i2c address? 72*681b2a36SB. J. Wyman 73*681b2a36SB. J. Wyman // Try where gpioLineName is empty. 741d7a7df8SBrandon Wyman try 751d7a7df8SBrandon Wyman { 761d7a7df8SBrandon Wyman auto psu = 77*681b2a36SB. J. Wyman std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, ""); 78*681b2a36SB. J. Wyman ADD_FAILURE() 79*681b2a36SB. J. Wyman << "Should not have reached this line. Invalid gpioLineName."; 80*681b2a36SB. J. Wyman } 81*681b2a36SB. J. Wyman catch (const std::invalid_argument& e) 82*681b2a36SB. J. Wyman { 83*681b2a36SB. J. Wyman EXPECT_STREQ(e.what(), "Invalid empty gpioLineName"); 84*681b2a36SB. J. Wyman } 85*681b2a36SB. J. Wyman catch (...) 86*681b2a36SB. J. Wyman { 87*681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 88*681b2a36SB. J. Wyman } 89*681b2a36SB. J. Wyman 90*681b2a36SB. J. Wyman // Test with valid arguments 91*681b2a36SB. J. Wyman // NOT using D-Bus inventory path for presence. 92*681b2a36SB. J. Wyman try 93*681b2a36SB. J. Wyman { 94*681b2a36SB. J. Wyman auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, 95*681b2a36SB. 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 } 107*681b2a36SB. J. Wyman 108*681b2a36SB. J. Wyman // Test with valid arguments 109*681b2a36SB. J. Wyman // TODO: Using D-Bus inventory path for presence. 110*681b2a36SB. J. Wyman try 111*681b2a36SB. J. Wyman { 112*681b2a36SB. J. Wyman // FIXME: How do I get that presenceGPIO.read() in the startup to throw 113*681b2a36SB. J. Wyman // an exception? 114*681b2a36SB. J. Wyman 115*681b2a36SB. J. Wyman // EXPECT_CALL(mockedUtil, getPresence(_, 116*681b2a36SB. J. Wyman // StrEq(PSUInventoryPath))) 117*681b2a36SB. J. Wyman // .Times(1); 118*681b2a36SB. J. Wyman } 119*681b2a36SB. J. Wyman catch (...) 120*681b2a36SB. J. Wyman { 121*681b2a36SB. J. Wyman ADD_FAILURE() << "Should not have caught exception."; 122*681b2a36SB. J. Wyman } 1231d7a7df8SBrandon Wyman } 1243f1242f3SBrandon Wyman 1253f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Analyze) 1263f1242f3SBrandon Wyman { 1273f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1283f1242f3SBrandon Wyman 129*681b2a36SB. J. Wyman // If I default to reading the GPIO, I will NOT expect a call to 130*681b2a36SB. J. Wyman // getPresence(). 131*681b2a36SB. J. Wyman 132*681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName}; 133*681b2a36SB. J. Wyman MockedGPIOReader* mockPresenceGPIO = 134*681b2a36SB. J. Wyman static_cast<MockedGPIOReader*>(psu.getPresenceGPIO()); 135*681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0)); 136*681b2a36SB. 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); 1443f1242f3SBrandon Wyman 145*681b2a36SB. J. Wyman PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName}; 146*681b2a36SB. J. Wyman // In order to get the various faults tested, the power supply needs to 147*681b2a36SB. J. Wyman // be present in order to read from the PMBus device(s). 148*681b2a36SB. J. Wyman MockedGPIOReader* mockPresenceGPIO2 = 149*681b2a36SB. J. Wyman static_cast<MockedGPIOReader*>(psu2.getPresenceGPIO()); 150*681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO2, read()).WillByDefault(Return(1)); 151*681b2a36SB. J. Wyman 152*681b2a36SB. J. Wyman EXPECT_EQ(psu2.isPresent(), false); 1533f1242f3SBrandon Wyman 1543f1242f3SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 155*681b2a36SB. J. Wyman // It will read STATUS_MFR at the same time, so there are 2 reads. 1563f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus()); 157*681b2a36SB. J. Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(2).WillRepeatedly(Return(0x0000)); 1583f1242f3SBrandon Wyman psu2.analyze(); 1593f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 1603f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 1613f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 1623f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 1633f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 1643f1242f3SBrandon Wyman 1653f1242f3SBrandon Wyman // STATUS_WORD input fault/warn 1663f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 16710d94055SJay Meyer .Times(2) 16810d94055SJay Meyer .WillOnce(Return(status_word::INPUT_FAULT_WARN)) 16910d94055SJay Meyer .WillOnce(Return(0x0000)); 1703f1242f3SBrandon Wyman psu2.analyze(); 1713f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 1723f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), true); 1733f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), true); 1743f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 1753f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 1763f1242f3SBrandon Wyman 1773f1242f3SBrandon Wyman // STATUS_WORD INPUT/UV fault. 1783f1242f3SBrandon Wyman // First need it to return good status, then the fault 1793f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 1803f1242f3SBrandon Wyman .WillOnce(Return(0x0000)) 18110d94055SJay Meyer .WillOnce(Return(status_word::VIN_UV_FAULT)) 18210d94055SJay Meyer .WillOnce(Return(0x0000)); 1833f1242f3SBrandon Wyman psu2.analyze(); 1843f1242f3SBrandon Wyman psu2.analyze(); 1853f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 1863f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), true); 1873f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 1883f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 1893f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), true); 1903f1242f3SBrandon Wyman 1913f1242f3SBrandon Wyman // STATUS_WORD MFR fault. 1923f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 1933f1242f3SBrandon Wyman .WillOnce(Return(0x0000)) 19410d94055SJay Meyer .WillOnce(Return(status_word::MFR_SPECIFIC_FAULT)) 19510d94055SJay Meyer .WillOnce(Return(1)); // mock return for read(STATUS_MFR... ) 1963f1242f3SBrandon Wyman psu2.analyze(); 1973f1242f3SBrandon Wyman psu2.analyze(); 1983f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 1993f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), true); 2003f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 2013f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), true); 2023f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 2033f1242f3SBrandon Wyman 2043f1242f3SBrandon Wyman // Ignore Temperature fault. 2053f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 2063f1242f3SBrandon Wyman .WillOnce(Return(0x0000)) 20710d94055SJay Meyer .WillOnce(Return(status_word::TEMPERATURE_FAULT_WARN)) 20810d94055SJay Meyer .WillOnce(Return(0x0000)); 2093f1242f3SBrandon Wyman psu2.analyze(); 2103f1242f3SBrandon Wyman psu2.analyze(); 2113f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2123f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 2133f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 2143f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 2153f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 2163f1242f3SBrandon Wyman 2173f1242f3SBrandon Wyman // Ignore fan fault 2183f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 2193f1242f3SBrandon Wyman .WillOnce(Return(0x0000)) 22010d94055SJay Meyer .WillOnce(Return(status_word::FAN_FAULT)) 22110d94055SJay Meyer .WillOnce(Return(0x0000)); 2223f1242f3SBrandon Wyman psu2.analyze(); 2233f1242f3SBrandon Wyman psu2.analyze(); 2243f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2253f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 2263f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 2273f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 2283f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 2293f1242f3SBrandon Wyman 2303f1242f3SBrandon Wyman // TODO: ReadFailure 2313f1242f3SBrandon Wyman } 2323f1242f3SBrandon Wyman 23359a35793SBrandon Wyman TEST_F(PowerSupplyTests, OnOffConfig) 23459a35793SBrandon Wyman { 23559a35793SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 23659a35793SBrandon Wyman uint8_t data = 0x15; 23759a35793SBrandon Wyman 23859a35793SBrandon Wyman // Test where PSU is NOT present 23959a35793SBrandon Wyman try 24059a35793SBrandon Wyman { 241*681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 242*681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName}; 243*681b2a36SB. J. Wyman 244*681b2a36SB. J. Wyman MockedGPIOReader* mockPresenceGPIO = 245*681b2a36SB. J. Wyman static_cast<MockedGPIOReader*>(psu.getPresenceGPIO()); 246*681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0)); 24759a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 248*681b2a36SB. J. Wyman // Constructor should set initial presence, default read returns 0. 24959a35793SBrandon Wyman // If it is not present, I should not be trying to write to it. 25059a35793SBrandon Wyman EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0); 25159a35793SBrandon Wyman psu.onOffConfig(data); 25259a35793SBrandon Wyman } 25359a35793SBrandon Wyman catch (...) 25459a35793SBrandon Wyman { 25559a35793SBrandon Wyman } 25659a35793SBrandon Wyman 25759a35793SBrandon Wyman // Test where PSU is present 25859a35793SBrandon Wyman try 25959a35793SBrandon Wyman { 260*681b2a36SB. J. Wyman // Assume GPIO presence, not inventory presence? 261*681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName}; 262*681b2a36SB. J. Wyman MockedGPIOReader* mockPresenceGPIO = 263*681b2a36SB. J. Wyman static_cast<MockedGPIOReader*>(psu.getPresenceGPIO()); 264*681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(1)); 26559a35793SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 266*681b2a36SB. J. Wyman // TODO: expect setPresence call? 267*681b2a36SB. J. Wyman // updatePresence() private function reads gpio, called by analyze(). 268*681b2a36SB. J. Wyman psu.analyze(); 26959a35793SBrandon Wyman // TODO: ???should I check the filename? 27059a35793SBrandon Wyman EXPECT_CALL(mockPMBus, 27159a35793SBrandon Wyman writeBinary(_, ElementsAre(0x15), Type::HwmonDeviceDebug)) 27259a35793SBrandon Wyman .Times(1); 27359a35793SBrandon Wyman psu.onOffConfig(data); 27459a35793SBrandon Wyman } 27559a35793SBrandon Wyman catch (...) 27659a35793SBrandon Wyman { 27759a35793SBrandon Wyman } 27859a35793SBrandon Wyman } 27959a35793SBrandon Wyman 2803f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, ClearFaults) 2813f1242f3SBrandon Wyman { 2823f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 283*681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, PSUGPIOLineName}; 284*681b2a36SB. J. Wyman MockedGPIOReader* mockPresenceGPIO = 285*681b2a36SB. J. Wyman static_cast<MockedGPIOReader*>(psu.getPresenceGPIO()); 286*681b2a36SB. J. Wyman // GPIO read return 1 to indicate present. 287*681b2a36SB. J. Wyman ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(1)); 288*681b2a36SB. J. Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 289*681b2a36SB. J. Wyman ON_CALL(mockPMBus, read(_, _)).WillByDefault(Return(0)); 290*681b2a36SB. J. Wyman psu.analyze(); 2913f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 2923f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 2933f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 2943f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 2953f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 29610d94055SJay Meyer EXPECT_CALL(mockPMBus, read(_, _)) 29710d94055SJay Meyer .Times(2) 29810d94055SJay Meyer .WillOnce(Return(0xFFFF)) 29910d94055SJay Meyer .WillOnce(Return(1)); // mock return for read(STATUS_MFR... ) 3003f1242f3SBrandon Wyman psu.analyze(); 3013f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 3023f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 3033f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 3043f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 3053f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 3063c208464SBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_input", _)) 3073c208464SBrandon Wyman .Times(1) 3083c208464SBrandon Wyman .WillOnce(Return(209000)); 3093f1242f3SBrandon Wyman psu.clearFaults(); 3103f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 3113f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 3123f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 3133f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 3143f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 315*681b2a36SB. J. Wyman 316*681b2a36SB. J. Wyman // TODO: Faults clear on missing/present? 3173f1242f3SBrandon Wyman } 3183f1242f3SBrandon Wyman 3193f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory) 3203f1242f3SBrandon Wyman { 3213f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 3221d7a7df8SBrandon Wyman 3231d7a7df8SBrandon Wyman try 3241d7a7df8SBrandon Wyman { 325*681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 3261d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 3271d7a7df8SBrandon Wyman // If it is not present, I should not be trying to read a string 3281d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).Times(0); 3291d7a7df8SBrandon Wyman psu.updateInventory(); 3301d7a7df8SBrandon Wyman } 3311d7a7df8SBrandon Wyman catch (...) 3321d7a7df8SBrandon Wyman { 3331d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 3341d7a7df8SBrandon Wyman } 3351d7a7df8SBrandon Wyman 3361d7a7df8SBrandon Wyman try 3371d7a7df8SBrandon Wyman { 338*681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, PSUGPIOLineName}; 339*681b2a36SB. J. Wyman MockedGPIOReader* mockPresenceGPIO = 340*681b2a36SB. J. Wyman static_cast<MockedGPIOReader*>(psu.getPresenceGPIO()); 341*681b2a36SB. J. Wyman // GPIO read return 1 to indicate present. 342*681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 343*681b2a36SB. J. Wyman psu.analyze(); 3441d7a7df8SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 3451d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return("")); 3463f1242f3SBrandon Wyman psu.updateInventory(); 3471d7a7df8SBrandon Wyman 3483c530fbdSBrandon Wyman #if IBM_VPD 3491d7a7df8SBrandon Wyman EXPECT_CALL(mockPMBus, readString(_, _)) 3501d7a7df8SBrandon Wyman .WillOnce(Return("CCIN")) 3511d7a7df8SBrandon Wyman .WillOnce(Return("PN3456")) 3521d7a7df8SBrandon Wyman .WillOnce(Return("FN3456")) 3531d7a7df8SBrandon Wyman .WillOnce(Return("HEADER")) 3541d7a7df8SBrandon Wyman .WillOnce(Return("SN3456")) 3551d7a7df8SBrandon Wyman .WillOnce(Return("FW3456")); 3563c530fbdSBrandon Wyman #endif 3571d7a7df8SBrandon Wyman psu.updateInventory(); 3581d7a7df8SBrandon Wyman // TODO: D-Bus mocking to verify values stored on D-Bus (???) 3591d7a7df8SBrandon Wyman } 3601d7a7df8SBrandon Wyman catch (...) 3611d7a7df8SBrandon Wyman { 3621d7a7df8SBrandon Wyman ADD_FAILURE() << "Should not have caught exception."; 3631d7a7df8SBrandon Wyman } 3643f1242f3SBrandon Wyman } 3653f1242f3SBrandon Wyman 3663f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent) 3673f1242f3SBrandon Wyman { 3683f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 369*681b2a36SB. J. Wyman 370*681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 371*681b2a36SB. J. Wyman MockedGPIOReader* mockPresenceGPIO = 372*681b2a36SB. J. Wyman static_cast<MockedGPIOReader*>(psu.getPresenceGPIO()); 3733f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 3743f1242f3SBrandon Wyman 375*681b2a36SB. J. Wyman // Change GPIO read to return 1 to indicate present. 376*681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1)); 377*681b2a36SB. J. Wyman psu.analyze(); 378*681b2a36SB. J. Wyman EXPECT_EQ(psu.isPresent(), true); 3793f1242f3SBrandon Wyman } 3803f1242f3SBrandon Wyman 3813f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted) 3823f1242f3SBrandon Wyman { 3833f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 384*681b2a36SB. J. Wyman 385*681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, PSUGPIOLineName}; 386*681b2a36SB. J. Wyman MockedGPIOReader* mockPresenceGPIO = 387*681b2a36SB. J. Wyman static_cast<MockedGPIOReader*>(psu.getPresenceGPIO()); 388*681b2a36SB. J. Wyman // Always return 1 to indicate present. 389*681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 390*681b2a36SB. J. Wyman psu.analyze(); 3913f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 3923f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 39310d94055SJay Meyer EXPECT_CALL(mockPMBus, read(_, _)) 39410d94055SJay Meyer .Times(2) 39510d94055SJay Meyer .WillOnce(Return(0xFFFF)) 39610d94055SJay Meyer .WillOnce(Return(1)); // mock return for read(STATUS_MFR... ) 3973f1242f3SBrandon Wyman psu.analyze(); 3983f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 3993f1242f3SBrandon Wyman } 4003f1242f3SBrandon Wyman 4013f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasInputFault) 4023f1242f3SBrandon Wyman { 4033f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 404*681b2a36SB. J. Wyman 405*681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 406*681b2a36SB. J. Wyman MockedGPIOReader* mockPresenceGPIO = 407*681b2a36SB. J. Wyman static_cast<MockedGPIOReader*>(psu.getPresenceGPIO()); 408*681b2a36SB. J. Wyman // Always return 1 to indicate present. 409*681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 410*681b2a36SB. J. Wyman psu.analyze(); 4113f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 4123f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 4133f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000)); 4143f1242f3SBrandon Wyman psu.analyze(); 4153f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 4163f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 41710d94055SJay Meyer .Times(2) 41810d94055SJay Meyer .WillOnce(Return(status_word::INPUT_FAULT_WARN)) 41910d94055SJay Meyer .WillOnce(Return(0)); 4203f1242f3SBrandon Wyman psu.analyze(); 4213f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 4223f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000)); 4233f1242f3SBrandon Wyman psu.analyze(); 4243f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 4253f1242f3SBrandon Wyman } 4263f1242f3SBrandon Wyman 4273f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault) 4283f1242f3SBrandon Wyman { 4293f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 430*681b2a36SB. J. Wyman 431*681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 432*681b2a36SB. J. Wyman MockedGPIOReader* mockPresenceGPIO = 433*681b2a36SB. J. Wyman static_cast<MockedGPIOReader*>(psu.getPresenceGPIO()); 434*681b2a36SB. J. Wyman // Always return 1 to indicate present. 435*681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 436*681b2a36SB. J. Wyman psu.analyze(); 4373f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 4383f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 4393f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000)); 4403f1242f3SBrandon Wyman psu.analyze(); 4413f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 4423f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 44310d94055SJay Meyer .Times(2) 44410d94055SJay Meyer .WillOnce(Return(status_word::MFR_SPECIFIC_FAULT)) 44510d94055SJay Meyer .WillOnce(Return(1)); // mock return for read(STATUS_MFR... ) 4463f1242f3SBrandon Wyman psu.analyze(); 4473f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 4483f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000)); 4493f1242f3SBrandon Wyman psu.analyze(); 4503f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 4513f1242f3SBrandon Wyman } 4523f1242f3SBrandon Wyman 4533f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault) 4543f1242f3SBrandon Wyman { 4553f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 456*681b2a36SB. J. Wyman 457*681b2a36SB. J. Wyman PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName}; 458*681b2a36SB. J. Wyman MockedGPIOReader* mockPresenceGPIO = 459*681b2a36SB. J. Wyman static_cast<MockedGPIOReader*>(psu.getPresenceGPIO()); 460*681b2a36SB. J. Wyman // Always return 1 to indicate present. 461*681b2a36SB. J. Wyman EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1)); 462*681b2a36SB. J. Wyman psu.analyze(); 4633f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 4643f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 4653f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000)); 4663f1242f3SBrandon Wyman psu.analyze(); 4673f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 4683f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 46910d94055SJay Meyer .Times(2) 47010d94055SJay Meyer .WillOnce(Return(status_word::VIN_UV_FAULT)) 47110d94055SJay Meyer .WillOnce(Return(0)); 4723f1242f3SBrandon Wyman psu.analyze(); 4733f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 4743f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000)); 4753f1242f3SBrandon Wyman psu.analyze(); 4763f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 4773f1242f3SBrandon Wyman } 478