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::_; 143f1242f3SBrandon Wyman using ::testing::Assign; 153f1242f3SBrandon Wyman using ::testing::DoAll; 163f1242f3SBrandon Wyman using ::testing::Return; 173f1242f3SBrandon Wyman using ::testing::StrEq; 183f1242f3SBrandon Wyman 193f1242f3SBrandon Wyman static auto PSUInventoryPath = "/xyz/bmc/inv/sys/chassis/board/powersupply0"; 203f1242f3SBrandon Wyman 213f1242f3SBrandon Wyman class PowerSupplyTests : public ::testing::Test 223f1242f3SBrandon Wyman { 233f1242f3SBrandon Wyman public: 243f1242f3SBrandon Wyman PowerSupplyTests() : 253f1242f3SBrandon Wyman mockedUtil(reinterpret_cast<const MockedUtil&>(getUtils())) 263f1242f3SBrandon Wyman { 273f1242f3SBrandon Wyman ON_CALL(mockedUtil, getPresence(_, _)).WillByDefault(Return(false)); 283f1242f3SBrandon Wyman } 293f1242f3SBrandon Wyman 303f1242f3SBrandon Wyman ~PowerSupplyTests() override 313f1242f3SBrandon Wyman { 323f1242f3SBrandon Wyman freeUtils(); 333f1242f3SBrandon Wyman } 343f1242f3SBrandon Wyman 353f1242f3SBrandon Wyman const MockedUtil& mockedUtil; 363f1242f3SBrandon Wyman }; 373f1242f3SBrandon Wyman 383f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Constructor) 393f1242f3SBrandon Wyman { 403f1242f3SBrandon Wyman /** 413f1242f3SBrandon Wyman * @param[in] invpath - String for inventory path to use 423f1242f3SBrandon Wyman * @param[in] i2cbus - The bus number this power supply is on 433f1242f3SBrandon Wyman * @param[in] i2caddr - The 16-bit I2C address of the power supply 443f1242f3SBrandon Wyman */ 453f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 463f1242f3SBrandon Wyman EXPECT_CALL(mockedUtil, getPresence(_, StrEq(PSUInventoryPath))).Times(1); 473f1242f3SBrandon Wyman auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, "0068"); 483f1242f3SBrandon Wyman 493f1242f3SBrandon Wyman EXPECT_EQ(psu->isPresent(), false); 503f1242f3SBrandon Wyman EXPECT_EQ(psu->isFaulted(), false); 513f1242f3SBrandon Wyman EXPECT_EQ(psu->hasInputFault(), false); 523f1242f3SBrandon Wyman EXPECT_EQ(psu->hasMFRFault(), false); 533f1242f3SBrandon Wyman EXPECT_EQ(psu->hasVINUVFault(), false); 543f1242f3SBrandon Wyman } 553f1242f3SBrandon Wyman 563f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, Analyze) 573f1242f3SBrandon Wyman { 583f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 593f1242f3SBrandon Wyman 603f1242f3SBrandon Wyman EXPECT_CALL(mockedUtil, getPresence(_, StrEq(PSUInventoryPath))).Times(1); 613f1242f3SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 4, "0069"}; 623f1242f3SBrandon Wyman psu.analyze(); 633f1242f3SBrandon Wyman // By default, nothing should change. 643f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 653f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 663f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 673f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 683f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 693f1242f3SBrandon Wyman 703f1242f3SBrandon Wyman // In order to get the various faults tested, the power supply needs to be 713f1242f3SBrandon Wyman // present in order to read from the PMBus device(s). 723f1242f3SBrandon Wyman EXPECT_CALL(mockedUtil, getPresence(_, StrEq(PSUInventoryPath))) 733f1242f3SBrandon Wyman .Times(1) 743f1242f3SBrandon Wyman .WillOnce(Return(true)); // present 753f1242f3SBrandon Wyman PowerSupply psu2{bus, PSUInventoryPath, 5, "006a"}; 763f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 773f1242f3SBrandon Wyman 783f1242f3SBrandon Wyman // STATUS_WORD 0x0000 is powered on, no faults. 793f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus()); 803f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000)); 813f1242f3SBrandon Wyman psu2.analyze(); 823f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 833f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 843f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 853f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 863f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 873f1242f3SBrandon Wyman 883f1242f3SBrandon Wyman // STATUS_WORD input fault/warn 893f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 903f1242f3SBrandon Wyman .Times(1) 913f1242f3SBrandon Wyman .WillOnce(Return(status_word::INPUT_FAULT_WARN)); 923f1242f3SBrandon Wyman psu2.analyze(); 933f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 943f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), true); 953f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), true); 963f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 973f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 983f1242f3SBrandon Wyman 993f1242f3SBrandon Wyman // STATUS_WORD INPUT/UV fault. 1003f1242f3SBrandon Wyman // First need it to return good status, then the fault 1013f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 1023f1242f3SBrandon Wyman .WillOnce(Return(0x0000)) 1033f1242f3SBrandon Wyman .WillOnce(Return(status_word::VIN_UV_FAULT)); 1043f1242f3SBrandon Wyman psu2.analyze(); 1053f1242f3SBrandon Wyman psu2.analyze(); 1063f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 1073f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), true); 1083f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 1093f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 1103f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), true); 1113f1242f3SBrandon Wyman 1123f1242f3SBrandon Wyman // STATUS_WORD MFR fault. 1133f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 1143f1242f3SBrandon Wyman .WillOnce(Return(0x0000)) 1153f1242f3SBrandon Wyman .WillOnce(Return(status_word::MFR_SPECIFIC_FAULT)); 1163f1242f3SBrandon Wyman psu2.analyze(); 1173f1242f3SBrandon Wyman psu2.analyze(); 1183f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 1193f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), true); 1203f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 1213f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), true); 1223f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 1233f1242f3SBrandon Wyman 1243f1242f3SBrandon Wyman // Ignore Temperature fault. 1253f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 1263f1242f3SBrandon Wyman .WillOnce(Return(0x0000)) 1273f1242f3SBrandon Wyman .WillOnce(Return(status_word::TEMPERATURE_FAULT_WARN)); 1283f1242f3SBrandon Wyman psu2.analyze(); 1293f1242f3SBrandon Wyman psu2.analyze(); 1303f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 1313f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 1323f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 1333f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 1343f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 1353f1242f3SBrandon Wyman 1363f1242f3SBrandon Wyman // Ignore fan fault 1373f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 1383f1242f3SBrandon Wyman .WillOnce(Return(0x0000)) 1393f1242f3SBrandon Wyman .WillOnce(Return(status_word::FAN_FAULT)); 1403f1242f3SBrandon Wyman psu2.analyze(); 1413f1242f3SBrandon Wyman psu2.analyze(); 1423f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 1433f1242f3SBrandon Wyman EXPECT_EQ(psu2.isFaulted(), false); 1443f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasInputFault(), false); 1453f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasMFRFault(), false); 1463f1242f3SBrandon Wyman EXPECT_EQ(psu2.hasVINUVFault(), false); 1473f1242f3SBrandon Wyman 1483f1242f3SBrandon Wyman // TODO: ReadFailure 1493f1242f3SBrandon Wyman } 1503f1242f3SBrandon Wyman 1513f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, ClearFaults) 1523f1242f3SBrandon Wyman { 1533f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1543f1242f3SBrandon Wyman EXPECT_CALL(mockedUtil, getPresence(_, StrEq(PSUInventoryPath))) 1553f1242f3SBrandon Wyman .Times(1) 1563f1242f3SBrandon Wyman .WillOnce(Return(true)); // present 1573f1242f3SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 13, "0068"}; 1583f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 1593f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 1603f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 1613f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 1623f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 1633f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 1643f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0xFFFF)); 1653f1242f3SBrandon Wyman psu.analyze(); 1663f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 1673f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 1683f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 1693f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 1703f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 171*3c208464SBrandon Wyman EXPECT_CALL(mockPMBus, read("in1_input", _)) 172*3c208464SBrandon Wyman .Times(1) 173*3c208464SBrandon Wyman .WillOnce(Return(209000)); 1743f1242f3SBrandon Wyman psu.clearFaults(); 1753f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), true); 1763f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 1773f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 1783f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 1793f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 1803f1242f3SBrandon Wyman } 1813f1242f3SBrandon Wyman 1823f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory) 1833f1242f3SBrandon Wyman { 1843f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1853f1242f3SBrandon Wyman EXPECT_CALL(mockedUtil, getPresence(_, StrEq(PSUInventoryPath))) 1863f1242f3SBrandon Wyman .Times(1) 1873f1242f3SBrandon Wyman .WillOnce(Return(true)); // present 1883f1242f3SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, "0068"}; 1893f1242f3SBrandon Wyman psu.updateInventory(); 1903f1242f3SBrandon Wyman // TODO: Checks / Story #921 1913f1242f3SBrandon Wyman } 1923f1242f3SBrandon Wyman 1933f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent) 1943f1242f3SBrandon Wyman { 1953f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 1963f1242f3SBrandon Wyman EXPECT_CALL(mockedUtil, getPresence(_, StrEq(PSUInventoryPath))).Times(1); 1973f1242f3SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, "0068"}; 1983f1242f3SBrandon Wyman EXPECT_EQ(psu.isPresent(), false); 1993f1242f3SBrandon Wyman 2003f1242f3SBrandon Wyman EXPECT_CALL(mockedUtil, getPresence(_, _)) 2013f1242f3SBrandon Wyman .WillOnce(Return(true)); // present 2023f1242f3SBrandon Wyman PowerSupply psu2{bus, PSUInventoryPath, 10, "006b"}; 2033f1242f3SBrandon Wyman EXPECT_EQ(psu2.isPresent(), true); 2043f1242f3SBrandon Wyman } 2053f1242f3SBrandon Wyman 2063f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted) 2073f1242f3SBrandon Wyman { 2083f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2093f1242f3SBrandon Wyman EXPECT_CALL(mockedUtil, getPresence(_, _)) 2103f1242f3SBrandon Wyman .WillOnce(Return(true)); // present 2113f1242f3SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 11, "006f"}; 2123f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), false); 2133f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2143f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0xFFFF)); 2153f1242f3SBrandon Wyman psu.analyze(); 2163f1242f3SBrandon Wyman EXPECT_EQ(psu.isFaulted(), true); 2173f1242f3SBrandon Wyman } 2183f1242f3SBrandon Wyman 2193f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasInputFault) 2203f1242f3SBrandon Wyman { 2213f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2223f1242f3SBrandon Wyman EXPECT_CALL(mockedUtil, getPresence(_, _)) 2233f1242f3SBrandon Wyman .WillOnce(Return(true)); // present 2243f1242f3SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, "0068"}; 2253f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2263f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 2273f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000)); 2283f1242f3SBrandon Wyman psu.analyze(); 2293f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 2303f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 2313f1242f3SBrandon Wyman .Times(1) 2323f1242f3SBrandon Wyman .WillOnce(Return(status_word::INPUT_FAULT_WARN)); 2333f1242f3SBrandon Wyman psu.analyze(); 2343f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), true); 2353f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000)); 2363f1242f3SBrandon Wyman psu.analyze(); 2373f1242f3SBrandon Wyman EXPECT_EQ(psu.hasInputFault(), false); 2383f1242f3SBrandon Wyman } 2393f1242f3SBrandon Wyman 2403f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault) 2413f1242f3SBrandon Wyman { 2423f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2433f1242f3SBrandon Wyman EXPECT_CALL(mockedUtil, getPresence(_, _)) 2443f1242f3SBrandon Wyman .WillOnce(Return(true)); // present 2453f1242f3SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, "0068"}; 2463f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2473f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 2483f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000)); 2493f1242f3SBrandon Wyman psu.analyze(); 2503f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 2513f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 2523f1242f3SBrandon Wyman .Times(1) 2533f1242f3SBrandon Wyman .WillOnce(Return(status_word::MFR_SPECIFIC_FAULT)); 2543f1242f3SBrandon Wyman psu.analyze(); 2553f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), true); 2563f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000)); 2573f1242f3SBrandon Wyman psu.analyze(); 2583f1242f3SBrandon Wyman EXPECT_EQ(psu.hasMFRFault(), false); 2593f1242f3SBrandon Wyman } 2603f1242f3SBrandon Wyman 2613f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault) 2623f1242f3SBrandon Wyman { 2633f1242f3SBrandon Wyman auto bus = sdbusplus::bus::new_default(); 2643f1242f3SBrandon Wyman EXPECT_CALL(mockedUtil, getPresence(_, _)) 2653f1242f3SBrandon Wyman .WillOnce(Return(true)); // present 2663f1242f3SBrandon Wyman PowerSupply psu{bus, PSUInventoryPath, 3, "0068"}; 2673f1242f3SBrandon Wyman MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus()); 2683f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 2693f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000)); 2703f1242f3SBrandon Wyman psu.analyze(); 2713f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 2723f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)) 2733f1242f3SBrandon Wyman .Times(1) 2743f1242f3SBrandon Wyman .WillOnce(Return(status_word::VIN_UV_FAULT)); 2753f1242f3SBrandon Wyman psu.analyze(); 2763f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), true); 2773f1242f3SBrandon Wyman EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000)); 2783f1242f3SBrandon Wyman psu.analyze(); 2793f1242f3SBrandon Wyman EXPECT_EQ(psu.hasVINUVFault(), false); 2803f1242f3SBrandon Wyman } 281