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