blob: 0417b5a36ee24c826c179c4d72d79d83480caae1 [file] [log] [blame]
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001#include "../power_supply.hpp"
Brandon Wymanc3324422022-03-24 20:30:57 +00002#include "../record_manager.hpp"
Brandon Wyman3f1242f2020-01-28 13:11:25 -06003#include "mock.hpp"
4
5#include <xyz/openbmc_project/Common/Device/error.hpp>
6#include <xyz/openbmc_project/Common/error.hpp>
7
8#include <gmock/gmock.h>
9#include <gtest/gtest.h>
10
11using namespace phosphor::power::psu;
12using namespace phosphor::pmbus;
13
14using ::testing::_;
Brandon Wyman59a35792020-06-04 12:37:40 -050015using ::testing::Args;
Brandon Wyman3f1242f2020-01-28 13:11:25 -060016using ::testing::Assign;
17using ::testing::DoAll;
Brandon Wyman59a35792020-06-04 12:37:40 -050018using ::testing::ElementsAre;
19using ::testing::NotNull;
Brandon Wyman3f1242f2020-01-28 13:11:25 -060020using ::testing::Return;
21using ::testing::StrEq;
22
23static auto PSUInventoryPath = "/xyz/bmc/inv/sys/chassis/board/powersupply0";
B. J. Wyman681b2a32021-04-20 22:31:22 +000024static auto PSUGPIOLineName = "presence-ps0";
George Liu9464c422023-02-27 14:30:27 +080025static auto isPowerOn = []() { return true; };
Brandon Wyman3f1242f2020-01-28 13:11:25 -060026
Brandon Wymanb654c612021-11-05 23:24:51 +000027struct PMBusExpectations
28{
29 uint16_t statusWordValue{0x0000};
30 uint8_t statusInputValue{0x00};
31 uint8_t statusMFRValue{0x00};
32 uint8_t statusCMLValue{0x00};
33 uint8_t statusVOUTValue{0x00};
Brandon Wymanb10b3be2021-11-09 22:12:15 +000034 uint8_t statusIOUTValue{0x00};
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +000035 uint8_t statusFans12Value{0x00};
Brandon Wyman96893a42021-11-05 19:56:57 +000036 uint8_t statusTempValue{0x00};
Brandon Wymanb654c612021-11-05 23:24:51 +000037};
38
Brandon Wyman8da35c52021-10-28 22:45:08 +000039// Helper function to setup expectations for various STATUS_* commands
Brandon Wymanb654c612021-11-05 23:24:51 +000040void setPMBusExpectations(MockedPMBus& mockPMBus,
41 const PMBusExpectations& expectations)
Brandon Wyman8da35c52021-10-28 22:45:08 +000042{
Brandon Wyman32453e92021-12-15 19:00:14 +000043 EXPECT_CALL(mockPMBus, read(STATUS_WORD, _, _))
Brandon Wyman8da35c52021-10-28 22:45:08 +000044 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000045 .WillOnce(Return(expectations.statusWordValue));
Brandon Wyman8da35c52021-10-28 22:45:08 +000046
Brandon Wymanb654c612021-11-05 23:24:51 +000047 if (expectations.statusWordValue != 0)
Brandon Wyman8da35c52021-10-28 22:45:08 +000048 {
49 // If fault bits are on in STATUS_WORD, there will also be a read of
Brandon Wyman96893a42021-11-05 19:56:57 +000050 // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT (page 0), and
51 // STATUS_TEMPERATURE.
Brandon Wyman32453e92021-12-15 19:00:14 +000052 EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _, _))
Brandon Wyman8da35c52021-10-28 22:45:08 +000053 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000054 .WillOnce(Return(expectations.statusInputValue));
Brandon Wyman32453e92021-12-15 19:00:14 +000055 EXPECT_CALL(mockPMBus, read(STATUS_MFR, _, _))
Brandon Wyman8da35c52021-10-28 22:45:08 +000056 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000057 .WillOnce(Return(expectations.statusMFRValue));
Brandon Wyman32453e92021-12-15 19:00:14 +000058 EXPECT_CALL(mockPMBus, read(STATUS_CML, _, _))
Brandon Wyman8da35c52021-10-28 22:45:08 +000059 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000060 .WillOnce(Return(expectations.statusCMLValue));
Brandon Wyman6710ba22021-10-27 17:39:31 +000061 // Page will need to be set to 0 to read STATUS_VOUT.
62 EXPECT_CALL(mockPMBus, insertPageNum(STATUS_VOUT, 0))
63 .Times(1)
64 .WillOnce(Return("status0_vout"));
Brandon Wyman32453e92021-12-15 19:00:14 +000065 EXPECT_CALL(mockPMBus, read("status0_vout", _, _))
Brandon Wyman6710ba22021-10-27 17:39:31 +000066 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000067 .WillOnce(Return(expectations.statusVOUTValue));
Brandon Wyman32453e92021-12-15 19:00:14 +000068 EXPECT_CALL(mockPMBus, read(STATUS_IOUT, _, _))
Brandon Wymanb10b3be2021-11-09 22:12:15 +000069 .Times(1)
70 .WillOnce(Return(expectations.statusIOUTValue));
Brandon Wyman32453e92021-12-15 19:00:14 +000071 EXPECT_CALL(mockPMBus, read(STATUS_FANS_1_2, _, _))
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +000072 .Times(1)
73 .WillOnce(Return(expectations.statusFans12Value));
Brandon Wyman32453e92021-12-15 19:00:14 +000074 EXPECT_CALL(mockPMBus, read(STATUS_TEMPERATURE, _, _))
Brandon Wyman96893a42021-11-05 19:56:57 +000075 .Times(1)
76 .WillOnce(Return(expectations.statusTempValue));
Brandon Wyman8da35c52021-10-28 22:45:08 +000077 }
78}
79
Brandon Wyman3f1242f2020-01-28 13:11:25 -060080class PowerSupplyTests : public ::testing::Test
81{
82 public:
83 PowerSupplyTests() :
84 mockedUtil(reinterpret_cast<const MockedUtil&>(getUtils()))
85 {
86 ON_CALL(mockedUtil, getPresence(_, _)).WillByDefault(Return(false));
87 }
88
89 ~PowerSupplyTests() override
90 {
91 freeUtils();
92 }
93
94 const MockedUtil& mockedUtil;
95};
96
Brandon Wyman391a0692021-12-08 23:28:18 +000097// Helper function for when a power supply goes from missing to present.
98void setMissingToPresentExpects(MockedPMBus& pmbus, const MockedUtil& util)
99{
100 // Call to analyze() will update to present, that will trigger updating
101 // to the correct/latest HWMON directory, in case it changes.
102 EXPECT_CALL(pmbus, findHwmonDir());
103 // Presence change from missing to present will trigger write to
104 // ON_OFF_CONFIG.
105 EXPECT_CALL(pmbus, writeBinary(ON_OFF_CONFIG, _, _));
106 // Presence change from missing to present will trigger in1_input read
107 // in an attempt to get CLEAR_FAULTS called.
Brandon Wyman82affd92021-11-24 19:12:49 +0000108 // This READ_VIN for CLEAR_FAULTS does not check the returned value.
Brandon Wyman3225a452022-03-18 18:51:49 +0000109 EXPECT_CALL(pmbus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
110 // The call for clearing faults includes clearing VIN_UV fault.
111 // The voltage defaults to 0, the first call to analyze should update the
112 // voltage to the current reading, triggering clearing VIN_UV fault(s)
113 // due to below minimum to within range voltage.
114 EXPECT_CALL(pmbus, read("in1_lcrit_alarm", _, _))
Brandon Wyman82affd92021-11-24 19:12:49 +0000115 .Times(2)
Brandon Wyman3225a452022-03-18 18:51:49 +0000116 .WillRepeatedly(Return(1));
Brandon Wyman391a0692021-12-08 23:28:18 +0000117 // Missing/present call will update Presence in inventory.
Brandon Wyman391a0692021-12-08 23:28:18 +0000118 EXPECT_CALL(util, setPresence(_, _, true, _));
119}
120
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600121TEST_F(PowerSupplyTests, Constructor)
122{
123 /**
124 * @param[in] invpath - String for inventory path to use
125 * @param[in] i2cbus - The bus number this power supply is on
126 * @param[in] i2caddr - The 16-bit I2C address of the power supply
B. J. Wyman681b2a32021-04-20 22:31:22 +0000127 * @param[in] gpioLineName - The string for the gpio-line-name to read for
128 * presence.
129 * @param[in] bindDelay - Time in milliseconds to delay binding the device
130 * driver after seeing the presence line go active.
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600131 */
132 auto bus = sdbusplus::bus::new_default();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600133
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500134 // Try where inventory path is empty, constructor should fail.
135 try
136 {
Brandon Wymanc3324422022-03-24 20:30:57 +0000137 auto psu = std::make_unique<PowerSupply>(bus, "", 3, 0x68, "ibm-cffps",
George Liu9464c422023-02-27 14:30:27 +0800138 PSUGPIOLineName, isPowerOn);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500139 ADD_FAILURE() << "Should not have reached this line.";
140 }
141 catch (const std::invalid_argument& e)
142 {
143 EXPECT_STREQ(e.what(), "Invalid empty inventoryPath");
144 }
145 catch (...)
146 {
147 ADD_FAILURE() << "Should not have caught exception.";
148 }
149
B. J. Wyman681b2a32021-04-20 22:31:22 +0000150 // TODO: Try invalid i2c address?
151
152 // Try where gpioLineName is empty.
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500153 try
154 {
Brandon Wymanc3324422022-03-24 20:30:57 +0000155 auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68,
George Liu9464c422023-02-27 14:30:27 +0800156 "ibm-cffps", "", isPowerOn);
B. J. Wyman681b2a32021-04-20 22:31:22 +0000157 ADD_FAILURE()
158 << "Should not have reached this line. Invalid gpioLineName.";
159 }
160 catch (const std::invalid_argument& e)
161 {
162 EXPECT_STREQ(e.what(), "Invalid empty gpioLineName");
163 }
164 catch (...)
165 {
166 ADD_FAILURE() << "Should not have caught exception.";
167 }
168
169 // Test with valid arguments
170 // NOT using D-Bus inventory path for presence.
171 try
172 {
173 auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68,
George Liu9464c422023-02-27 14:30:27 +0800174 "ibm-cffps", PSUGPIOLineName,
175 isPowerOn);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500176
177 EXPECT_EQ(psu->isPresent(), false);
178 EXPECT_EQ(psu->isFaulted(), false);
Brandon Wyman8da35c52021-10-28 22:45:08 +0000179 EXPECT_EQ(psu->hasCommFault(), false);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500180 EXPECT_EQ(psu->hasInputFault(), false);
181 EXPECT_EQ(psu->hasMFRFault(), false);
182 EXPECT_EQ(psu->hasVINUVFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000183 EXPECT_EQ(psu->hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000184 EXPECT_EQ(psu->hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000185 EXPECT_EQ(psu->hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000186 EXPECT_EQ(psu->hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000187 EXPECT_EQ(psu->hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000188 EXPECT_EQ(psu->hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000189 EXPECT_EQ(psu->hasPSKillFault(), false);
190 EXPECT_EQ(psu->hasPS12VcsFault(), false);
191 EXPECT_EQ(psu->hasPSCS12VFault(), false);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500192 }
193 catch (...)
194 {
195 ADD_FAILURE() << "Should not have caught exception.";
196 }
B. J. Wyman681b2a32021-04-20 22:31:22 +0000197
198 // Test with valid arguments
199 // TODO: Using D-Bus inventory path for presence.
200 try
201 {
202 // FIXME: How do I get that presenceGPIO.read() in the startup to throw
203 // an exception?
204
205 // EXPECT_CALL(mockedUtil, getPresence(_,
206 // StrEq(PSUInventoryPath)))
207 // .Times(1);
208 }
209 catch (...)
210 {
211 ADD_FAILURE() << "Should not have caught exception.";
212 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600213}
214
215TEST_F(PowerSupplyTests, Analyze)
216{
217 auto bus = sdbusplus::bus::new_default();
218
Brandon Wymanb654c612021-11-05 23:24:51 +0000219 {
220 // If I default to reading the GPIO, I will NOT expect a call to
221 // getPresence().
B. J. Wyman681b2a32021-04-20 22:31:22 +0000222
George Liu9464c422023-02-27 14:30:27 +0800223 PowerSupply psu{bus, PSUInventoryPath, 4, 0x69,
224 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Brandon Wymanb654c612021-11-05 23:24:51 +0000225 MockedGPIOInterface* mockPresenceGPIO =
226 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
227 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000228
Brandon Wymanb654c612021-11-05 23:24:51 +0000229 psu.analyze();
230 // By default, nothing should change.
231 EXPECT_EQ(psu.isPresent(), false);
232 EXPECT_EQ(psu.isFaulted(), false);
233 EXPECT_EQ(psu.hasInputFault(), false);
234 EXPECT_EQ(psu.hasMFRFault(), false);
235 EXPECT_EQ(psu.hasVINUVFault(), false);
236 EXPECT_EQ(psu.hasCommFault(), false);
237 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000238 EXPECT_EQ(psu.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000239 EXPECT_EQ(psu.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000240 EXPECT_EQ(psu.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000241 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000242 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000243 EXPECT_EQ(psu.hasPSKillFault(), false);
244 EXPECT_EQ(psu.hasPS12VcsFault(), false);
245 EXPECT_EQ(psu.hasPSCS12VFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000246 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600247
George Liu9464c422023-02-27 14:30:27 +0800248 PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a,
249 "ibm-cffps", PSUGPIOLineName, isPowerOn};
B. J. Wyman681b2a32021-04-20 22:31:22 +0000250 // In order to get the various faults tested, the power supply needs to
251 // be present in order to read from the PMBus device(s).
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000252 MockedGPIOInterface* mockPresenceGPIO2 =
253 static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO());
Brandon Wyman06ca4592021-12-06 22:52:23 +0000254 // Always return 1 to indicate present.
255 // Each analyze() call will trigger a read of the presence GPIO.
256 EXPECT_CALL(*mockPresenceGPIO2, read()).WillRepeatedly(Return(1));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000257 EXPECT_EQ(psu2.isPresent(), false);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600258
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600259 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +0000260 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +0000261 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
262 // for INPUT_HISTORY will check max_power_out to see if it is
263 // old/unsupported power supply. Indicate good value, supported.
264 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
265 .Times(1)
266 .WillOnce(Return("2000"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600267
Brandon Wymanb654c612021-11-05 23:24:51 +0000268 // STATUS_WORD INPUT fault.
269 {
270 // Start with STATUS_WORD 0x0000. Powered on, no faults.
271 // Set expectations for a no fault
272 PMBusExpectations expectations;
273 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000274 // After reading STATUS_WORD, etc., there will be a READ_VIN check.
275 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
276 .Times(1)
277 .WillOnce(Return("206000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000278 psu2.analyze();
279 EXPECT_EQ(psu2.isPresent(), true);
280 EXPECT_EQ(psu2.isFaulted(), false);
281 EXPECT_EQ(psu2.hasInputFault(), false);
282 EXPECT_EQ(psu2.hasMFRFault(), false);
283 EXPECT_EQ(psu2.hasVINUVFault(), false);
284 EXPECT_EQ(psu2.hasCommFault(), false);
285 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000286 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000287 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000288 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000289 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000290 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000291 EXPECT_EQ(psu2.hasPSKillFault(), false);
292 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
293 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000294
295 // Update expectations for STATUS_WORD input fault/warn
Brandon Wyman96893a42021-11-05 19:56:57 +0000296 // STATUS_INPUT fault bits ... on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000297 expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
Brandon Wyman3225a452022-03-18 18:51:49 +0000298 // IIN_OC fault.
299 expectations.statusInputValue = 0x04;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000300
301 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
302 {
303 setPMBusExpectations(mockPMBus, expectations);
304 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
305 .Times(1)
306 .WillOnce(Return("207000"));
307 psu2.analyze();
308 EXPECT_EQ(psu2.isPresent(), true);
309 // Should not be faulted until it reaches the deglitch limit.
310 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
311 EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT);
312 EXPECT_EQ(psu2.hasMFRFault(), false);
313 EXPECT_EQ(psu2.hasVINUVFault(), false);
314 EXPECT_EQ(psu2.hasCommFault(), false);
315 EXPECT_EQ(psu2.hasVoutOVFault(), false);
316 EXPECT_EQ(psu2.hasIoutOCFault(), false);
317 EXPECT_EQ(psu2.hasVoutUVFault(), false);
318 EXPECT_EQ(psu2.hasFanFault(), false);
319 EXPECT_EQ(psu2.hasTempFault(), false);
320 EXPECT_EQ(psu2.hasPgoodFault(), false);
321 EXPECT_EQ(psu2.hasPSKillFault(), false);
322 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
323 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
324 }
Brandon Wymanb654c612021-11-05 23:24:51 +0000325 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600326
Brandon Wyman32453e92021-12-15 19:00:14 +0000327 EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
Brandon Wyman3225a452022-03-18 18:51:49 +0000328 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
329 .Times(1)
330 .WillOnce(Return(1));
Brandon Wymanc2906f42021-12-21 20:14:56 +0000331 psu2.clearFaults();
332
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600333 // STATUS_WORD INPUT/UV fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000334 {
335 // First need it to return good status, then the fault
336 PMBusExpectations expectations;
337 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000338 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
339 .Times(1)
340 .WillOnce(Return("208000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000341 psu2.analyze();
Brandon Wymanc2906f42021-12-21 20:14:56 +0000342 EXPECT_EQ(psu2.isFaulted(), false);
343 EXPECT_EQ(psu2.hasInputFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000344 // Now set fault bits in STATUS_WORD
345 expectations.statusWordValue =
346 (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT);
347 // STATUS_INPUT fault bits ... on.
Brandon Wyman3225a452022-03-18 18:51:49 +0000348 expectations.statusInputValue = 0x18;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000349 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
350 {
351 setPMBusExpectations(mockPMBus, expectations);
352 // Input/UV fault, so voltage should read back low.
353 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
354 .Times(1)
355 .WillOnce(Return("19123"));
356 psu2.analyze();
357 EXPECT_EQ(psu2.isPresent(), true);
358 // Only faulted if hit deglitch limit
359 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
360 EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT);
361 EXPECT_EQ(psu2.hasVINUVFault(), x >= DEGLITCH_LIMIT);
362 EXPECT_EQ(psu2.hasMFRFault(), false);
363 EXPECT_EQ(psu2.hasCommFault(), false);
364 EXPECT_EQ(psu2.hasVoutOVFault(), false);
365 EXPECT_EQ(psu2.hasIoutOCFault(), false);
366 EXPECT_EQ(psu2.hasVoutUVFault(), false);
367 EXPECT_EQ(psu2.hasFanFault(), false);
368 EXPECT_EQ(psu2.hasTempFault(), false);
369 EXPECT_EQ(psu2.hasPgoodFault(), false);
370 EXPECT_EQ(psu2.hasPSKillFault(), false);
371 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
372 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
373 }
Brandon Wyman82affd92021-11-24 19:12:49 +0000374 // Turning VIN_UV fault off causes clearing of faults, causing read of
375 // in1_input as an attempt to get CLEAR_FAULTS called.
376 expectations.statusWordValue = 0;
377 setPMBusExpectations(mockPMBus, expectations);
378 // The call to read the voltage
379 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
380 .Times(1)
381 .WillOnce(Return("209000"));
Brandon Wyman3225a452022-03-18 18:51:49 +0000382 // The call to clear VIN_UV/Off fault(s)
383 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
Brandon Wyman32453e92021-12-15 19:00:14 +0000384 .Times(1)
Brandon Wyman3225a452022-03-18 18:51:49 +0000385 .WillOnce(Return(1));
Brandon Wyman82affd92021-11-24 19:12:49 +0000386 psu2.analyze();
387 // Should remain present, no longer be faulted, no input fault, no
388 // VIN_UV fault. Nothing else should change.
389 EXPECT_EQ(psu2.isPresent(), true);
390 EXPECT_EQ(psu2.isFaulted(), false);
391 EXPECT_EQ(psu2.hasInputFault(), false);
392 EXPECT_EQ(psu2.hasVINUVFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000393 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600394
Brandon Wyman32453e92021-12-15 19:00:14 +0000395 EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
Brandon Wyman3225a452022-03-18 18:51:49 +0000396 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
397 .Times(1)
398 .WillOnce(Return(1));
Brandon Wymanc2906f42021-12-21 20:14:56 +0000399 psu2.clearFaults();
400
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600401 // STATUS_WORD MFR fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000402 {
403 // First need it to return good status, then the fault
404 PMBusExpectations expectations;
405 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000406 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
407 .Times(1)
408 .WillOnce(Return("210000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000409 psu2.analyze();
410 // Now STATUS_WORD with MFR fault bit on.
411 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
412 // STATUS_MFR bits on.
413 expectations.statusMFRValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000414
415 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
416 {
417 setPMBusExpectations(mockPMBus, expectations);
418 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
419 .Times(1)
420 .WillOnce(Return("211000"));
421 psu2.analyze();
422 EXPECT_EQ(psu2.isPresent(), true);
423 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
424 EXPECT_EQ(psu2.hasInputFault(), false);
425 EXPECT_EQ(psu2.hasMFRFault(), x >= DEGLITCH_LIMIT);
426 EXPECT_EQ(psu2.hasPSKillFault(), x >= DEGLITCH_LIMIT);
427 EXPECT_EQ(psu2.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
428 EXPECT_EQ(psu2.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
429 EXPECT_EQ(psu2.hasVINUVFault(), false);
430 EXPECT_EQ(psu2.hasCommFault(), false);
431 EXPECT_EQ(psu2.hasVoutOVFault(), false);
432 EXPECT_EQ(psu2.hasIoutOCFault(), false);
433 EXPECT_EQ(psu2.hasVoutUVFault(), false);
434 EXPECT_EQ(psu2.hasFanFault(), false);
435 EXPECT_EQ(psu2.hasTempFault(), false);
436 EXPECT_EQ(psu2.hasPgoodFault(), false);
437 }
Brandon Wymanb654c612021-11-05 23:24:51 +0000438 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600439
Brandon Wyman32453e92021-12-15 19:00:14 +0000440 EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
Brandon Wyman3225a452022-03-18 18:51:49 +0000441 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
442 .Times(1)
443 .WillOnce(Return(1));
Brandon Wymanc2906f42021-12-21 20:14:56 +0000444 psu2.clearFaults();
Brandon Wyman3225a452022-03-18 18:51:49 +0000445
Brandon Wyman96893a42021-11-05 19:56:57 +0000446 // Temperature fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000447 {
448 // First STATUS_WORD with no bits set, then with temperature fault.
449 PMBusExpectations expectations;
450 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000451 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
452 .Times(1)
453 .WillOnce(Return("212000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000454 psu2.analyze();
455 // STATUS_WORD with temperature fault bit on.
456 expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
Brandon Wyman96893a42021-11-05 19:56:57 +0000457 // STATUS_TEMPERATURE with fault bit(s) on.
458 expectations.statusTempValue = 0x10;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000459 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
460 {
461 setPMBusExpectations(mockPMBus, expectations);
462 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
463 .Times(1)
464 .WillOnce(Return("213000"));
465 psu2.analyze();
466 EXPECT_EQ(psu2.isPresent(), true);
467 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
468 EXPECT_EQ(psu2.hasInputFault(), false);
469 EXPECT_EQ(psu2.hasMFRFault(), false);
470 EXPECT_EQ(psu2.hasVINUVFault(), false);
471 EXPECT_EQ(psu2.hasCommFault(), false);
472 EXPECT_EQ(psu2.hasVoutOVFault(), false);
473 EXPECT_EQ(psu2.hasIoutOCFault(), false);
474 EXPECT_EQ(psu2.hasVoutUVFault(), false);
475 EXPECT_EQ(psu2.hasFanFault(), false);
476 EXPECT_EQ(psu2.hasTempFault(), x >= DEGLITCH_LIMIT);
477 EXPECT_EQ(psu2.hasPgoodFault(), false);
478 EXPECT_EQ(psu2.hasPSKillFault(), false);
479 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
480 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
481 }
Brandon Wymanb654c612021-11-05 23:24:51 +0000482 }
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000483
Brandon Wyman32453e92021-12-15 19:00:14 +0000484 EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
Brandon Wyman3225a452022-03-18 18:51:49 +0000485 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
486 .Times(1)
487 .WillOnce(Return(1));
Brandon Wymanc2906f42021-12-21 20:14:56 +0000488 psu2.clearFaults();
Brandon Wyman3225a452022-03-18 18:51:49 +0000489
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000490 // CML fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000491 {
492 // First STATUS_WORD wit no bits set, then with CML fault.
493 PMBusExpectations expectations;
494 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000495 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
496 .Times(1)
497 .WillOnce(Return("214000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000498 psu2.analyze();
499 // STATUS_WORD with CML fault bit on.
500 expectations.statusWordValue = (status_word::CML_FAULT);
501 // Turn on STATUS_CML fault bit(s)
502 expectations.statusCMLValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000503 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
504 {
505 setPMBusExpectations(mockPMBus, expectations);
506 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
507 .Times(1)
508 .WillOnce(Return("215000"));
509 psu2.analyze();
510 EXPECT_EQ(psu2.isPresent(), true);
511 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
512 EXPECT_EQ(psu2.hasCommFault(), x >= DEGLITCH_LIMIT);
513 EXPECT_EQ(psu2.hasInputFault(), false);
514 EXPECT_EQ(psu2.hasMFRFault(), false);
515 EXPECT_EQ(psu2.hasVINUVFault(), false);
516 EXPECT_EQ(psu2.hasVoutOVFault(), false);
517 EXPECT_EQ(psu2.hasIoutOCFault(), false);
518 EXPECT_EQ(psu2.hasVoutUVFault(), false);
519 EXPECT_EQ(psu2.hasFanFault(), false);
520 EXPECT_EQ(psu2.hasTempFault(), false);
521 EXPECT_EQ(psu2.hasPgoodFault(), false);
522 EXPECT_EQ(psu2.hasPSKillFault(), false);
523 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
524 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
525 }
Brandon Wymanb654c612021-11-05 23:24:51 +0000526 }
Brandon Wyman6710ba22021-10-27 17:39:31 +0000527
Brandon Wyman32453e92021-12-15 19:00:14 +0000528 EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
Brandon Wyman3225a452022-03-18 18:51:49 +0000529 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
530 .Times(1)
531 .WillOnce(Return(1));
Brandon Wymanc2906f42021-12-21 20:14:56 +0000532 psu2.clearFaults();
Brandon Wyman3225a452022-03-18 18:51:49 +0000533
Brandon Wyman6710ba22021-10-27 17:39:31 +0000534 // VOUT_OV_FAULT fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000535 {
536 // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault.
537 PMBusExpectations expectations;
538 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000539 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
540 .Times(1)
541 .WillOnce(Return("216000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000542 psu2.analyze();
543 // STATUS_WORD with VOUT/VOUT_OV fault.
544 expectations.statusWordValue =
545 ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT));
546 // Turn on STATUS_VOUT fault bit(s)
547 expectations.statusVOUTValue = 0xA0;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000548 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
549 {
550 // STATUS_TEMPERATURE don't care (default)
551 setPMBusExpectations(mockPMBus, expectations);
552 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
553 .Times(1)
554 .WillOnce(Return("217000"));
555 psu2.analyze();
556 EXPECT_EQ(psu2.isPresent(), true);
557 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
558 EXPECT_EQ(psu2.hasInputFault(), false);
559 EXPECT_EQ(psu2.hasMFRFault(), false);
560 EXPECT_EQ(psu2.hasVINUVFault(), false);
561 EXPECT_EQ(psu2.hasCommFault(), false);
562 EXPECT_EQ(psu2.hasVoutOVFault(), x >= DEGLITCH_LIMIT);
563 EXPECT_EQ(psu2.hasVoutUVFault(), false);
564 EXPECT_EQ(psu2.hasIoutOCFault(), false);
565 EXPECT_EQ(psu2.hasFanFault(), false);
566 EXPECT_EQ(psu2.hasTempFault(), false);
567 EXPECT_EQ(psu2.hasPgoodFault(), false);
568 EXPECT_EQ(psu2.hasPSKillFault(), false);
569 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
570 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
571 }
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000572 }
573
574 // IOUT_OC_FAULT fault
575 {
576 // First STATUS_WORD with no bits set, then with IOUT_OC fault.
577 PMBusExpectations expectations;
578 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000579 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
580 .Times(1)
581 .WillOnce(Return("218000"));
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000582 psu2.analyze();
583 // STATUS_WORD with IOUT_OC fault.
584 expectations.statusWordValue = status_word::IOUT_OC_FAULT;
585 // Turn on STATUS_IOUT fault bit(s)
586 expectations.statusIOUTValue = 0x88;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000587 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
588 {
589 setPMBusExpectations(mockPMBus, expectations);
590 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
591 .Times(1)
592 .WillOnce(Return("219000"));
593 psu2.analyze();
594 EXPECT_EQ(psu2.isPresent(), true);
595 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
596 EXPECT_EQ(psu2.hasInputFault(), false);
597 EXPECT_EQ(psu2.hasMFRFault(), false);
598 EXPECT_EQ(psu2.hasVINUVFault(), false);
599 EXPECT_EQ(psu2.hasCommFault(), false);
600 EXPECT_EQ(psu2.hasVoutOVFault(), false);
601 EXPECT_EQ(psu2.hasIoutOCFault(), x >= DEGLITCH_LIMIT);
602 EXPECT_EQ(psu2.hasVoutUVFault(), false);
603 EXPECT_EQ(psu2.hasFanFault(), false);
604 EXPECT_EQ(psu2.hasTempFault(), false);
605 EXPECT_EQ(psu2.hasPgoodFault(), false);
606 EXPECT_EQ(psu2.hasPSKillFault(), false);
607 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
608 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
609 }
Brandon Wyman2cf46942021-10-28 19:09:16 +0000610 }
611
612 // VOUT_UV_FAULT
613 {
614 // First STATUS_WORD with no bits set, then with VOUT fault.
615 PMBusExpectations expectations;
616 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000617 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
618 .Times(1)
619 .WillOnce(Return("220000"));
Brandon Wyman2cf46942021-10-28 19:09:16 +0000620 psu2.analyze();
621 // Change STATUS_WORD to indicate VOUT fault.
622 expectations.statusWordValue = (status_word::VOUT_FAULT);
623 // Turn on STATUS_VOUT fault bit(s)
624 expectations.statusVOUTValue = 0x30;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000625 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
626 {
627 setPMBusExpectations(mockPMBus, expectations);
628 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
629 .Times(1)
630 .WillOnce(Return("221000"));
631 psu2.analyze();
632 EXPECT_EQ(psu2.isPresent(), true);
633 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
634 EXPECT_EQ(psu2.hasInputFault(), false);
635 EXPECT_EQ(psu2.hasMFRFault(), false);
636 EXPECT_EQ(psu2.hasVINUVFault(), false);
637 EXPECT_EQ(psu2.hasCommFault(), false);
638 EXPECT_EQ(psu2.hasVoutOVFault(), false);
639 EXPECT_EQ(psu2.hasIoutOCFault(), false);
640 EXPECT_EQ(psu2.hasVoutUVFault(), x >= DEGLITCH_LIMIT);
641 EXPECT_EQ(psu2.hasFanFault(), false);
642 EXPECT_EQ(psu2.hasTempFault(), false);
643 EXPECT_EQ(psu2.hasPgoodFault(), false);
644 EXPECT_EQ(psu2.hasPSKillFault(), false);
645 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
646 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
647 }
Brandon Wymanb654c612021-11-05 23:24:51 +0000648 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600649
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000650 // Fan fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000651 {
652 // First STATUS_WORD with no bits set, then with fan fault.
653 PMBusExpectations expectations;
654 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000655 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
656 .Times(1)
657 .WillOnce(Return("222000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000658 psu2.analyze();
659 expectations.statusWordValue = (status_word::FAN_FAULT);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000660 // STATUS_FANS_1_2 with fan 1 warning & fault bits on.
661 expectations.statusFans12Value = 0xA0;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000662
663 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
664 {
665 setPMBusExpectations(mockPMBus, expectations);
666 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
667 .Times(1)
668 .WillOnce(Return("223000"));
669 psu2.analyze();
670 EXPECT_EQ(psu2.isPresent(), true);
671 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
672 EXPECT_EQ(psu2.hasFanFault(), x >= DEGLITCH_LIMIT);
673 EXPECT_EQ(psu2.hasInputFault(), false);
674 EXPECT_EQ(psu2.hasMFRFault(), false);
675 EXPECT_EQ(psu2.hasVINUVFault(), false);
676 EXPECT_EQ(psu2.hasCommFault(), false);
677 EXPECT_EQ(psu2.hasVoutOVFault(), false);
678 EXPECT_EQ(psu2.hasIoutOCFault(), false);
679 EXPECT_EQ(psu2.hasVoutUVFault(), false);
680 EXPECT_EQ(psu2.hasTempFault(), false);
681 EXPECT_EQ(psu2.hasPgoodFault(), false);
682 EXPECT_EQ(psu2.hasPSKillFault(), false);
683 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
684 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
685 }
Brandon Wymanb654c612021-11-05 23:24:51 +0000686 }
Brandon Wyman2916ea52021-11-06 03:31:18 +0000687
Brandon Wyman06ca4592021-12-06 22:52:23 +0000688 // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT.
Brandon Wyman2916ea52021-11-06 03:31:18 +0000689 {
Brandon Wyman2916ea52021-11-06 03:31:18 +0000690 // First STATUS_WORD with no bits set.
691 PMBusExpectations expectations;
692 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000693 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
694 .Times(1)
695 .WillOnce(Return("123000"));
Brandon Wyman2916ea52021-11-06 03:31:18 +0000696 psu2.analyze();
697 EXPECT_EQ(psu2.isFaulted(), false);
698 // POWER_GOOD# inactive, and OFF bit on.
699 expectations.statusWordValue =
700 ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF));
Brandon Wyman6d469fd2022-06-15 16:58:21 +0000701 for (auto x = 1; x <= PGOOD_DEGLITCH_LIMIT; x++)
Brandon Wyman06ca4592021-12-06 22:52:23 +0000702 {
703 // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and
704 // STATUS_TEMPERATURE: Don't care if bits set or not (defaults).
705 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000706 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
707 .Times(1)
708 .WillOnce(Return("124000"));
Brandon Wyman06ca4592021-12-06 22:52:23 +0000709 psu2.analyze();
710 EXPECT_EQ(psu2.isPresent(), true);
Brandon Wyman6d469fd2022-06-15 16:58:21 +0000711 EXPECT_EQ(psu2.isFaulted(), x >= PGOOD_DEGLITCH_LIMIT);
Brandon Wyman06ca4592021-12-06 22:52:23 +0000712 EXPECT_EQ(psu2.hasInputFault(), false);
713 EXPECT_EQ(psu2.hasMFRFault(), false);
714 EXPECT_EQ(psu2.hasVINUVFault(), false);
715 EXPECT_EQ(psu2.hasCommFault(), false);
716 EXPECT_EQ(psu2.hasVoutOVFault(), false);
717 EXPECT_EQ(psu2.hasVoutUVFault(), false);
718 EXPECT_EQ(psu2.hasIoutOCFault(), false);
719 EXPECT_EQ(psu2.hasFanFault(), false);
720 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman6d469fd2022-06-15 16:58:21 +0000721 EXPECT_EQ(psu2.hasPgoodFault(), x >= PGOOD_DEGLITCH_LIMIT);
Brandon Wyman06ca4592021-12-06 22:52:23 +0000722 }
Brandon Wyman2916ea52021-11-06 03:31:18 +0000723 }
724
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600725 // TODO: ReadFailure
726}
727
Brandon Wyman59a35792020-06-04 12:37:40 -0500728TEST_F(PowerSupplyTests, OnOffConfig)
729{
730 auto bus = sdbusplus::bus::new_default();
731 uint8_t data = 0x15;
732
733 // Test where PSU is NOT present
734 try
735 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000736 // Assume GPIO presence, not inventory presence?
Matt Spinler0975eaf2022-02-14 15:38:30 -0600737 EXPECT_CALL(mockedUtil, setAvailable(_, _, _)).Times(0);
George Liu9464c422023-02-27 14:30:27 +0800738 PowerSupply psu{bus, PSUInventoryPath, 4, 0x69,
739 "ibm-cffps", PSUGPIOLineName, isPowerOn};
B. J. Wyman681b2a32021-04-20 22:31:22 +0000740
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000741 MockedGPIOInterface* mockPresenceGPIO =
742 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000743 ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0));
Brandon Wyman59a35792020-06-04 12:37:40 -0500744 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000745 // Constructor should set initial presence, default read returns 0.
Brandon Wyman59a35792020-06-04 12:37:40 -0500746 // If it is not present, I should not be trying to write to it.
747 EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0);
748 psu.onOffConfig(data);
749 }
750 catch (...)
Adriana Kobylak0c9a33d2021-09-13 18:05:09 +0000751 {}
Brandon Wyman59a35792020-06-04 12:37:40 -0500752
753 // Test where PSU is present
754 try
755 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000756 // Assume GPIO presence, not inventory presence?
Matt Spinler0975eaf2022-02-14 15:38:30 -0600757 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
George Liu9464c422023-02-27 14:30:27 +0800758 PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a,
759 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000760 MockedGPIOInterface* mockPresenceGPIO =
761 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wyman391a0692021-12-08 23:28:18 +0000762 // There will potentially be multiple calls, we want it to continue
763 // returning 1 for the GPIO read to keep the power supply present.
764 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman59a35792020-06-04 12:37:40 -0500765 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +0000766 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +0000767 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
768 // for INPUT_HISTORY will check max_power_out to see if it is
769 // old/unsupported power supply. Indicate good value, supported.
770 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
771 .Times(1)
772 .WillOnce(Return("2000"));
Brandon Wyman391a0692021-12-08 23:28:18 +0000773 // If I am calling analyze(), I should probably give it good data.
774 // STATUS_WORD 0x0000 is powered on, no faults.
775 PMBusExpectations expectations;
776 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000777 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
778 .Times(1)
779 .WillOnce(Return("205000"));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000780 psu.analyze();
Brandon Wyman391a0692021-12-08 23:28:18 +0000781 // I definitely should be writting ON_OFF_CONFIG if I call the function
782 EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, ElementsAre(0x15),
783 Type::HwmonDeviceDebug))
Brandon Wyman59a35792020-06-04 12:37:40 -0500784 .Times(1);
785 psu.onOffConfig(data);
786 }
787 catch (...)
Adriana Kobylak0c9a33d2021-09-13 18:05:09 +0000788 {}
Brandon Wyman59a35792020-06-04 12:37:40 -0500789}
790
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600791TEST_F(PowerSupplyTests, ClearFaults)
792{
793 auto bus = sdbusplus::bus::new_default();
George Liu9464c422023-02-27 14:30:27 +0800794 PowerSupply psu{bus, PSUInventoryPath, 13, 0x68,
795 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000796 MockedGPIOInterface* mockPresenceGPIO =
797 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wyman06ca4592021-12-06 22:52:23 +0000798 // Always return 1 to indicate present.
799 // Each analyze() call will trigger a read of the presence GPIO.
800 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000801 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +0000802 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +0000803 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
804 // for INPUT_HISTORY will check max_power_out to see if it is
805 // old/unsupported power supply. Indicate good value, supported.
806 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
807 .Times(1)
808 .WillOnce(Return("2000"));
Brandon Wyman8da35c52021-10-28 22:45:08 +0000809 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000810 PMBusExpectations expectations;
811 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000812 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
813 .Times(1)
814 .WillOnce(Return("207000"));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000815 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600816 EXPECT_EQ(psu.isPresent(), true);
817 EXPECT_EQ(psu.isFaulted(), false);
818 EXPECT_EQ(psu.hasInputFault(), false);
819 EXPECT_EQ(psu.hasMFRFault(), false);
820 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000821 EXPECT_EQ(psu.hasCommFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000822 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000823 EXPECT_EQ(psu.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000824 EXPECT_EQ(psu.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000825 EXPECT_EQ(psu.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000826 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000827 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000828 EXPECT_EQ(psu.hasPSKillFault(), false);
829 EXPECT_EQ(psu.hasPS12VcsFault(), false);
830 EXPECT_EQ(psu.hasPSCS12VFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000831
Brandon Wymanf07bc792021-10-12 19:00:35 +0000832 // STATUS_WORD with fault bits galore!
Brandon Wymanb654c612021-11-05 23:24:51 +0000833 expectations.statusWordValue = 0xFFFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000834 // STATUS_INPUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000835 expectations.statusInputValue = 0xFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000836 // STATUS_MFR_SPEFIC with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000837 expectations.statusMFRValue = 0xFF;
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000838 // STATUS_CML with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000839 expectations.statusCMLValue = 0xFF;
Brandon Wyman6710ba22021-10-27 17:39:31 +0000840 // STATUS_VOUT with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000841 expectations.statusVOUTValue = 0xFF;
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000842 // STATUS_IOUT with bits on.
843 expectations.statusIOUTValue = 0xFF;
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000844 // STATUS_FANS_1_2 with bits on.
845 expectations.statusFans12Value = 0xFF;
Brandon Wyman96893a42021-11-05 19:56:57 +0000846 // STATUS_TEMPERATURE with bits on.
847 expectations.statusTempValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000848
Brandon Wyman6d469fd2022-06-15 16:58:21 +0000849 for (auto x = 1; x <= PGOOD_DEGLITCH_LIMIT; x++)
Brandon Wymanc2906f42021-12-21 20:14:56 +0000850 {
851 setPMBusExpectations(mockPMBus, expectations);
852 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
853 .Times(1)
854 .WillOnce(Return("0"));
Matt Spinler0975eaf2022-02-14 15:38:30 -0600855 if (x == DEGLITCH_LIMIT)
856 {
857 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
858 }
Brandon Wymanc2906f42021-12-21 20:14:56 +0000859 psu.analyze();
860 EXPECT_EQ(psu.isPresent(), true);
861 // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
862 // Rely on HasVoutUVFault() to verify this sets and clears.
863 EXPECT_EQ(psu.hasVoutUVFault(), false);
Brandon Wyman6d469fd2022-06-15 16:58:21 +0000864 // pgoodFault at PGOOD_DEGLITCH_LIMIT, all other faults are deglitched
865 // up to DEGLITCH_LIMIT
Brandon Wymanc2906f42021-12-21 20:14:56 +0000866 EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT);
867 EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT);
868 EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT);
869 EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT);
870 EXPECT_EQ(psu.hasCommFault(), x >= DEGLITCH_LIMIT);
871 EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT);
872 EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT);
873 EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT);
874 EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT);
Brandon Wyman6d469fd2022-06-15 16:58:21 +0000875 EXPECT_EQ(psu.hasPgoodFault(), x >= PGOOD_DEGLITCH_LIMIT);
Brandon Wymanc2906f42021-12-21 20:14:56 +0000876 EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT);
877 EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
878 EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
879 }
880
Brandon Wyman32453e92021-12-15 19:00:14 +0000881 EXPECT_CALL(mockPMBus, read(READ_VIN, _, _))
882 .Times(1)
883 .WillOnce(Return(207000));
Brandon Wyman3225a452022-03-18 18:51:49 +0000884 // Clearing VIN_UV fault via in1_lcrit_alarm
885 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
886 .Times(1)
887 .WillOnce(Return(1));
Matt Spinler0975eaf2022-02-14 15:38:30 -0600888 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600889 psu.clearFaults();
890 EXPECT_EQ(psu.isPresent(), true);
891 EXPECT_EQ(psu.isFaulted(), false);
892 EXPECT_EQ(psu.hasInputFault(), false);
893 EXPECT_EQ(psu.hasMFRFault(), false);
894 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000895 EXPECT_EQ(psu.hasCommFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000896 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000897 EXPECT_EQ(psu.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000898 EXPECT_EQ(psu.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000899 EXPECT_EQ(psu.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000900 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000901 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000902 EXPECT_EQ(psu.hasPSKillFault(), false);
903 EXPECT_EQ(psu.hasPS12VcsFault(), false);
904 EXPECT_EQ(psu.hasPSCS12VFault(), false);
B. J. Wyman681b2a32021-04-20 22:31:22 +0000905
Brandon Wyman82affd92021-11-24 19:12:49 +0000906 // Faults clear on READ_VIN 0 -> !0
907 // STATUS_WORD with fault bits galore!
908 expectations.statusWordValue = 0xFFFF;
909 // STATUS_INPUT with fault bits on.
910 expectations.statusInputValue = 0xFF;
911 // STATUS_MFR_SPEFIC with bits on.
912 expectations.statusMFRValue = 0xFF;
913 // STATUS_CML with bits on.
914 expectations.statusCMLValue = 0xFF;
915 // STATUS_VOUT with bits on.
916 expectations.statusVOUTValue = 0xFF;
917 // STATUS_IOUT with bits on.
918 expectations.statusIOUTValue = 0xFF;
919 // STATUS_FANS_1_2 with bits on.
920 expectations.statusFans12Value = 0xFF;
921 // STATUS_TEMPERATURE with bits on.
922 expectations.statusTempValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000923
Brandon Wyman6d469fd2022-06-15 16:58:21 +0000924 // All faults deglitched now. Check for false before limit above.
Brandon Wymanc2906f42021-12-21 20:14:56 +0000925 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
926 {
927 setPMBusExpectations(mockPMBus, expectations);
928 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
929 .Times(1)
930 .WillOnce(Return("0"));
Matt Spinler0975eaf2022-02-14 15:38:30 -0600931 if (x == DEGLITCH_LIMIT)
932 {
933 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
934 }
Brandon Wymanc2906f42021-12-21 20:14:56 +0000935 psu.analyze();
936 }
937
Brandon Wyman82affd92021-11-24 19:12:49 +0000938 EXPECT_EQ(psu.isPresent(), true);
939 EXPECT_EQ(psu.isFaulted(), true);
940 EXPECT_EQ(psu.hasInputFault(), true);
941 EXPECT_EQ(psu.hasMFRFault(), true);
942 EXPECT_EQ(psu.hasVINUVFault(), true);
943 // True due to CML fault bits on
944 EXPECT_EQ(psu.hasCommFault(), true);
945 EXPECT_EQ(psu.hasVoutOVFault(), true);
946 EXPECT_EQ(psu.hasIoutOCFault(), true);
947 // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
948 // Rely on HasVoutUVFault() to verify this sets and clears.
949 EXPECT_EQ(psu.hasVoutUVFault(), false);
950 EXPECT_EQ(psu.hasFanFault(), true);
951 EXPECT_EQ(psu.hasTempFault(), true);
Brandon Wyman6d469fd2022-06-15 16:58:21 +0000952 // No PGOOD fault, as less than PGOOD_DEGLITCH_LIMIT
953 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman82affd92021-11-24 19:12:49 +0000954 EXPECT_EQ(psu.hasPSKillFault(), true);
955 EXPECT_EQ(psu.hasPS12VcsFault(), true);
956 EXPECT_EQ(psu.hasPSCS12VFault(), true);
957 // STATUS_WORD with INPUT/VIN_UV fault bits off.
958 expectations.statusWordValue = 0xDFF7;
959 // STATUS_INPUT with VIN_UV_WARNING, VIN_UV_FAULT, and Unit Off For
960 // Insufficient Input Voltage bits off.
961 expectations.statusInputValue = 0xC7;
962 setPMBusExpectations(mockPMBus, expectations);
963 // READ_VIN back in range.
964 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
965 .Times(1)
966 .WillOnce(Return("206000"));
Brandon Wyman3225a452022-03-18 18:51:49 +0000967 // VIN_UV cleared via in1_lcrit_alarm when voltage back in range.
968 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
969 .Times(1)
970 .WillOnce(Return(1));
971 psu.analyze();
972 // We only cleared the VIN_UV and OFF faults.
973 EXPECT_EQ(psu.isPresent(), true);
974 EXPECT_EQ(psu.isFaulted(), true);
975 EXPECT_EQ(psu.hasInputFault(), false);
976 EXPECT_EQ(psu.hasMFRFault(), true);
977 EXPECT_EQ(psu.hasVINUVFault(), false);
978 EXPECT_EQ(psu.hasCommFault(), true);
979 EXPECT_EQ(psu.hasVoutOVFault(), true);
980 EXPECT_EQ(psu.hasIoutOCFault(), true);
981 EXPECT_EQ(psu.hasVoutUVFault(), false);
982 EXPECT_EQ(psu.hasFanFault(), true);
983 EXPECT_EQ(psu.hasTempFault(), true);
Brandon Wyman6d469fd2022-06-15 16:58:21 +0000984 // No PGOOD fault, as less than PGOOD_DEGLITCH_LIMIT
985 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman3225a452022-03-18 18:51:49 +0000986 EXPECT_EQ(psu.hasPSKillFault(), true);
987 EXPECT_EQ(psu.hasPS12VcsFault(), true);
988 EXPECT_EQ(psu.hasPSCS12VFault(), true);
989
990 // All faults cleared
991 expectations = {0};
992 setPMBusExpectations(mockPMBus, expectations);
993 // READ_VIN back in range.
994 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
995 .Times(1)
996 .WillOnce(Return("206000"));
Matt Spinler0975eaf2022-02-14 15:38:30 -0600997 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
Brandon Wyman82affd92021-11-24 19:12:49 +0000998 psu.analyze();
999 EXPECT_EQ(psu.isPresent(), true);
1000 EXPECT_EQ(psu.isFaulted(), false);
1001 EXPECT_EQ(psu.hasInputFault(), false);
1002 EXPECT_EQ(psu.hasMFRFault(), false);
1003 EXPECT_EQ(psu.hasVINUVFault(), false);
1004 EXPECT_EQ(psu.hasCommFault(), false);
1005 EXPECT_EQ(psu.hasVoutOVFault(), false);
1006 EXPECT_EQ(psu.hasIoutOCFault(), false);
1007 EXPECT_EQ(psu.hasVoutUVFault(), false);
1008 EXPECT_EQ(psu.hasFanFault(), false);
1009 EXPECT_EQ(psu.hasTempFault(), false);
1010 EXPECT_EQ(psu.hasPgoodFault(), false);
1011 EXPECT_EQ(psu.hasPSKillFault(), false);
1012 EXPECT_EQ(psu.hasPS12VcsFault(), false);
1013 EXPECT_EQ(psu.hasPSCS12VFault(), false);
1014
B. J. Wyman681b2a32021-04-20 22:31:22 +00001015 // TODO: Faults clear on missing/present?
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001016}
1017
1018TEST_F(PowerSupplyTests, UpdateInventory)
1019{
1020 auto bus = sdbusplus::bus::new_default();
Brandon Wyman1d7a7df2020-03-26 10:14:05 -05001021
1022 try
1023 {
George Liu9464c422023-02-27 14:30:27 +08001024 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68,
1025 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Brandon Wyman1d7a7df2020-03-26 10:14:05 -05001026 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1027 // If it is not present, I should not be trying to read a string
1028 EXPECT_CALL(mockPMBus, readString(_, _)).Times(0);
1029 psu.updateInventory();
1030 }
1031 catch (...)
1032 {
1033 ADD_FAILURE() << "Should not have caught exception.";
1034 }
1035
1036 try
1037 {
George Liu9464c422023-02-27 14:30:27 +08001038 PowerSupply psu{bus, PSUInventoryPath, 13, 0x69,
1039 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +00001040 MockedGPIOInterface* mockPresenceGPIO =
1041 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +00001042 // GPIO read return 1 to indicate present.
1043 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
Brandon Wyman1d7a7df2020-03-26 10:14:05 -05001044 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001045 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001046 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1047 // for INPUT_HISTORY will check max_power_out to see if it is
1048 // old/unsupported power supply. Indicate good value, supported.
1049 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1050 .Times(1)
1051 .WillOnce(Return("2000"));
Brandon Wyman391a0692021-12-08 23:28:18 +00001052 // STATUS_WORD 0x0000 is powered on, no faults.
1053 PMBusExpectations expectations;
1054 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001055 // Call to analyze will read voltage, trigger clear faults for 0 to
1056 // within range.
1057 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1058 .Times(1)
1059 .WillOnce(Return("123456"));
Brandon Wyman391a0692021-12-08 23:28:18 +00001060 psu.analyze();
Brandon Wyman1d7a7df2020-03-26 10:14:05 -05001061 EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return(""));
1062 psu.updateInventory();
1063
Brandon Wyman3c530fb2021-04-13 13:13:22 -05001064#if IBM_VPD
Brandon Wyman1d7a7df2020-03-26 10:14:05 -05001065 EXPECT_CALL(mockPMBus, readString(_, _))
1066 .WillOnce(Return("CCIN"))
1067 .WillOnce(Return("PN3456"))
1068 .WillOnce(Return("FN3456"))
1069 .WillOnce(Return("HEADER"))
1070 .WillOnce(Return("SN3456"))
1071 .WillOnce(Return("FW3456"));
Brandon Wyman3c530fb2021-04-13 13:13:22 -05001072#endif
Brandon Wyman1d7a7df2020-03-26 10:14:05 -05001073 psu.updateInventory();
1074 // TODO: D-Bus mocking to verify values stored on D-Bus (???)
1075 }
1076 catch (...)
1077 {
1078 ADD_FAILURE() << "Should not have caught exception.";
1079 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001080}
1081
1082TEST_F(PowerSupplyTests, IsPresent)
1083{
1084 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +00001085
George Liu9464c422023-02-27 14:30:27 +08001086 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68,
1087 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +00001088 MockedGPIOInterface* mockPresenceGPIO =
1089 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001090 EXPECT_EQ(psu.isPresent(), false);
1091
B. J. Wyman681b2a32021-04-20 22:31:22 +00001092 // Change GPIO read to return 1 to indicate present.
1093 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
Brandon Wyman391a0692021-12-08 23:28:18 +00001094 // Call to analyze() will update to present, that will trigger updating
1095 // to the correct/latest HWMON directory, in case it changes.
1096 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1097 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001098 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1099 // for INPUT_HISTORY will check max_power_out to see if it is
1100 // old/unsupported power supply. Indicate good value, supported.
1101 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1102 .Times(1)
1103 .WillOnce(Return("2000"));
Brandon Wyman391a0692021-12-08 23:28:18 +00001104 // Call to analyze things will trigger read of STATUS_WORD and READ_VIN.
1105 // Default expectations will be on, no faults.
1106 PMBusExpectations expectations;
1107 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001108 // Give it an input voltage in the 100-volt range.
1109 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1110 .Times(1)
1111 .WillOnce(Return("123456"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001112 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
B. J. Wyman681b2a32021-04-20 22:31:22 +00001113 psu.analyze();
1114 EXPECT_EQ(psu.isPresent(), true);
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001115}
1116
1117TEST_F(PowerSupplyTests, IsFaulted)
1118{
1119 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +00001120
George Liu9464c422023-02-27 14:30:27 +08001121 PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f,
1122 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +00001123 MockedGPIOInterface* mockPresenceGPIO =
1124 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +00001125 // Always return 1 to indicate present.
1126 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman391a0692021-12-08 23:28:18 +00001127 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1128 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001129 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1130 // for INPUT_HISTORY will check max_power_out to see if it is
1131 // old/unsupported power supply. Indicate good value, supported.
1132 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1133 .Times(1)
1134 .WillOnce(Return("2000"));
Brandon Wyman391a0692021-12-08 23:28:18 +00001135 // Call to analyze things will trigger read of STATUS_WORD and READ_VIN.
1136 // Default expectations will be on, no faults.
1137 PMBusExpectations expectations;
1138 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001139 // Give it an input voltage in the 100-volt range.
1140 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1141 .Times(1)
1142 .WillOnce(Return("124680"));
B. J. Wyman681b2a32021-04-20 22:31:22 +00001143 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001144 EXPECT_EQ(psu.isFaulted(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001145 // STATUS_WORD with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001146 expectations.statusWordValue = 0xFFFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +00001147 // STATUS_INPUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001148 expectations.statusInputValue = 0xFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +00001149 // STATUS_MFR_SPECIFIC with faults bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001150 expectations.statusMFRValue = 0xFF;
Brandon Wyman85c7bf42021-10-19 22:28:48 +00001151 // STATUS_CML with faults bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001152 expectations.statusCMLValue = 0xFF;
Brandon Wyman6710ba22021-10-27 17:39:31 +00001153 // STATUS_VOUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001154 expectations.statusVOUTValue = 0xFF;
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001155 // STATUS_IOUT with fault bits on.
1156 expectations.statusIOUTValue = 0xFF;
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001157 // STATUS_FANS_1_2 with bits on.
1158 expectations.statusFans12Value = 0xFF;
Brandon Wyman96893a42021-11-05 19:56:57 +00001159 // STATUS_TEMPERATURE with fault bits on.
1160 expectations.statusTempValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001161 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1162 {
1163 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman4fc191f2022-03-10 23:07:13 +00001164 // Also get another read of READ_VIN, faulted, so not in 100-volt range
Brandon Wymanc2906f42021-12-21 20:14:56 +00001165 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1166 .Times(1)
Brandon Wyman4fc191f2022-03-10 23:07:13 +00001167 .WillOnce(Return("19000"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001168 if (x == DEGLITCH_LIMIT)
1169 {
1170 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1171 }
Brandon Wymanc2906f42021-12-21 20:14:56 +00001172 psu.analyze();
1173 EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT);
1174 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001175}
1176
1177TEST_F(PowerSupplyTests, HasInputFault)
1178{
1179 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +00001180
George Liu9464c422023-02-27 14:30:27 +08001181 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68,
1182 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +00001183 MockedGPIOInterface* mockPresenceGPIO =
1184 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +00001185 // Always return 1 to indicate present.
1186 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001187 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001188 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001189 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1190 // for INPUT_HISTORY will check max_power_out to see if it is
1191 // old/unsupported power supply. Indicate good value, supported.
1192 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1193 .Times(1)
1194 .WillOnce(Return("2000"));
Brandon Wyman8da35c52021-10-28 22:45:08 +00001195 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +00001196 PMBusExpectations expectations;
1197 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001198 // Analyze call will also need good READ_VIN value to check.
1199 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1200 .Times(1)
1201 .WillOnce(Return("201100"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001202 psu.analyze();
1203 EXPECT_EQ(psu.hasInputFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001204 // STATUS_WORD with input fault/warn on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001205 expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001206 // STATUS_INPUT with an input fault bit on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001207 expectations.statusInputValue = 0x80;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001208 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1209 {
1210 setPMBusExpectations(mockPMBus, expectations);
1211 // Analyze call will also need good READ_VIN value to check.
1212 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1213 .Times(1)
1214 .WillOnce(Return("201200"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001215 if (x == DEGLITCH_LIMIT)
1216 {
1217 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1218 }
Brandon Wymanc2906f42021-12-21 20:14:56 +00001219 psu.analyze();
1220 EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT);
1221 }
Brandon Wymanf07bc792021-10-12 19:00:35 +00001222 // STATUS_WORD with no bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001223 expectations.statusWordValue = 0;
1224 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001225 // Analyze call will also need good READ_VIN value to check.
1226 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1227 .Times(1)
1228 .WillOnce(Return("201300"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001229 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001230 psu.analyze();
1231 EXPECT_EQ(psu.hasInputFault(), false);
1232}
1233
1234TEST_F(PowerSupplyTests, HasMFRFault)
1235{
1236 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +00001237
George Liu9464c422023-02-27 14:30:27 +08001238 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68,
1239 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +00001240 MockedGPIOInterface* mockPresenceGPIO =
1241 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +00001242 // Always return 1 to indicate present.
1243 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001244 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001245 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001246 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1247 // for INPUT_HISTORY will check max_power_out to see if it is
1248 // old/unsupported power supply. Indicate good value, supported.
1249 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1250 .Times(1)
1251 .WillOnce(Return("2000"));
Brandon Wymanf07bc792021-10-12 19:00:35 +00001252 // First return STATUS_WORD with no bits on.
Brandon Wyman8da35c52021-10-28 22:45:08 +00001253 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +00001254 PMBusExpectations expectations;
1255 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001256 // Analyze call will also need good READ_VIN value to check.
1257 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1258 .Times(1)
1259 .WillOnce(Return("202100"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001260 psu.analyze();
1261 EXPECT_EQ(psu.hasMFRFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001262 // Next return STATUS_WORD with MFR fault bit on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001263 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001264 // STATUS_MFR_SPEFIC with bit(s) on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001265 expectations.statusMFRValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001266 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1267 {
1268 setPMBusExpectations(mockPMBus, expectations);
1269 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1270 .Times(1)
1271 .WillOnce(Return("202200"));
1272 psu.analyze();
1273 EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT);
1274 }
Brandon Wymanf07bc792021-10-12 19:00:35 +00001275 // Back to no bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +00001276 expectations.statusWordValue = 0;
1277 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001278 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1279 .Times(1)
1280 .WillOnce(Return("202300"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001281 psu.analyze();
1282 EXPECT_EQ(psu.hasMFRFault(), false);
1283}
1284
1285TEST_F(PowerSupplyTests, HasVINUVFault)
1286{
1287 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +00001288
George Liu9464c422023-02-27 14:30:27 +08001289 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68,
1290 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +00001291 MockedGPIOInterface* mockPresenceGPIO =
1292 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +00001293 // Always return 1 to indicate present.
1294 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001295 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001296 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001297 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1298 // for INPUT_HISTORY will check max_power_out to see if it is
1299 // old/unsupported power supply. Indicate good value, supported.
1300 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1301 .Times(1)
1302 .WillOnce(Return("2000"));
Brandon Wyman82affd92021-11-24 19:12:49 +00001303
1304 // Presence change from missing to present will trigger in1_input read in
1305 // an attempt to get CLEAR_FAULTS called. Return value ignored.
1306 // Zero to non-zero voltage, for missing/present change, triggers clear
1307 // faults call again. Return value ignored.
1308 // Fault (low voltage) to not faulted (voltage in range) triggers clear
1309 // faults call a third time.
1310
Brandon Wyman8da35c52021-10-28 22:45:08 +00001311 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +00001312 PMBusExpectations expectations;
1313 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001314 // Analyze call will also need good READ_VIN value to check.
1315 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1316 .Times(1)
1317 .WillOnce(Return("201100"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001318 psu.analyze();
1319 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001320 // Turn fault on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001321 expectations.statusWordValue = (status_word::VIN_UV_FAULT);
Brandon Wyman85c7bf42021-10-19 22:28:48 +00001322 // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by
1323 // Figure 16, and assume bits on in STATUS_INPUT.
Brandon Wymanb654c612021-11-05 23:24:51 +00001324 expectations.statusInputValue = 0x18;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001325 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1326 {
1327 setPMBusExpectations(mockPMBus, expectations);
1328 // If there is a VIN_UV fault, fake reading voltage of less than 20V
1329 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1330 .Times(1)
1331 .WillOnce(Return("19876"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001332 if (x == DEGLITCH_LIMIT)
1333 {
1334 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1335 }
Brandon Wymanc2906f42021-12-21 20:14:56 +00001336 psu.analyze();
1337 EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT);
1338 }
Brandon Wymanf07bc792021-10-12 19:00:35 +00001339 // Back to no fault bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +00001340 expectations.statusWordValue = 0;
1341 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001342 // Updates now result in clearing faults if read voltage goes from below the
1343 // minimum, to within a valid range.
1344 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1345 .Times(1)
1346 .WillOnce(Return("201300"));
Brandon Wyman3225a452022-03-18 18:51:49 +00001347 // Went from below minimum to within range, expect clearVinUVFault().
1348 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
1349 .Times(1)
1350 .WillOnce(Return(1));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001351 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001352 psu.analyze();
1353 EXPECT_EQ(psu.hasVINUVFault(), false);
1354}
Brandon Wyman6710ba22021-10-27 17:39:31 +00001355
1356TEST_F(PowerSupplyTests, HasVoutOVFault)
1357{
1358 auto bus = sdbusplus::bus::new_default();
1359
George Liu9464c422023-02-27 14:30:27 +08001360 PowerSupply psu{bus, PSUInventoryPath, 3, 0x69,
1361 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Brandon Wyman6710ba22021-10-27 17:39:31 +00001362 MockedGPIOInterface* mockPresenceGPIO =
1363 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1364 // Always return 1 to indicate present.
1365 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman6710ba22021-10-27 17:39:31 +00001366 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001367 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001368 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1369 // for INPUT_HISTORY will check max_power_out to see if it is
1370 // old/unsupported power supply. Indicate good value, supported.
1371 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1372 .Times(1)
1373 .WillOnce(Return("2000"));
Brandon Wyman6710ba22021-10-27 17:39:31 +00001374 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +00001375 PMBusExpectations expectations;
1376 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001377 // Call to analyze will trigger read of "in1_input" to check voltage.
1378 // Initial value would be 0, so this read updates it to non-zero.
1379 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1380 .Times(1)
1381 .WillOnce(Return("202100"));
Brandon Wyman6710ba22021-10-27 17:39:31 +00001382 psu.analyze();
1383 EXPECT_EQ(psu.hasVoutOVFault(), false);
1384 // Turn fault on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001385 expectations.statusWordValue = (status_word::VOUT_OV_FAULT);
Brandon Wyman6710ba22021-10-27 17:39:31 +00001386 // STATUS_VOUT fault bit(s)
Brandon Wymanb654c612021-11-05 23:24:51 +00001387 expectations.statusVOUTValue = 0x80;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001388 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1389 {
1390 setPMBusExpectations(mockPMBus, expectations);
1391 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1392 .Times(1)
1393 .WillOnce(Return("202200"));
1394 psu.analyze();
1395 EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT);
1396 }
Brandon Wyman6710ba22021-10-27 17:39:31 +00001397 // Back to no fault bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +00001398 expectations.statusWordValue = 0;
1399 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001400 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1401 .Times(1)
1402 .WillOnce(Return("202300"));
Brandon Wyman6710ba22021-10-27 17:39:31 +00001403 psu.analyze();
1404 EXPECT_EQ(psu.hasVoutOVFault(), false);
1405}
Brandon Wyman96893a42021-11-05 19:56:57 +00001406
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001407TEST_F(PowerSupplyTests, HasIoutOCFault)
1408{
1409 auto bus = sdbusplus::bus::new_default();
1410
George Liu9464c422023-02-27 14:30:27 +08001411 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d,
1412 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001413 MockedGPIOInterface* mockPresenceGPIO =
1414 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1415 // Always return 1 to indicate present.
1416 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001417 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001418 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001419 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1420 // for INPUT_HISTORY will check max_power_out to see if it is
1421 // old/unsupported power supply. Indicate good value, supported.
1422 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1423 .Times(1)
1424 .WillOnce(Return("2000"));
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001425 // STATUS_WORD 0x0000 is powered on, no faults.
1426 PMBusExpectations expectations;
1427 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001428 // Call to analyze will trigger read of "in1_input" to check voltage.
1429 // Initial value would be 0, so this read updates it to non-zero.
1430 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1431 .Times(1)
1432 .WillOnce(Return("203100"));
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001433 psu.analyze();
1434 EXPECT_EQ(psu.hasIoutOCFault(), false);
1435 // Turn fault on.
1436 expectations.statusWordValue = status_word::IOUT_OC_FAULT;
1437 // STATUS_IOUT fault bit(s)
1438 expectations.statusIOUTValue = 0x88;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001439 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1440 {
1441 setPMBusExpectations(mockPMBus, expectations);
1442 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1443 .Times(1)
1444 .WillOnce(Return("203200"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001445 if (x == DEGLITCH_LIMIT)
1446 {
1447 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1448 }
Brandon Wymanc2906f42021-12-21 20:14:56 +00001449 psu.analyze();
1450 EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT);
1451 }
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001452 // Back to no fault bits on in STATUS_WORD
1453 expectations.statusWordValue = 0;
1454 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001455 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1456 .Times(1)
1457 .WillOnce(Return("203300"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001458 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001459 psu.analyze();
1460 EXPECT_EQ(psu.hasIoutOCFault(), false);
1461}
1462
Brandon Wyman2cf46942021-10-28 19:09:16 +00001463TEST_F(PowerSupplyTests, HasVoutUVFault)
1464{
1465 auto bus = sdbusplus::bus::new_default();
1466
George Liu9464c422023-02-27 14:30:27 +08001467 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a,
1468 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Brandon Wyman2cf46942021-10-28 19:09:16 +00001469 MockedGPIOInterface* mockPresenceGPIO =
1470 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1471 // Always return 1 to indicate present.
1472 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman2cf46942021-10-28 19:09:16 +00001473 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001474 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001475 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1476 // for INPUT_HISTORY will check max_power_out to see if it is
1477 // old/unsupported power supply. Indicate good value, supported.
1478 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1479 .Times(1)
1480 .WillOnce(Return("2000"));
Brandon Wyman391a0692021-12-08 23:28:18 +00001481 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wyman2cf46942021-10-28 19:09:16 +00001482 PMBusExpectations expectations;
1483 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001484 // Call to analyze will trigger read of "in1_input" to check voltage.
1485 // Initial value would be 0, so this read updates it to non-zero.
1486 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1487 .Times(1)
1488 .WillOnce(Return("204100"));
Brandon Wyman2cf46942021-10-28 19:09:16 +00001489 psu.analyze();
1490 EXPECT_EQ(psu.hasVoutUVFault(), false);
1491 // Turn fault on.
1492 expectations.statusWordValue = (status_word::VOUT_FAULT);
1493 // STATUS_VOUT fault bit(s)
1494 expectations.statusVOUTValue = 0x30;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001495 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1496 {
1497 setPMBusExpectations(mockPMBus, expectations);
1498 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1499 .Times(1)
1500 .WillOnce(Return("204200"));
1501 psu.analyze();
1502 EXPECT_EQ(psu.hasVoutUVFault(), x >= DEGLITCH_LIMIT);
1503 }
Brandon Wyman2cf46942021-10-28 19:09:16 +00001504 // Back to no fault bits on in STATUS_WORD
1505 expectations.statusWordValue = 0;
1506 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001507 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1508 .Times(1)
1509 .WillOnce(Return("204300"));
Brandon Wyman2cf46942021-10-28 19:09:16 +00001510 psu.analyze();
1511 EXPECT_EQ(psu.hasVoutUVFault(), false);
1512}
1513
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001514TEST_F(PowerSupplyTests, HasFanFault)
1515{
1516 auto bus = sdbusplus::bus::new_default();
1517
Matt Spinler0975eaf2022-02-14 15:38:30 -06001518 EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1);
1519 EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0);
1520
George Liu9464c422023-02-27 14:30:27 +08001521 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d,
1522 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001523 MockedGPIOInterface* mockPresenceGPIO =
1524 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1525 // Always return 1 to indicate present.
1526 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001527 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001528 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001529 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1530 // for INPUT_HISTORY will check max_power_out to see if it is
1531 // old/unsupported power supply. Indicate good value, supported.
1532 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1533 .Times(1)
1534 .WillOnce(Return("2000"));
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001535 // STATUS_WORD 0x0000 is powered on, no faults.
1536 PMBusExpectations expectations;
1537 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001538 // Call to analyze will trigger read of "in1_input" to check voltage.
1539 // Initial value would be 0, so this read updates it to non-zero.
1540 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1541 .Times(1)
1542 .WillOnce(Return("205100"));
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001543 psu.analyze();
1544 EXPECT_EQ(psu.hasFanFault(), false);
1545 // Turn fault on.
1546 expectations.statusWordValue = (status_word::FAN_FAULT);
1547 // STATUS_FANS_1_2 fault bit on (Fan 1 Fault)
1548 expectations.statusFans12Value = 0x80;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001549 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1550 {
1551 setPMBusExpectations(mockPMBus, expectations);
1552 // Call to analyze will trigger read of "in1_input" to check voltage.
1553 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1554 .Times(1)
1555 .WillOnce(Return("205200"));
1556 psu.analyze();
1557 EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT);
1558 }
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001559 // Back to no fault bits on in STATUS_WORD
1560 expectations.statusWordValue = 0;
1561 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001562 // Call to analyze will trigger read of "in1_input" to check voltage.
1563 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1564 .Times(1)
1565 .WillOnce(Return("205300"));
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001566 psu.analyze();
1567 EXPECT_EQ(psu.hasFanFault(), false);
1568}
1569
Brandon Wyman96893a42021-11-05 19:56:57 +00001570TEST_F(PowerSupplyTests, HasTempFault)
1571{
1572 auto bus = sdbusplus::bus::new_default();
1573
Matt Spinler0975eaf2022-02-14 15:38:30 -06001574 EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1);
1575 EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0);
1576
George Liu9464c422023-02-27 14:30:27 +08001577 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a,
1578 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Brandon Wyman96893a42021-11-05 19:56:57 +00001579 MockedGPIOInterface* mockPresenceGPIO =
1580 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1581 // Always return 1 to indicate present.
1582 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman96893a42021-11-05 19:56:57 +00001583 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001584 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001585 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1586 // for INPUT_HISTORY will check max_power_out to see if it is
1587 // old/unsupported power supply. Indicate good value, supported.
1588 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1589 .Times(1)
1590 .WillOnce(Return("2000"));
Brandon Wyman96893a42021-11-05 19:56:57 +00001591 // STATUS_WORD 0x0000 is powered on, no faults.
1592 PMBusExpectations expectations;
1593 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001594 // Call to analyze will trigger read of "in1_input" to check voltage.
1595 // Initial value would be 0, so this read updates it to non-zero.
1596 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1597 .Times(1)
1598 .WillOnce(Return("206100"));
Brandon Wyman96893a42021-11-05 19:56:57 +00001599 psu.analyze();
1600 EXPECT_EQ(psu.hasTempFault(), false);
1601 // Turn fault on.
1602 expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
1603 // STATUS_TEMPERATURE fault bit on (OT Fault)
1604 expectations.statusTempValue = 0x80;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001605 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1606 {
1607 setPMBusExpectations(mockPMBus, expectations);
1608 // Call to analyze will trigger read of "in1_input" to check voltage.
1609 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1610 .Times(1)
1611 .WillOnce(Return("206200"));
1612 psu.analyze();
1613 EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT);
1614 }
Brandon Wyman96893a42021-11-05 19:56:57 +00001615 // Back to no fault bits on in STATUS_WORD
1616 expectations.statusWordValue = 0;
1617 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001618 // Call to analyze will trigger read of "in1_input" to check voltage.
1619 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1620 .Times(1)
1621 .WillOnce(Return("206300"));
Brandon Wyman96893a42021-11-05 19:56:57 +00001622 psu.analyze();
1623 EXPECT_EQ(psu.hasTempFault(), false);
1624}
Brandon Wyman2916ea52021-11-06 03:31:18 +00001625
1626TEST_F(PowerSupplyTests, HasPgoodFault)
1627{
1628 auto bus = sdbusplus::bus::new_default();
1629
George Liu9464c422023-02-27 14:30:27 +08001630 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6b,
1631 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Brandon Wyman2916ea52021-11-06 03:31:18 +00001632 MockedGPIOInterface* mockPresenceGPIO =
1633 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1634 // Always return 1 to indicate present.
1635 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001636 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001637 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001638 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1639 // for INPUT_HISTORY will check max_power_out to see if it is
1640 // old/unsupported power supply. Indicate good value, supported.
1641 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1642 .Times(1)
1643 .WillOnce(Return("2000"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001644 // STATUS_WORD 0x0000 is powered on, no faults.
1645 PMBusExpectations expectations;
1646 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001647 // Call to analyze will trigger read of "in1_input" to check voltage.
1648 // Initial value would be 0, so this read updates it to non-zero.
1649 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1650 .Times(1)
1651 .WillOnce(Return("207100"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001652 psu.analyze();
1653 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman391a0692021-12-08 23:28:18 +00001654 // Setup another expectation of no faults.
1655 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001656 // Call to analyze will trigger read of "in1_input" to check voltage.
1657 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1658 .Times(1)
1659 .WillOnce(Return("207200"));
1660 psu.analyze();
1661 EXPECT_EQ(psu.hasPgoodFault(), false);
1662 // Setup another expectation of no faults.
1663 setPMBusExpectations(mockPMBus, expectations);
1664 // Call to analyze will trigger read of "in1_input" to check voltage.
1665 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1666 .Times(1)
1667 .WillOnce(Return("207300"));
Brandon Wyman391a0692021-12-08 23:28:18 +00001668 psu.analyze();
1669 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +00001670 // Turn PGOOD# off (fault on).
1671 expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED);
1672 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001673 // Call to analyze will trigger read of "in1_input" to check voltage.
1674 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1675 .Times(1)
1676 .WillOnce(Return("207400"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001677 psu.analyze();
Brandon Wyman6d469fd2022-06-15 16:58:21 +00001678 // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 1
Brandon Wyman06ca4592021-12-06 22:52:23 +00001679 EXPECT_EQ(psu.hasPgoodFault(), false);
1680 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001681 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1682 .Times(1)
1683 .WillOnce(Return("207500"));
Brandon Wyman06ca4592021-12-06 22:52:23 +00001684 psu.analyze();
Brandon Wyman6d469fd2022-06-15 16:58:21 +00001685 // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 2
Brandon Wyman06ca4592021-12-06 22:52:23 +00001686 EXPECT_EQ(psu.hasPgoodFault(), false);
1687 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001688 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1689 .Times(1)
1690 .WillOnce(Return("207600"));
Brandon Wyman06ca4592021-12-06 22:52:23 +00001691 psu.analyze();
Brandon Wyman6d469fd2022-06-15 16:58:21 +00001692 // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 3
1693 EXPECT_EQ(psu.hasPgoodFault(), false);
1694 setPMBusExpectations(mockPMBus, expectations);
1695 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1696 .Times(1)
1697 .WillOnce(Return("207700"));
1698 psu.analyze();
1699 // Expect false until reaches PGOOD_DEGLITCH_LIMIT @ 4
1700 EXPECT_EQ(psu.hasPgoodFault(), false);
1701 setPMBusExpectations(mockPMBus, expectations);
1702 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1703 .Times(1)
1704 .WillOnce(Return("207800"));
1705 psu.analyze();
1706 // Expect true. PGOOD_DEGLITCH_LIMIT @ 5
Brandon Wyman2916ea52021-11-06 03:31:18 +00001707 EXPECT_EQ(psu.hasPgoodFault(), true);
1708 // Back to no fault bits on in STATUS_WORD
1709 expectations.statusWordValue = 0;
1710 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001711 // Call to analyze will trigger read of "in1_input" to check voltage.
1712 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1713 .Times(1)
1714 .WillOnce(Return("207700"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001715 psu.analyze();
1716 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman82affd92021-11-24 19:12:49 +00001717
Brandon Wyman2916ea52021-11-06 03:31:18 +00001718 // Turn OFF bit on
1719 expectations.statusWordValue = (status_word::UNIT_IS_OFF);
1720 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001721 // Call to analyze will trigger read of "in1_input" to check voltage.
1722 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1723 .Times(1)
1724 .WillOnce(Return("208100"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001725 psu.analyze();
Brandon Wyman06ca4592021-12-06 22:52:23 +00001726 EXPECT_EQ(psu.hasPgoodFault(), false);
1727 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001728 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1729 .Times(1)
1730 .WillOnce(Return("208200"));
Brandon Wyman06ca4592021-12-06 22:52:23 +00001731 psu.analyze();
1732 EXPECT_EQ(psu.hasPgoodFault(), false);
1733 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001734 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1735 .Times(1)
1736 .WillOnce(Return("208300"));
Brandon Wyman06ca4592021-12-06 22:52:23 +00001737 psu.analyze();
Brandon Wyman6d469fd2022-06-15 16:58:21 +00001738 EXPECT_EQ(psu.hasPgoodFault(), false);
1739 setPMBusExpectations(mockPMBus, expectations);
1740 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1741 .Times(1)
1742 .WillOnce(Return("208400"));
1743 psu.analyze();
1744 EXPECT_EQ(psu.hasPgoodFault(), false);
1745 setPMBusExpectations(mockPMBus, expectations);
1746 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1747 .Times(1)
1748 .WillOnce(Return("208500"));
1749 psu.analyze();
Brandon Wyman2916ea52021-11-06 03:31:18 +00001750 EXPECT_EQ(psu.hasPgoodFault(), true);
1751 // Back to no fault bits on in STATUS_WORD
1752 expectations.statusWordValue = 0;
1753 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001754 // Call to analyze will trigger read of "in1_input" to check voltage.
1755 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1756 .Times(1)
Brandon Wyman6d469fd2022-06-15 16:58:21 +00001757 .WillOnce(Return("208000"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001758 psu.analyze();
1759 EXPECT_EQ(psu.hasPgoodFault(), false);
1760}
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001761
1762TEST_F(PowerSupplyTests, HasPSKillFault)
1763{
1764 auto bus = sdbusplus::bus::new_default();
George Liu9464c422023-02-27 14:30:27 +08001765 PowerSupply psu{bus, PSUInventoryPath, 4, 0x6d,
1766 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001767 MockedGPIOInterface* mockPresenceGPIO =
1768 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1769 // Always return 1 to indicate present.
1770 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001771 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman82affd92021-11-24 19:12:49 +00001772 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001773 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1774 // for INPUT_HISTORY will check max_power_out to see if it is
1775 // old/unsupported power supply. Indicate good value, supported.
1776 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1777 .Times(1)
1778 .WillOnce(Return("2000"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001779 // STATUS_WORD 0x0000 is powered on, no faults.
1780 PMBusExpectations expectations;
1781 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001782 // Call to analyze will trigger read of "in1_input" to check voltage.
1783 // Initial value would be 0, so this read updates it to non-zero.
1784 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1785 .Times(1)
1786 .WillOnce(Return("208100"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001787 psu.analyze();
1788 EXPECT_EQ(psu.hasPSKillFault(), false);
1789 // Next return STATUS_WORD with MFR fault bit on.
1790 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1791 // STATUS_MFR_SPEFIC with bit(s) on.
1792 expectations.statusMFRValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001793
1794 // Deglitching faults, false until read the fault bits on up to the limit.
1795 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1796 {
1797 setPMBusExpectations(mockPMBus, expectations);
1798 // Call to analyze will trigger read of "in1_input" to check voltage.
1799 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1800 .Times(1)
1801 .WillOnce(Return("208200"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001802 if (x == DEGLITCH_LIMIT)
1803 {
1804 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1805 }
Brandon Wymanc2906f42021-12-21 20:14:56 +00001806 psu.analyze();
1807 EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT);
1808 }
1809
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001810 // Back to no bits on in STATUS_WORD
1811 expectations.statusWordValue = 0;
1812 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001813 // Call to analyze will trigger read of "in1_input" to check voltage.
1814 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1815 .Times(1)
1816 .WillOnce(Return("208300"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001817 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001818 psu.analyze();
1819 EXPECT_EQ(psu.hasPSKillFault(), false);
1820 // Next return STATUS_WORD with MFR fault bit on.
1821 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1822 // STATUS_MFR_SPEFIC with bit 4 on.
1823 expectations.statusMFRValue = 0x10;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001824
1825 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1826 {
1827 setPMBusExpectations(mockPMBus, expectations);
1828 // Call to analyze will trigger read of "in1_input" to check voltage.
1829 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1830 .Times(1)
1831 .WillOnce(Return("208400"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001832 if (x == DEGLITCH_LIMIT)
1833 {
1834 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1835 }
Brandon Wymanc2906f42021-12-21 20:14:56 +00001836 psu.analyze();
1837 EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT);
1838 }
1839
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001840 // Back to no bits on in STATUS_WORD
1841 expectations.statusWordValue = 0;
1842 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001843 // Call to analyze will trigger read of "in1_input" to check voltage.
1844 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1845 .Times(1)
1846 .WillOnce(Return("208500"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001847 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001848 psu.analyze();
1849 EXPECT_EQ(psu.hasPSKillFault(), false);
1850}
1851
1852TEST_F(PowerSupplyTests, HasPS12VcsFault)
1853{
1854 auto bus = sdbusplus::bus::new_default();
George Liu9464c422023-02-27 14:30:27 +08001855 PowerSupply psu{bus, PSUInventoryPath, 5, 0x6e,
1856 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001857 MockedGPIOInterface* mockPresenceGPIO =
1858 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1859 // Always return 1 to indicate present.
1860 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001861 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman82affd92021-11-24 19:12:49 +00001862 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001863 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1864 // for INPUT_HISTORY will check max_power_out to see if it is
1865 // old/unsupported power supply. Indicate good value, supported.
1866 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1867 .Times(1)
1868 .WillOnce(Return("2000"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001869 // STATUS_WORD 0x0000 is powered on, no faults.
1870 PMBusExpectations expectations;
1871 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001872 // Call to analyze will trigger read of "in1_input" to check voltage.
1873 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1874 .Times(1)
1875 .WillOnce(Return("209100"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001876 psu.analyze();
1877 EXPECT_EQ(psu.hasPS12VcsFault(), false);
1878 // Next return STATUS_WORD with MFR fault bit on.
1879 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1880 // STATUS_MFR_SPEFIC with bit(s) on.
1881 expectations.statusMFRValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001882
1883 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1884 {
1885 setPMBusExpectations(mockPMBus, expectations);
1886 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1887 .Times(1)
1888 .WillOnce(Return("209200"));
1889 psu.analyze();
1890 EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
1891 }
1892
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001893 // Back to no bits on in STATUS_WORD
1894 expectations.statusWordValue = 0;
1895 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001896 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1897 .Times(1)
1898 .WillOnce(Return("209300"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001899 psu.analyze();
1900 EXPECT_EQ(psu.hasPS12VcsFault(), false);
1901 // Next return STATUS_WORD with MFR fault bit on.
1902 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1903 // STATUS_MFR_SPEFIC with bit 6 on.
1904 expectations.statusMFRValue = 0x40;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001905
1906 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1907 {
1908 setPMBusExpectations(mockPMBus, expectations);
1909 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1910 .Times(1)
1911 .WillOnce(Return("209400"));
1912 psu.analyze();
1913 EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
1914 }
1915
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001916 // Back to no bits on in STATUS_WORD
1917 expectations.statusWordValue = 0;
1918 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001919 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1920 .Times(1)
1921 .WillOnce(Return("209500"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001922 psu.analyze();
1923 EXPECT_EQ(psu.hasPS12VcsFault(), false);
1924}
1925
1926TEST_F(PowerSupplyTests, HasPSCS12VFault)
1927{
1928 auto bus = sdbusplus::bus::new_default();
George Liu9464c422023-02-27 14:30:27 +08001929 PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f,
1930 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001931 MockedGPIOInterface* mockPresenceGPIO =
1932 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1933 // Always return 1 to indicate present.
1934 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001935 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman82affd92021-11-24 19:12:49 +00001936 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001937 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1938 // for INPUT_HISTORY will check max_power_out to see if it is
1939 // old/unsupported power supply. Indicate good value, supported.
1940 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1941 .Times(1)
1942 .WillOnce(Return("2000"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001943 // STATUS_WORD 0x0000 is powered on, no faults.
1944 PMBusExpectations expectations;
1945 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001946 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1947 .Times(1)
1948 .WillOnce(Return("209100"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001949 psu.analyze();
1950 EXPECT_EQ(psu.hasPSCS12VFault(), false);
1951 // Next return STATUS_WORD with MFR fault bit on.
1952 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1953 // STATUS_MFR_SPEFIC with bit(s) on.
1954 expectations.statusMFRValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001955
1956 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1957 {
1958 setPMBusExpectations(mockPMBus, expectations);
1959 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1960 .Times(1)
1961 .WillOnce(Return("209200"));
1962 psu.analyze();
1963 EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
1964 }
1965
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001966 // Back to no bits on in STATUS_WORD
1967 expectations.statusWordValue = 0;
1968 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001969 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1970 .Times(1)
1971 .WillOnce(Return("209300"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001972 psu.analyze();
1973 EXPECT_EQ(psu.hasPSCS12VFault(), false);
1974 // Next return STATUS_WORD with MFR fault bit on.
1975 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1976 // STATUS_MFR_SPEFIC with bit 7 on.
1977 expectations.statusMFRValue = 0x80;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001978
1979 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1980 {
1981 setPMBusExpectations(mockPMBus, expectations);
1982 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1983 .Times(1)
1984 .WillOnce(Return("209400"));
1985 psu.analyze();
1986 EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
1987 }
1988
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001989 // Back to no bits on in STATUS_WORD
1990 expectations.statusWordValue = 0;
1991 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001992 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1993 .Times(1)
1994 .WillOnce(Return("209500"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001995 psu.analyze();
1996 EXPECT_EQ(psu.hasPSCS12VFault(), false);
1997}
Brandon Wymanc3324422022-03-24 20:30:57 +00001998
1999TEST_F(PowerSupplyTests, SetupInputHistory)
2000{
2001 auto bus = sdbusplus::bus::new_default();
2002 {
George Liu9464c422023-02-27 14:30:27 +08002003 PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f,
2004 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Brandon Wymanc3324422022-03-24 20:30:57 +00002005 // Defaults to not present due to constructor and mock ordering.
2006 psu.setupInputHistory();
2007 EXPECT_EQ(psu.hasInputHistory(), false);
2008 MockedGPIOInterface* mockPresenceGPIO =
2009 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wymanae35ac52022-05-23 22:33:40 +00002010 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wymanc3324422022-03-24 20:30:57 +00002011 // Always return 1 to indicate present.
2012 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wymanae35ac52022-05-23 22:33:40 +00002013 setMissingToPresentExpects(mockPMBus, mockedUtil);
2014 PMBusExpectations expectations;
2015 setPMBusExpectations(mockPMBus, expectations);
2016 // After reading STATUS_WORD, etc., there will be a READ_VIN check.
2017 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
2018 .Times(1)
2019 .WillOnce(Return("206000"));
2020 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
2021 // for INPUT_HISTORY will check max_power_out to see if it is
2022 // old/unsupported power supply. Indicate good value, supported.
2023 /// Also called when I redo setupInputHistory().
2024 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
2025 .Times(2)
2026 .WillRepeatedly(Return("2000"));
2027 // Call to analyze() and above expectations to get missing/present and
2028 // good status.
Brandon Wymanc3324422022-03-24 20:30:57 +00002029 psu.analyze();
2030 psu.setupInputHistory();
2031 EXPECT_EQ(psu.hasInputHistory(), true);
2032 }
2033 {
Brandon Wymanae35ac52022-05-23 22:33:40 +00002034 // Workaround - Disable INPUT_HISTORY collection if 1400W
George Liu9464c422023-02-27 14:30:27 +08002035 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68,
2036 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Brandon Wymanae35ac52022-05-23 22:33:40 +00002037 // Defaults to not present due to constructor and mock ordering.
2038 psu.setupInputHistory();
2039 EXPECT_EQ(psu.hasInputHistory(), false);
2040 MockedGPIOInterface* mockPresenceGPIO =
2041 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
2042 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
2043 // Always return 1 to indicate present.
2044 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
2045 setMissingToPresentExpects(mockPMBus, mockedUtil);
2046 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
2047 // for INPUT_HISTORY will check max_power_out to see if it is
2048 // old/unsupported power supply. Indicate 1400W IBM value, unsupported.
2049 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
2050 .Times(2)
2051 .WillRepeatedly(Return("30725"));
2052 PMBusExpectations expectations;
2053 setPMBusExpectations(mockPMBus, expectations);
2054 // After reading STATUS_WORD, etc., there will be a READ_VIN check.
2055 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
2056 .Times(1)
2057 .WillOnce(Return("206000"));
2058 // Call to analyze() and above expectations to get missing/present and
2059 // good status.
2060 psu.analyze();
2061 psu.setupInputHistory();
2062 // After updating to present, and retrying setup, expect ibm-cffps with
2063 // 1400W to still not support INPUT_HISTORY.
2064 EXPECT_EQ(psu.hasInputHistory(), false);
2065 }
2066 {
George Liu9464c422023-02-27 14:30:27 +08002067 PowerSupply psu{bus, PSUInventoryPath, 11,
2068 0x58, "inspur-ipsps", PSUGPIOLineName,
2069 isPowerOn};
Brandon Wymanc3324422022-03-24 20:30:57 +00002070 // Defaults to not present due to constructor and mock ordering.
2071 psu.setupInputHistory();
2072 EXPECT_EQ(psu.hasInputHistory(), false);
2073 MockedGPIOInterface* mockPresenceGPIO =
2074 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wymanae35ac52022-05-23 22:33:40 +00002075 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wymanc3324422022-03-24 20:30:57 +00002076 // Always return 1 to indicate present.
2077 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wymanae35ac52022-05-23 22:33:40 +00002078 setMissingToPresentExpects(mockPMBus, mockedUtil);
2079 PMBusExpectations expectations;
2080 setPMBusExpectations(mockPMBus, expectations);
2081 // After reading STATUS_WORD, etc., there will be a READ_VIN check.
2082 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
2083 .Times(1)
2084 .WillOnce(Return("206000"));
2085 // Call to analyze() and above expectations to get missing/present and
2086 // good status.
Brandon Wymanc3324422022-03-24 20:30:57 +00002087 psu.analyze();
2088 psu.setupInputHistory();
2089 // After updating to present, and retrying setup, expect inspur-ipsps to
2090 // still not support INPUT_HISTORY.
2091 EXPECT_EQ(psu.hasInputHistory(), false);
2092 }
2093}
2094
2095TEST_F(PowerSupplyTests, UpdateHistory)
2096{
2097 auto bus = sdbusplus::bus::new_default();
George Liu9464c422023-02-27 14:30:27 +08002098 PowerSupply psu{bus, PSUInventoryPath, 7, 0x6e,
2099 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Brandon Wymanc3324422022-03-24 20:30:57 +00002100 EXPECT_EQ(psu.hasInputHistory(), false);
2101 EXPECT_EQ(psu.getNumInputHistoryRecords(), 0);
2102 MockedGPIOInterface* mockPresenceGPIO =
2103 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
2104 // Always return 1 to indicate present.
2105 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
2106 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
2107 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00002108 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
2109 // for INPUT_HISTORY will check max_power_out to see if it is
2110 // old/unsupported power supply. Indicate good value, supported.
2111 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
2112 .Times(1)
2113 .WillOnce(Return("2000"));
Brandon Wymanc3324422022-03-24 20:30:57 +00002114 PMBusExpectations expectations;
2115 setPMBusExpectations(mockPMBus, expectations);
2116 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
2117 .Times(6)
2118 .WillRepeatedly(Return("205000"));
2119 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
2120 // First read after missing/present will have no data.
2121 std::vector<uint8_t> emptyHistory{};
2122 // Second read, after about 30 seconds, should have a record. 5-bytes.
2123 // Sequence Number: 0x00, Average: 0x50 0xf3 (212), Maximum: 0x54 0xf3 (213)
2124 std::vector<uint8_t> firstHistory{0x00, 0x50, 0xf3, 0x54, 0xf3};
2125 // Third read, after about 60 seconds, should have two records, 10-bytes,
2126 // but only reading 5 bytes, so make sure new/next sequence number
2127 std::vector<uint8_t> secondHistory{0x01, 0x54, 0xf3, 0x58, 0xf3};
2128 // Fourth read, 3rd sequence number (0x02).
2129 std::vector<uint8_t> thirdHistory{0x02, 0x54, 0xf3, 0x58, 0xf3};
2130 // Fifth read, out of sequence, clear and insert this one?
2131 std::vector<uint8_t> outseqHistory{0xff, 0x5c, 0xf3, 0x60, 0xf3};
2132 EXPECT_CALL(
2133 mockPMBus,
2134 readBinary(INPUT_HISTORY, Type::HwmonDeviceDebug,
2135 phosphor::power::history::RecordManager::RAW_RECORD_SIZE))
2136 .Times(6)
2137 .WillOnce(Return(emptyHistory))
2138 .WillOnce(Return(firstHistory))
2139 .WillOnce(Return(secondHistory))
2140 .WillOnce(Return(thirdHistory))
2141 .WillOnce(Return(outseqHistory))
2142 .WillOnce(Return(emptyHistory));
2143 // Calling analyze will update the presence, which will setup the input
2144 // history if the power supply went from missing to present.
2145 psu.analyze();
2146 // The ibm-cffps power supply should support input history
2147 EXPECT_EQ(psu.hasInputHistory(), true);
2148 // Usually should have empty buffer right after missing to present.
2149 // Faked that out above with mocked readBinary with emptyHistory data.
2150 EXPECT_EQ(psu.getNumInputHistoryRecords(), 0);
2151 // Second run through...
2152 setPMBusExpectations(mockPMBus, expectations);
2153 psu.analyze();
2154 EXPECT_EQ(psu.hasInputHistory(), true);
2155 EXPECT_EQ(psu.getNumInputHistoryRecords(), 1);
2156 // Third run through
2157 setPMBusExpectations(mockPMBus, expectations);
2158 psu.analyze();
2159 EXPECT_EQ(psu.hasInputHistory(), true);
2160 EXPECT_EQ(psu.getNumInputHistoryRecords(), 2);
2161 // Fourth run through. Up to 3 records now?
2162 setPMBusExpectations(mockPMBus, expectations);
2163 psu.analyze();
2164 EXPECT_EQ(psu.hasInputHistory(), true);
2165 EXPECT_EQ(psu.getNumInputHistoryRecords(), 3);
2166 // Out of sequencer, reset, insert new one.
2167 setPMBusExpectations(mockPMBus, expectations);
2168 psu.analyze();
2169 EXPECT_EQ(psu.hasInputHistory(), true);
2170 EXPECT_EQ(psu.getNumInputHistoryRecords(), 1);
2171 // Empty one after last one good. Reset/clear.
2172 setPMBusExpectations(mockPMBus, expectations);
2173 psu.analyze();
2174 EXPECT_EQ(psu.hasInputHistory(), true);
2175 EXPECT_EQ(psu.getNumInputHistoryRecords(), 0);
2176}
Brandon Wyman18a24d92022-04-19 22:48:34 +00002177
2178TEST_F(PowerSupplyTests, IsSyncHistoryRequired)
2179{
2180 auto bus = sdbusplus::bus::new_default();
George Liu9464c422023-02-27 14:30:27 +08002181 PowerSupply psu{bus, PSUInventoryPath, 8, 0x6f,
2182 "ibm-cffps", PSUGPIOLineName, isPowerOn};
Brandon Wyman18a24d92022-04-19 22:48:34 +00002183 EXPECT_EQ(psu.hasInputHistory(), false);
2184 EXPECT_EQ(psu.isSyncHistoryRequired(), false);
2185 MockedGPIOInterface* mockPresenceGPIO =
2186 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
2187 // Always return 1 to indicate present.
2188 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
2189 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
2190 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00002191 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
2192 // for INPUT_HISTORY will check max_power_out to see if it is
2193 // old/unsupported power supply. Indicate good value, supported.
2194 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
2195 .Times(1)
2196 .WillOnce(Return("2000"));
Brandon Wyman18a24d92022-04-19 22:48:34 +00002197 PMBusExpectations expectations;
2198 setPMBusExpectations(mockPMBus, expectations);
2199 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
2200 .Times(1)
2201 .WillRepeatedly(Return("205000"));
2202 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
2203 psu.analyze();
2204 // The ibm-cffps power supply should support input history
2205 EXPECT_EQ(psu.hasInputHistory(), true);
2206 // Missing -> Present requires history sync
2207 EXPECT_EQ(psu.isSyncHistoryRequired(), true);
2208 psu.clearSyncHistoryRequired();
2209 EXPECT_EQ(psu.isSyncHistoryRequired(), false);
2210}