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};
133681b2a36SB. J. Wyman     MockedGPIOReader* mockPresenceGPIO =
134681b2a36SB. J. Wyman         static_cast<MockedGPIOReader*>(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);
1443f1242f3SBrandon Wyman 
145681b2a36SB. J. Wyman     PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
146681b2a36SB. J. Wyman     // In order to get the various faults tested, the power supply needs to
147681b2a36SB. J. Wyman     // be present in order to read from the PMBus device(s).
148681b2a36SB. J. Wyman     MockedGPIOReader* mockPresenceGPIO2 =
149681b2a36SB. J. Wyman         static_cast<MockedGPIOReader*>(psu2.getPresenceGPIO());
150681b2a36SB. J. Wyman     ON_CALL(*mockPresenceGPIO2, read()).WillByDefault(Return(1));
151681b2a36SB. J. Wyman 
152681b2a36SB. J. Wyman     EXPECT_EQ(psu2.isPresent(), false);
1533f1242f3SBrandon Wyman 
1543f1242f3SBrandon Wyman     // STATUS_WORD 0x0000 is powered on, no faults.
155681b2a36SB. 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());
157681b2a36SB. 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     {
241681b2a36SB. J. Wyman         // Assume GPIO presence, not inventory presence?
242681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
243681b2a36SB. J. Wyman 
244681b2a36SB. J. Wyman         MockedGPIOReader* mockPresenceGPIO =
245681b2a36SB. J. Wyman             static_cast<MockedGPIOReader*>(psu.getPresenceGPIO());
246681b2a36SB. J. Wyman         ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0));
24759a35793SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
248681b2a36SB. 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 (...)
254*0c9a33d6SAdriana Kobylak     {}
25559a35793SBrandon Wyman 
25659a35793SBrandon Wyman     // Test where PSU is present
25759a35793SBrandon Wyman     try
25859a35793SBrandon Wyman     {
259681b2a36SB. J. Wyman         // Assume GPIO presence, not inventory presence?
260681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
261681b2a36SB. J. Wyman         MockedGPIOReader* mockPresenceGPIO =
262681b2a36SB. J. Wyman             static_cast<MockedGPIOReader*>(psu.getPresenceGPIO());
263681b2a36SB. J. Wyman         ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(1));
26459a35793SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
265681b2a36SB. J. Wyman         // TODO: expect setPresence call?
266681b2a36SB. J. Wyman         // updatePresence() private function reads gpio, called by analyze().
267681b2a36SB. J. Wyman         psu.analyze();
26859a35793SBrandon Wyman         // TODO: ???should I check the filename?
26959a35793SBrandon Wyman         EXPECT_CALL(mockPMBus,
27059a35793SBrandon Wyman                     writeBinary(_, ElementsAre(0x15), Type::HwmonDeviceDebug))
27159a35793SBrandon Wyman             .Times(1);
27259a35793SBrandon Wyman         psu.onOffConfig(data);
27359a35793SBrandon Wyman     }
27459a35793SBrandon Wyman     catch (...)
275*0c9a33d6SAdriana Kobylak     {}
27659a35793SBrandon Wyman }
27759a35793SBrandon Wyman 
2783f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, ClearFaults)
2793f1242f3SBrandon Wyman {
2803f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
281681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, PSUGPIOLineName};
282681b2a36SB. J. Wyman     MockedGPIOReader* mockPresenceGPIO =
283681b2a36SB. J. Wyman         static_cast<MockedGPIOReader*>(psu.getPresenceGPIO());
284681b2a36SB. J. Wyman     // GPIO read return 1 to indicate present.
285681b2a36SB. J. Wyman     ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(1));
286681b2a36SB. J. Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
287681b2a36SB. J. Wyman     ON_CALL(mockPMBus, read(_, _)).WillByDefault(Return(0));
288681b2a36SB. J. Wyman     psu.analyze();
2893f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), true);
2903f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), false);
2913f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
2923f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
2933f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
29410d94055SJay Meyer     EXPECT_CALL(mockPMBus, read(_, _))
29510d94055SJay Meyer         .Times(2)
29610d94055SJay Meyer         .WillOnce(Return(0xFFFF))
29710d94055SJay Meyer         .WillOnce(Return(1)); // mock return for read(STATUS_MFR... )
2983f1242f3SBrandon Wyman     psu.analyze();
2993f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), true);
3003f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), true);
3013f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), true);
3023f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), true);
3033f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), true);
3043c208464SBrandon Wyman     EXPECT_CALL(mockPMBus, read("in1_input", _))
3053c208464SBrandon Wyman         .Times(1)
3063c208464SBrandon Wyman         .WillOnce(Return(209000));
3073f1242f3SBrandon Wyman     psu.clearFaults();
3083f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), true);
3093f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), false);
3103f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
3113f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
3123f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
313681b2a36SB. J. Wyman 
314681b2a36SB. J. Wyman     // TODO: Faults clear on missing/present?
3153f1242f3SBrandon Wyman }
3163f1242f3SBrandon Wyman 
3173f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, UpdateInventory)
3183f1242f3SBrandon Wyman {
3193f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
3201d7a7df8SBrandon Wyman 
3211d7a7df8SBrandon Wyman     try
3221d7a7df8SBrandon Wyman     {
323681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
3241d7a7df8SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
3251d7a7df8SBrandon Wyman         // If it is not present, I should not be trying to read a string
3261d7a7df8SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(_, _)).Times(0);
3271d7a7df8SBrandon Wyman         psu.updateInventory();
3281d7a7df8SBrandon Wyman     }
3291d7a7df8SBrandon Wyman     catch (...)
3301d7a7df8SBrandon Wyman     {
3311d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have caught exception.";
3321d7a7df8SBrandon Wyman     }
3331d7a7df8SBrandon Wyman 
3341d7a7df8SBrandon Wyman     try
3351d7a7df8SBrandon Wyman     {
336681b2a36SB. J. Wyman         PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, PSUGPIOLineName};
337681b2a36SB. J. Wyman         MockedGPIOReader* mockPresenceGPIO =
338681b2a36SB. J. Wyman             static_cast<MockedGPIOReader*>(psu.getPresenceGPIO());
339681b2a36SB. J. Wyman         // GPIO read return 1 to indicate present.
340681b2a36SB. J. Wyman         EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
341681b2a36SB. J. Wyman         psu.analyze();
3421d7a7df8SBrandon Wyman         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
3431d7a7df8SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return(""));
3443f1242f3SBrandon Wyman         psu.updateInventory();
3451d7a7df8SBrandon Wyman 
3463c530fbdSBrandon Wyman #if IBM_VPD
3471d7a7df8SBrandon Wyman         EXPECT_CALL(mockPMBus, readString(_, _))
3481d7a7df8SBrandon Wyman             .WillOnce(Return("CCIN"))
3491d7a7df8SBrandon Wyman             .WillOnce(Return("PN3456"))
3501d7a7df8SBrandon Wyman             .WillOnce(Return("FN3456"))
3511d7a7df8SBrandon Wyman             .WillOnce(Return("HEADER"))
3521d7a7df8SBrandon Wyman             .WillOnce(Return("SN3456"))
3531d7a7df8SBrandon Wyman             .WillOnce(Return("FW3456"));
3543c530fbdSBrandon Wyman #endif
3551d7a7df8SBrandon Wyman         psu.updateInventory();
3561d7a7df8SBrandon Wyman         // TODO: D-Bus mocking to verify values stored on D-Bus (???)
3571d7a7df8SBrandon Wyman     }
3581d7a7df8SBrandon Wyman     catch (...)
3591d7a7df8SBrandon Wyman     {
3601d7a7df8SBrandon Wyman         ADD_FAILURE() << "Should not have caught exception.";
3611d7a7df8SBrandon Wyman     }
3623f1242f3SBrandon Wyman }
3633f1242f3SBrandon Wyman 
3643f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsPresent)
3653f1242f3SBrandon Wyman {
3663f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
367681b2a36SB. J. Wyman 
368681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
369681b2a36SB. J. Wyman     MockedGPIOReader* mockPresenceGPIO =
370681b2a36SB. J. Wyman         static_cast<MockedGPIOReader*>(psu.getPresenceGPIO());
3713f1242f3SBrandon Wyman     EXPECT_EQ(psu.isPresent(), false);
3723f1242f3SBrandon Wyman 
373681b2a36SB. J. Wyman     // Change GPIO read to return 1 to indicate present.
374681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
375681b2a36SB. J. Wyman     psu.analyze();
376681b2a36SB. J. Wyman     EXPECT_EQ(psu.isPresent(), true);
3773f1242f3SBrandon Wyman }
3783f1242f3SBrandon Wyman 
3793f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, IsFaulted)
3803f1242f3SBrandon Wyman {
3813f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
382681b2a36SB. J. Wyman 
383681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, PSUGPIOLineName};
384681b2a36SB. J. Wyman     MockedGPIOReader* mockPresenceGPIO =
385681b2a36SB. J. Wyman         static_cast<MockedGPIOReader*>(psu.getPresenceGPIO());
386681b2a36SB. J. Wyman     // Always return 1 to indicate present.
387681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
388681b2a36SB. J. Wyman     psu.analyze();
3893f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), false);
3903f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
39110d94055SJay Meyer     EXPECT_CALL(mockPMBus, read(_, _))
39210d94055SJay Meyer         .Times(2)
39310d94055SJay Meyer         .WillOnce(Return(0xFFFF))
39410d94055SJay Meyer         .WillOnce(Return(1)); // mock return for read(STATUS_MFR... )
3953f1242f3SBrandon Wyman     psu.analyze();
3963f1242f3SBrandon Wyman     EXPECT_EQ(psu.isFaulted(), true);
3973f1242f3SBrandon Wyman }
3983f1242f3SBrandon Wyman 
3993f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasInputFault)
4003f1242f3SBrandon Wyman {
4013f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
402681b2a36SB. J. Wyman 
403681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
404681b2a36SB. J. Wyman     MockedGPIOReader* mockPresenceGPIO =
405681b2a36SB. J. Wyman         static_cast<MockedGPIOReader*>(psu.getPresenceGPIO());
406681b2a36SB. J. Wyman     // Always return 1 to indicate present.
407681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
408681b2a36SB. J. Wyman     psu.analyze();
4093f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
4103f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
4113f1242f3SBrandon Wyman     EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000));
4123f1242f3SBrandon Wyman     psu.analyze();
4133f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
4143f1242f3SBrandon Wyman     EXPECT_CALL(mockPMBus, read(_, _))
41510d94055SJay Meyer         .Times(2)
41610d94055SJay Meyer         .WillOnce(Return(status_word::INPUT_FAULT_WARN))
41710d94055SJay Meyer         .WillOnce(Return(0));
4183f1242f3SBrandon Wyman     psu.analyze();
4193f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), true);
4203f1242f3SBrandon Wyman     EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000));
4213f1242f3SBrandon Wyman     psu.analyze();
4223f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasInputFault(), false);
4233f1242f3SBrandon Wyman }
4243f1242f3SBrandon Wyman 
4253f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasMFRFault)
4263f1242f3SBrandon Wyman {
4273f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
428681b2a36SB. J. Wyman 
429681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
430681b2a36SB. J. Wyman     MockedGPIOReader* mockPresenceGPIO =
431681b2a36SB. J. Wyman         static_cast<MockedGPIOReader*>(psu.getPresenceGPIO());
432681b2a36SB. J. Wyman     // Always return 1 to indicate present.
433681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
434681b2a36SB. J. Wyman     psu.analyze();
4353f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
4363f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
4373f1242f3SBrandon Wyman     EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000));
4383f1242f3SBrandon Wyman     psu.analyze();
4393f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
4403f1242f3SBrandon Wyman     EXPECT_CALL(mockPMBus, read(_, _))
44110d94055SJay Meyer         .Times(2)
44210d94055SJay Meyer         .WillOnce(Return(status_word::MFR_SPECIFIC_FAULT))
44310d94055SJay Meyer         .WillOnce(Return(1)); // mock return for read(STATUS_MFR... )
4443f1242f3SBrandon Wyman     psu.analyze();
4453f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), true);
4463f1242f3SBrandon Wyman     EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000));
4473f1242f3SBrandon Wyman     psu.analyze();
4483f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasMFRFault(), false);
4493f1242f3SBrandon Wyman }
4503f1242f3SBrandon Wyman 
4513f1242f3SBrandon Wyman TEST_F(PowerSupplyTests, HasVINUVFault)
4523f1242f3SBrandon Wyman {
4533f1242f3SBrandon Wyman     auto bus = sdbusplus::bus::new_default();
454681b2a36SB. J. Wyman 
455681b2a36SB. J. Wyman     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
456681b2a36SB. J. Wyman     MockedGPIOReader* mockPresenceGPIO =
457681b2a36SB. J. Wyman         static_cast<MockedGPIOReader*>(psu.getPresenceGPIO());
458681b2a36SB. J. Wyman     // Always return 1 to indicate present.
459681b2a36SB. J. Wyman     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
460681b2a36SB. J. Wyman     psu.analyze();
4613f1242f3SBrandon Wyman     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
4623f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
4633f1242f3SBrandon Wyman     EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000));
4643f1242f3SBrandon Wyman     psu.analyze();
4653f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
4663f1242f3SBrandon Wyman     EXPECT_CALL(mockPMBus, read(_, _))
46710d94055SJay Meyer         .Times(2)
46810d94055SJay Meyer         .WillOnce(Return(status_word::VIN_UV_FAULT))
46910d94055SJay Meyer         .WillOnce(Return(0));
4703f1242f3SBrandon Wyman     psu.analyze();
4713f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), true);
4723f1242f3SBrandon Wyman     EXPECT_CALL(mockPMBus, read(_, _)).Times(1).WillOnce(Return(0x0000));
4733f1242f3SBrandon Wyman     psu.analyze();
4743f1242f3SBrandon Wyman     EXPECT_EQ(psu.hasVINUVFault(), false);
4753f1242f3SBrandon Wyman }
476