1 #include "../power_supply.hpp"
2 #include "../record_manager.hpp"
3 #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 
11 using namespace phosphor::power::psu;
12 using namespace phosphor::pmbus;
13 
14 using ::testing::_;
15 using ::testing::Args;
16 using ::testing::Assign;
17 using ::testing::DoAll;
18 using ::testing::ElementsAre;
19 using ::testing::NotNull;
20 using ::testing::Return;
21 using ::testing::StrEq;
22 
23 static auto PSUInventoryPath = "/xyz/bmc/inv/sys/chassis/board/powersupply0";
24 static auto PSUGPIOLineName = "presence-ps0";
25 
26 struct PMBusExpectations
27 {
28     uint16_t statusWordValue{0x0000};
29     uint8_t statusInputValue{0x00};
30     uint8_t statusMFRValue{0x00};
31     uint8_t statusCMLValue{0x00};
32     uint8_t statusVOUTValue{0x00};
33     uint8_t statusIOUTValue{0x00};
34     uint8_t statusFans12Value{0x00};
35     uint8_t statusTempValue{0x00};
36 };
37 
38 // Helper function to setup expectations for various STATUS_* commands
39 void setPMBusExpectations(MockedPMBus& mockPMBus,
40                           const PMBusExpectations& expectations)
41 {
42     EXPECT_CALL(mockPMBus, read(STATUS_WORD, _, _))
43         .Times(1)
44         .WillOnce(Return(expectations.statusWordValue));
45 
46     if (expectations.statusWordValue != 0)
47     {
48         // If fault bits are on in STATUS_WORD, there will also be a read of
49         // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT (page 0), and
50         // STATUS_TEMPERATURE.
51         EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _, _))
52             .Times(1)
53             .WillOnce(Return(expectations.statusInputValue));
54         EXPECT_CALL(mockPMBus, read(STATUS_MFR, _, _))
55             .Times(1)
56             .WillOnce(Return(expectations.statusMFRValue));
57         EXPECT_CALL(mockPMBus, read(STATUS_CML, _, _))
58             .Times(1)
59             .WillOnce(Return(expectations.statusCMLValue));
60         // Page will need to be set to 0 to read STATUS_VOUT.
61         EXPECT_CALL(mockPMBus, insertPageNum(STATUS_VOUT, 0))
62             .Times(1)
63             .WillOnce(Return("status0_vout"));
64         EXPECT_CALL(mockPMBus, read("status0_vout", _, _))
65             .Times(1)
66             .WillOnce(Return(expectations.statusVOUTValue));
67         EXPECT_CALL(mockPMBus, read(STATUS_IOUT, _, _))
68             .Times(1)
69             .WillOnce(Return(expectations.statusIOUTValue));
70         EXPECT_CALL(mockPMBus, read(STATUS_FANS_1_2, _, _))
71             .Times(1)
72             .WillOnce(Return(expectations.statusFans12Value));
73         EXPECT_CALL(mockPMBus, read(STATUS_TEMPERATURE, _, _))
74             .Times(1)
75             .WillOnce(Return(expectations.statusTempValue));
76     }
77 }
78 
79 class PowerSupplyTests : public ::testing::Test
80 {
81   public:
82     PowerSupplyTests() :
83         mockedUtil(reinterpret_cast<const MockedUtil&>(getUtils()))
84     {
85         ON_CALL(mockedUtil, getPresence(_, _)).WillByDefault(Return(false));
86     }
87 
88     ~PowerSupplyTests() override
89     {
90         freeUtils();
91     }
92 
93     const MockedUtil& mockedUtil;
94 };
95 
96 // Helper function for when a power supply goes from missing to present.
97 void setMissingToPresentExpects(MockedPMBus& pmbus, const MockedUtil& util)
98 {
99     // Call to analyze() will update to present, that will trigger updating
100     // to the correct/latest HWMON directory, in case it changes.
101     EXPECT_CALL(pmbus, findHwmonDir());
102     // Presence change from missing to present will trigger write to
103     // ON_OFF_CONFIG.
104     EXPECT_CALL(pmbus, writeBinary(ON_OFF_CONFIG, _, _));
105     // Presence change from missing to present will trigger in1_input read
106     // in an attempt to get CLEAR_FAULTS called.
107     // This READ_VIN for CLEAR_FAULTS does not check the returned value.
108     EXPECT_CALL(pmbus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
109     // The call for clearing faults includes clearing VIN_UV fault.
110     // The voltage defaults to 0, the first call to analyze should update the
111     // voltage to the current reading, triggering clearing VIN_UV fault(s)
112     // due to below minimum to within range voltage.
113     EXPECT_CALL(pmbus, read("in1_lcrit_alarm", _, _))
114         .Times(2)
115         .WillRepeatedly(Return(1));
116     // Missing/present call will update Presence in inventory.
117     EXPECT_CALL(util, setPresence(_, _, true, _));
118 }
119 
120 TEST_F(PowerSupplyTests, Constructor)
121 {
122     /**
123      * @param[in] invpath - String for inventory path to use
124      * @param[in] i2cbus - The bus number this power supply is on
125      * @param[in] i2caddr - The 16-bit I2C address of the power supply
126      * @param[in] gpioLineName - The string for the gpio-line-name to read for
127      * presence.
128      * @param[in] bindDelay - Time in milliseconds to delay binding the device
129      * driver after seeing the presence line go active.
130      */
131     auto bus = sdbusplus::bus::new_default();
132 
133     // Try where inventory path is empty, constructor should fail.
134     try
135     {
136         auto psu = std::make_unique<PowerSupply>(bus, "", 3, 0x68, "ibm-cffps",
137                                                  PSUGPIOLineName);
138         ADD_FAILURE() << "Should not have reached this line.";
139     }
140     catch (const std::invalid_argument& e)
141     {
142         EXPECT_STREQ(e.what(), "Invalid empty inventoryPath");
143     }
144     catch (...)
145     {
146         ADD_FAILURE() << "Should not have caught exception.";
147     }
148 
149     // TODO: Try invalid i2c address?
150 
151     // Try where gpioLineName is empty.
152     try
153     {
154         auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68,
155                                                  "ibm-cffps", "");
156         ADD_FAILURE()
157             << "Should not have reached this line. Invalid gpioLineName.";
158     }
159     catch (const std::invalid_argument& e)
160     {
161         EXPECT_STREQ(e.what(), "Invalid empty gpioLineName");
162     }
163     catch (...)
164     {
165         ADD_FAILURE() << "Should not have caught exception.";
166     }
167 
168     // Test with valid arguments
169     // NOT using D-Bus inventory path for presence.
170     try
171     {
172         auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68,
173                                                  "ibm-cffps", PSUGPIOLineName);
174 
175         EXPECT_EQ(psu->isPresent(), false);
176         EXPECT_EQ(psu->isFaulted(), false);
177         EXPECT_EQ(psu->hasCommFault(), false);
178         EXPECT_EQ(psu->hasInputFault(), false);
179         EXPECT_EQ(psu->hasMFRFault(), false);
180         EXPECT_EQ(psu->hasVINUVFault(), false);
181         EXPECT_EQ(psu->hasVoutOVFault(), false);
182         EXPECT_EQ(psu->hasIoutOCFault(), false);
183         EXPECT_EQ(psu->hasVoutUVFault(), false);
184         EXPECT_EQ(psu->hasFanFault(), false);
185         EXPECT_EQ(psu->hasTempFault(), false);
186         EXPECT_EQ(psu->hasPgoodFault(), false);
187         EXPECT_EQ(psu->hasPSKillFault(), false);
188         EXPECT_EQ(psu->hasPS12VcsFault(), false);
189         EXPECT_EQ(psu->hasPSCS12VFault(), false);
190     }
191     catch (...)
192     {
193         ADD_FAILURE() << "Should not have caught exception.";
194     }
195 
196     // Test with valid arguments
197     // TODO: Using D-Bus inventory path for presence.
198     try
199     {
200         // FIXME: How do I get that presenceGPIO.read() in the startup to throw
201         // an exception?
202 
203         // EXPECT_CALL(mockedUtil, getPresence(_,
204         // StrEq(PSUInventoryPath)))
205         //    .Times(1);
206     }
207     catch (...)
208     {
209         ADD_FAILURE() << "Should not have caught exception.";
210     }
211 }
212 
213 TEST_F(PowerSupplyTests, Analyze)
214 {
215     auto bus = sdbusplus::bus::new_default();
216 
217     {
218         // If I default to reading the GPIO, I will NOT expect a call to
219         // getPresence().
220 
221         PowerSupply psu{bus,  PSUInventoryPath, 4,
222                         0x69, "ibm-cffps",      PSUGPIOLineName};
223         MockedGPIOInterface* mockPresenceGPIO =
224             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
225         EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0));
226 
227         psu.analyze();
228         // By default, nothing should change.
229         EXPECT_EQ(psu.isPresent(), false);
230         EXPECT_EQ(psu.isFaulted(), false);
231         EXPECT_EQ(psu.hasInputFault(), false);
232         EXPECT_EQ(psu.hasMFRFault(), false);
233         EXPECT_EQ(psu.hasVINUVFault(), false);
234         EXPECT_EQ(psu.hasCommFault(), false);
235         EXPECT_EQ(psu.hasVoutOVFault(), false);
236         EXPECT_EQ(psu.hasIoutOCFault(), false);
237         EXPECT_EQ(psu.hasVoutUVFault(), false);
238         EXPECT_EQ(psu.hasFanFault(), false);
239         EXPECT_EQ(psu.hasTempFault(), false);
240         EXPECT_EQ(psu.hasPgoodFault(), false);
241         EXPECT_EQ(psu.hasPSKillFault(), false);
242         EXPECT_EQ(psu.hasPS12VcsFault(), false);
243         EXPECT_EQ(psu.hasPSCS12VFault(), false);
244     }
245 
246     PowerSupply psu2{bus,  PSUInventoryPath, 5,
247                      0x6a, "ibm-cffps",      PSUGPIOLineName};
248     // In order to get the various faults tested, the power supply needs to
249     // be present in order to read from the PMBus device(s).
250     MockedGPIOInterface* mockPresenceGPIO2 =
251         static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO());
252     // Always return 1 to indicate present.
253     // Each analyze() call will trigger a read of the presence GPIO.
254     EXPECT_CALL(*mockPresenceGPIO2, read()).WillRepeatedly(Return(1));
255     EXPECT_EQ(psu2.isPresent(), false);
256 
257     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus());
258     setMissingToPresentExpects(mockPMBus, mockedUtil);
259 
260     // STATUS_WORD INPUT fault.
261     {
262         // Start with STATUS_WORD 0x0000. Powered on, no faults.
263         // Set expectations for a no fault
264         PMBusExpectations expectations;
265         setPMBusExpectations(mockPMBus, expectations);
266         // After reading STATUS_WORD, etc., there will be a READ_VIN check.
267         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
268             .Times(1)
269             .WillOnce(Return("206000"));
270         psu2.analyze();
271         EXPECT_EQ(psu2.isPresent(), true);
272         EXPECT_EQ(psu2.isFaulted(), false);
273         EXPECT_EQ(psu2.hasInputFault(), false);
274         EXPECT_EQ(psu2.hasMFRFault(), false);
275         EXPECT_EQ(psu2.hasVINUVFault(), false);
276         EXPECT_EQ(psu2.hasCommFault(), false);
277         EXPECT_EQ(psu2.hasVoutOVFault(), false);
278         EXPECT_EQ(psu2.hasIoutOCFault(), false);
279         EXPECT_EQ(psu2.hasVoutUVFault(), false);
280         EXPECT_EQ(psu2.hasFanFault(), false);
281         EXPECT_EQ(psu2.hasTempFault(), false);
282         EXPECT_EQ(psu2.hasPgoodFault(), false);
283         EXPECT_EQ(psu2.hasPSKillFault(), false);
284         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
285         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
286 
287         // Update expectations for STATUS_WORD input fault/warn
288         // STATUS_INPUT fault bits ... on.
289         expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
290         // IIN_OC fault.
291         expectations.statusInputValue = 0x04;
292 
293         for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
294         {
295             setPMBusExpectations(mockPMBus, expectations);
296             EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
297                 .Times(1)
298                 .WillOnce(Return("207000"));
299             psu2.analyze();
300             EXPECT_EQ(psu2.isPresent(), true);
301             // Should not be faulted until it reaches the deglitch limit.
302             EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
303             EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT);
304             EXPECT_EQ(psu2.hasMFRFault(), false);
305             EXPECT_EQ(psu2.hasVINUVFault(), false);
306             EXPECT_EQ(psu2.hasCommFault(), false);
307             EXPECT_EQ(psu2.hasVoutOVFault(), false);
308             EXPECT_EQ(psu2.hasIoutOCFault(), false);
309             EXPECT_EQ(psu2.hasVoutUVFault(), false);
310             EXPECT_EQ(psu2.hasFanFault(), false);
311             EXPECT_EQ(psu2.hasTempFault(), false);
312             EXPECT_EQ(psu2.hasPgoodFault(), false);
313             EXPECT_EQ(psu2.hasPSKillFault(), false);
314             EXPECT_EQ(psu2.hasPS12VcsFault(), false);
315             EXPECT_EQ(psu2.hasPSCS12VFault(), false);
316         }
317     }
318 
319     EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
320     EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
321         .Times(1)
322         .WillOnce(Return(1));
323     psu2.clearFaults();
324 
325     // STATUS_WORD INPUT/UV fault.
326     {
327         // First need it to return good status, then the fault
328         PMBusExpectations expectations;
329         setPMBusExpectations(mockPMBus, expectations);
330         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
331             .Times(1)
332             .WillOnce(Return("208000"));
333         psu2.analyze();
334         EXPECT_EQ(psu2.isFaulted(), false);
335         EXPECT_EQ(psu2.hasInputFault(), false);
336         // Now set fault bits in STATUS_WORD
337         expectations.statusWordValue =
338             (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT);
339         // STATUS_INPUT fault bits ... on.
340         expectations.statusInputValue = 0x18;
341         for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
342         {
343             setPMBusExpectations(mockPMBus, expectations);
344             // Input/UV fault, so voltage should read back low.
345             EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
346                 .Times(1)
347                 .WillOnce(Return("19123"));
348             psu2.analyze();
349             EXPECT_EQ(psu2.isPresent(), true);
350             // Only faulted if hit deglitch limit
351             EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
352             EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT);
353             EXPECT_EQ(psu2.hasVINUVFault(), x >= DEGLITCH_LIMIT);
354             EXPECT_EQ(psu2.hasMFRFault(), false);
355             EXPECT_EQ(psu2.hasCommFault(), false);
356             EXPECT_EQ(psu2.hasVoutOVFault(), false);
357             EXPECT_EQ(psu2.hasIoutOCFault(), false);
358             EXPECT_EQ(psu2.hasVoutUVFault(), false);
359             EXPECT_EQ(psu2.hasFanFault(), false);
360             EXPECT_EQ(psu2.hasTempFault(), false);
361             EXPECT_EQ(psu2.hasPgoodFault(), false);
362             EXPECT_EQ(psu2.hasPSKillFault(), false);
363             EXPECT_EQ(psu2.hasPS12VcsFault(), false);
364             EXPECT_EQ(psu2.hasPSCS12VFault(), false);
365         }
366         // Turning VIN_UV fault off causes clearing of faults, causing read of
367         // in1_input as an attempt to get CLEAR_FAULTS called.
368         expectations.statusWordValue = 0;
369         setPMBusExpectations(mockPMBus, expectations);
370         // The call to read the voltage
371         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
372             .Times(1)
373             .WillOnce(Return("209000"));
374         // The call to clear VIN_UV/Off fault(s)
375         EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
376             .Times(1)
377             .WillOnce(Return(1));
378         psu2.analyze();
379         // Should remain present, no longer be faulted, no input fault, no
380         // VIN_UV fault. Nothing else should change.
381         EXPECT_EQ(psu2.isPresent(), true);
382         EXPECT_EQ(psu2.isFaulted(), false);
383         EXPECT_EQ(psu2.hasInputFault(), false);
384         EXPECT_EQ(psu2.hasVINUVFault(), false);
385     }
386 
387     EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
388     EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
389         .Times(1)
390         .WillOnce(Return(1));
391     psu2.clearFaults();
392 
393     // STATUS_WORD MFR fault.
394     {
395         // First need it to return good status, then the fault
396         PMBusExpectations expectations;
397         setPMBusExpectations(mockPMBus, expectations);
398         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
399             .Times(1)
400             .WillOnce(Return("210000"));
401         psu2.analyze();
402         // Now STATUS_WORD with MFR fault bit on.
403         expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
404         // STATUS_MFR bits on.
405         expectations.statusMFRValue = 0xFF;
406 
407         for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
408         {
409             setPMBusExpectations(mockPMBus, expectations);
410             EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
411                 .Times(1)
412                 .WillOnce(Return("211000"));
413             psu2.analyze();
414             EXPECT_EQ(psu2.isPresent(), true);
415             EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
416             EXPECT_EQ(psu2.hasInputFault(), false);
417             EXPECT_EQ(psu2.hasMFRFault(), x >= DEGLITCH_LIMIT);
418             EXPECT_EQ(psu2.hasPSKillFault(), x >= DEGLITCH_LIMIT);
419             EXPECT_EQ(psu2.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
420             EXPECT_EQ(psu2.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
421             EXPECT_EQ(psu2.hasVINUVFault(), false);
422             EXPECT_EQ(psu2.hasCommFault(), false);
423             EXPECT_EQ(psu2.hasVoutOVFault(), false);
424             EXPECT_EQ(psu2.hasIoutOCFault(), false);
425             EXPECT_EQ(psu2.hasVoutUVFault(), false);
426             EXPECT_EQ(psu2.hasFanFault(), false);
427             EXPECT_EQ(psu2.hasTempFault(), false);
428             EXPECT_EQ(psu2.hasPgoodFault(), false);
429         }
430     }
431 
432     EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
433     EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
434         .Times(1)
435         .WillOnce(Return(1));
436     psu2.clearFaults();
437 
438     // Temperature fault.
439     {
440         // First STATUS_WORD with no bits set, then with temperature fault.
441         PMBusExpectations expectations;
442         setPMBusExpectations(mockPMBus, expectations);
443         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
444             .Times(1)
445             .WillOnce(Return("212000"));
446         psu2.analyze();
447         // STATUS_WORD with temperature fault bit on.
448         expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
449         // STATUS_TEMPERATURE with fault bit(s) on.
450         expectations.statusTempValue = 0x10;
451         for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
452         {
453             setPMBusExpectations(mockPMBus, expectations);
454             EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
455                 .Times(1)
456                 .WillOnce(Return("213000"));
457             psu2.analyze();
458             EXPECT_EQ(psu2.isPresent(), true);
459             EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
460             EXPECT_EQ(psu2.hasInputFault(), false);
461             EXPECT_EQ(psu2.hasMFRFault(), false);
462             EXPECT_EQ(psu2.hasVINUVFault(), false);
463             EXPECT_EQ(psu2.hasCommFault(), false);
464             EXPECT_EQ(psu2.hasVoutOVFault(), false);
465             EXPECT_EQ(psu2.hasIoutOCFault(), false);
466             EXPECT_EQ(psu2.hasVoutUVFault(), false);
467             EXPECT_EQ(psu2.hasFanFault(), false);
468             EXPECT_EQ(psu2.hasTempFault(), x >= DEGLITCH_LIMIT);
469             EXPECT_EQ(psu2.hasPgoodFault(), false);
470             EXPECT_EQ(psu2.hasPSKillFault(), false);
471             EXPECT_EQ(psu2.hasPS12VcsFault(), false);
472             EXPECT_EQ(psu2.hasPSCS12VFault(), false);
473         }
474     }
475 
476     EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
477     EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
478         .Times(1)
479         .WillOnce(Return(1));
480     psu2.clearFaults();
481 
482     // CML fault
483     {
484         // First STATUS_WORD wit no bits set, then with CML fault.
485         PMBusExpectations expectations;
486         setPMBusExpectations(mockPMBus, expectations);
487         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
488             .Times(1)
489             .WillOnce(Return("214000"));
490         psu2.analyze();
491         // STATUS_WORD with CML fault bit on.
492         expectations.statusWordValue = (status_word::CML_FAULT);
493         // Turn on STATUS_CML fault bit(s)
494         expectations.statusCMLValue = 0xFF;
495         for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
496         {
497             setPMBusExpectations(mockPMBus, expectations);
498             EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
499                 .Times(1)
500                 .WillOnce(Return("215000"));
501             psu2.analyze();
502             EXPECT_EQ(psu2.isPresent(), true);
503             EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
504             EXPECT_EQ(psu2.hasCommFault(), x >= DEGLITCH_LIMIT);
505             EXPECT_EQ(psu2.hasInputFault(), false);
506             EXPECT_EQ(psu2.hasMFRFault(), false);
507             EXPECT_EQ(psu2.hasVINUVFault(), false);
508             EXPECT_EQ(psu2.hasVoutOVFault(), false);
509             EXPECT_EQ(psu2.hasIoutOCFault(), false);
510             EXPECT_EQ(psu2.hasVoutUVFault(), false);
511             EXPECT_EQ(psu2.hasFanFault(), false);
512             EXPECT_EQ(psu2.hasTempFault(), false);
513             EXPECT_EQ(psu2.hasPgoodFault(), false);
514             EXPECT_EQ(psu2.hasPSKillFault(), false);
515             EXPECT_EQ(psu2.hasPS12VcsFault(), false);
516             EXPECT_EQ(psu2.hasPSCS12VFault(), false);
517         }
518     }
519 
520     EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
521     EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
522         .Times(1)
523         .WillOnce(Return(1));
524     psu2.clearFaults();
525 
526     // VOUT_OV_FAULT fault
527     {
528         // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault.
529         PMBusExpectations expectations;
530         setPMBusExpectations(mockPMBus, expectations);
531         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
532             .Times(1)
533             .WillOnce(Return("216000"));
534         psu2.analyze();
535         // STATUS_WORD with VOUT/VOUT_OV fault.
536         expectations.statusWordValue =
537             ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT));
538         // Turn on STATUS_VOUT fault bit(s)
539         expectations.statusVOUTValue = 0xA0;
540         for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
541         {
542             // STATUS_TEMPERATURE don't care (default)
543             setPMBusExpectations(mockPMBus, expectations);
544             EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
545                 .Times(1)
546                 .WillOnce(Return("217000"));
547             psu2.analyze();
548             EXPECT_EQ(psu2.isPresent(), true);
549             EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
550             EXPECT_EQ(psu2.hasInputFault(), false);
551             EXPECT_EQ(psu2.hasMFRFault(), false);
552             EXPECT_EQ(psu2.hasVINUVFault(), false);
553             EXPECT_EQ(psu2.hasCommFault(), false);
554             EXPECT_EQ(psu2.hasVoutOVFault(), x >= DEGLITCH_LIMIT);
555             EXPECT_EQ(psu2.hasVoutUVFault(), false);
556             EXPECT_EQ(psu2.hasIoutOCFault(), false);
557             EXPECT_EQ(psu2.hasFanFault(), false);
558             EXPECT_EQ(psu2.hasTempFault(), false);
559             EXPECT_EQ(psu2.hasPgoodFault(), false);
560             EXPECT_EQ(psu2.hasPSKillFault(), false);
561             EXPECT_EQ(psu2.hasPS12VcsFault(), false);
562             EXPECT_EQ(psu2.hasPSCS12VFault(), false);
563         }
564     }
565 
566     // IOUT_OC_FAULT fault
567     {
568         // First STATUS_WORD with no bits set, then with IOUT_OC fault.
569         PMBusExpectations expectations;
570         setPMBusExpectations(mockPMBus, expectations);
571         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
572             .Times(1)
573             .WillOnce(Return("218000"));
574         psu2.analyze();
575         // STATUS_WORD with IOUT_OC fault.
576         expectations.statusWordValue = status_word::IOUT_OC_FAULT;
577         // Turn on STATUS_IOUT fault bit(s)
578         expectations.statusIOUTValue = 0x88;
579         for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
580         {
581             setPMBusExpectations(mockPMBus, expectations);
582             EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
583                 .Times(1)
584                 .WillOnce(Return("219000"));
585             psu2.analyze();
586             EXPECT_EQ(psu2.isPresent(), true);
587             EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
588             EXPECT_EQ(psu2.hasInputFault(), false);
589             EXPECT_EQ(psu2.hasMFRFault(), false);
590             EXPECT_EQ(psu2.hasVINUVFault(), false);
591             EXPECT_EQ(psu2.hasCommFault(), false);
592             EXPECT_EQ(psu2.hasVoutOVFault(), false);
593             EXPECT_EQ(psu2.hasIoutOCFault(), x >= DEGLITCH_LIMIT);
594             EXPECT_EQ(psu2.hasVoutUVFault(), false);
595             EXPECT_EQ(psu2.hasFanFault(), false);
596             EXPECT_EQ(psu2.hasTempFault(), false);
597             EXPECT_EQ(psu2.hasPgoodFault(), false);
598             EXPECT_EQ(psu2.hasPSKillFault(), false);
599             EXPECT_EQ(psu2.hasPS12VcsFault(), false);
600             EXPECT_EQ(psu2.hasPSCS12VFault(), false);
601         }
602     }
603 
604     // VOUT_UV_FAULT
605     {
606         // First STATUS_WORD with no bits set, then with VOUT fault.
607         PMBusExpectations expectations;
608         setPMBusExpectations(mockPMBus, expectations);
609         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
610             .Times(1)
611             .WillOnce(Return("220000"));
612         psu2.analyze();
613         // Change STATUS_WORD to indicate VOUT fault.
614         expectations.statusWordValue = (status_word::VOUT_FAULT);
615         // Turn on STATUS_VOUT fault bit(s)
616         expectations.statusVOUTValue = 0x30;
617         for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
618         {
619             setPMBusExpectations(mockPMBus, expectations);
620             EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
621                 .Times(1)
622                 .WillOnce(Return("221000"));
623             psu2.analyze();
624             EXPECT_EQ(psu2.isPresent(), true);
625             EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
626             EXPECT_EQ(psu2.hasInputFault(), false);
627             EXPECT_EQ(psu2.hasMFRFault(), false);
628             EXPECT_EQ(psu2.hasVINUVFault(), false);
629             EXPECT_EQ(psu2.hasCommFault(), false);
630             EXPECT_EQ(psu2.hasVoutOVFault(), false);
631             EXPECT_EQ(psu2.hasIoutOCFault(), false);
632             EXPECT_EQ(psu2.hasVoutUVFault(), x >= DEGLITCH_LIMIT);
633             EXPECT_EQ(psu2.hasFanFault(), false);
634             EXPECT_EQ(psu2.hasTempFault(), false);
635             EXPECT_EQ(psu2.hasPgoodFault(), false);
636             EXPECT_EQ(psu2.hasPSKillFault(), false);
637             EXPECT_EQ(psu2.hasPS12VcsFault(), false);
638             EXPECT_EQ(psu2.hasPSCS12VFault(), false);
639         }
640     }
641 
642     // Fan fault
643     {
644         // First STATUS_WORD with no bits set, then with fan fault.
645         PMBusExpectations expectations;
646         setPMBusExpectations(mockPMBus, expectations);
647         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
648             .Times(1)
649             .WillOnce(Return("222000"));
650         psu2.analyze();
651         expectations.statusWordValue = (status_word::FAN_FAULT);
652         // STATUS_FANS_1_2 with fan 1 warning & fault bits on.
653         expectations.statusFans12Value = 0xA0;
654 
655         for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
656         {
657             setPMBusExpectations(mockPMBus, expectations);
658             EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
659                 .Times(1)
660                 .WillOnce(Return("223000"));
661             psu2.analyze();
662             EXPECT_EQ(psu2.isPresent(), true);
663             EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
664             EXPECT_EQ(psu2.hasFanFault(), x >= DEGLITCH_LIMIT);
665             EXPECT_EQ(psu2.hasInputFault(), false);
666             EXPECT_EQ(psu2.hasMFRFault(), false);
667             EXPECT_EQ(psu2.hasVINUVFault(), false);
668             EXPECT_EQ(psu2.hasCommFault(), false);
669             EXPECT_EQ(psu2.hasVoutOVFault(), false);
670             EXPECT_EQ(psu2.hasIoutOCFault(), false);
671             EXPECT_EQ(psu2.hasVoutUVFault(), false);
672             EXPECT_EQ(psu2.hasTempFault(), false);
673             EXPECT_EQ(psu2.hasPgoodFault(), false);
674             EXPECT_EQ(psu2.hasPSKillFault(), false);
675             EXPECT_EQ(psu2.hasPS12VcsFault(), false);
676             EXPECT_EQ(psu2.hasPSCS12VFault(), false);
677         }
678     }
679 
680     // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT.
681     {
682         // First STATUS_WORD with no bits set.
683         PMBusExpectations expectations;
684         setPMBusExpectations(mockPMBus, expectations);
685         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
686             .Times(1)
687             .WillOnce(Return("123000"));
688         psu2.analyze();
689         EXPECT_EQ(psu2.isFaulted(), false);
690         // POWER_GOOD# inactive, and OFF bit on.
691         expectations.statusWordValue =
692             ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF));
693         for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
694         {
695             // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and
696             // STATUS_TEMPERATURE: Don't care if bits set or not (defaults).
697             setPMBusExpectations(mockPMBus, expectations);
698             EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
699                 .Times(1)
700                 .WillOnce(Return("124000"));
701             psu2.analyze();
702             EXPECT_EQ(psu2.isPresent(), true);
703             EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
704             EXPECT_EQ(psu2.hasInputFault(), false);
705             EXPECT_EQ(psu2.hasMFRFault(), false);
706             EXPECT_EQ(psu2.hasVINUVFault(), false);
707             EXPECT_EQ(psu2.hasCommFault(), false);
708             EXPECT_EQ(psu2.hasVoutOVFault(), false);
709             EXPECT_EQ(psu2.hasVoutUVFault(), false);
710             EXPECT_EQ(psu2.hasIoutOCFault(), false);
711             EXPECT_EQ(psu2.hasFanFault(), false);
712             EXPECT_EQ(psu2.hasTempFault(), false);
713             EXPECT_EQ(psu2.hasPgoodFault(), x >= DEGLITCH_LIMIT);
714         }
715     }
716 
717     // TODO: ReadFailure
718 }
719 
720 TEST_F(PowerSupplyTests, OnOffConfig)
721 {
722     auto bus = sdbusplus::bus::new_default();
723     uint8_t data = 0x15;
724 
725     // Test where PSU is NOT present
726     try
727     {
728         // Assume GPIO presence, not inventory presence?
729         EXPECT_CALL(mockedUtil, setAvailable(_, _, _)).Times(0);
730         PowerSupply psu{bus,  PSUInventoryPath, 4,
731                         0x69, "ibm-cffps",      PSUGPIOLineName};
732 
733         MockedGPIOInterface* mockPresenceGPIO =
734             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
735         ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0));
736         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
737         // Constructor should set initial presence, default read returns 0.
738         // If it is not present, I should not be trying to write to it.
739         EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0);
740         psu.onOffConfig(data);
741     }
742     catch (...)
743     {}
744 
745     // Test where PSU is present
746     try
747     {
748         // Assume GPIO presence, not inventory presence?
749         EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
750         PowerSupply psu{bus,  PSUInventoryPath, 5,
751                         0x6a, "ibm-cffps",      PSUGPIOLineName};
752         MockedGPIOInterface* mockPresenceGPIO =
753             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
754         // There will potentially be multiple calls, we want it to continue
755         // returning 1 for the GPIO read to keep the power supply present.
756         EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
757         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
758         setMissingToPresentExpects(mockPMBus, mockedUtil);
759         // If I am calling analyze(), I should probably give it good data.
760         // STATUS_WORD 0x0000 is powered on, no faults.
761         PMBusExpectations expectations;
762         setPMBusExpectations(mockPMBus, expectations);
763         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
764             .Times(1)
765             .WillOnce(Return("205000"));
766         psu.analyze();
767         // I definitely should be writting ON_OFF_CONFIG if I call the function
768         EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, ElementsAre(0x15),
769                                            Type::HwmonDeviceDebug))
770             .Times(1);
771         psu.onOffConfig(data);
772     }
773     catch (...)
774     {}
775 }
776 
777 TEST_F(PowerSupplyTests, ClearFaults)
778 {
779     auto bus = sdbusplus::bus::new_default();
780     PowerSupply psu{bus,  PSUInventoryPath, 13,
781                     0x68, "ibm-cffps",      PSUGPIOLineName};
782     MockedGPIOInterface* mockPresenceGPIO =
783         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
784     // Always return 1 to indicate present.
785     // Each analyze() call will trigger a read of the presence GPIO.
786     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
787     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
788     setMissingToPresentExpects(mockPMBus, mockedUtil);
789     // STATUS_WORD 0x0000 is powered on, no faults.
790     PMBusExpectations expectations;
791     setPMBusExpectations(mockPMBus, expectations);
792     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
793         .Times(1)
794         .WillOnce(Return("207000"));
795     psu.analyze();
796     EXPECT_EQ(psu.isPresent(), true);
797     EXPECT_EQ(psu.isFaulted(), false);
798     EXPECT_EQ(psu.hasInputFault(), false);
799     EXPECT_EQ(psu.hasMFRFault(), false);
800     EXPECT_EQ(psu.hasVINUVFault(), false);
801     EXPECT_EQ(psu.hasCommFault(), false);
802     EXPECT_EQ(psu.hasVoutOVFault(), false);
803     EXPECT_EQ(psu.hasIoutOCFault(), false);
804     EXPECT_EQ(psu.hasVoutUVFault(), false);
805     EXPECT_EQ(psu.hasFanFault(), false);
806     EXPECT_EQ(psu.hasTempFault(), false);
807     EXPECT_EQ(psu.hasPgoodFault(), false);
808     EXPECT_EQ(psu.hasPSKillFault(), false);
809     EXPECT_EQ(psu.hasPS12VcsFault(), false);
810     EXPECT_EQ(psu.hasPSCS12VFault(), false);
811 
812     // STATUS_WORD with fault bits galore!
813     expectations.statusWordValue = 0xFFFF;
814     // STATUS_INPUT with fault bits on.
815     expectations.statusInputValue = 0xFF;
816     // STATUS_MFR_SPEFIC with bits on.
817     expectations.statusMFRValue = 0xFF;
818     // STATUS_CML with bits on.
819     expectations.statusCMLValue = 0xFF;
820     // STATUS_VOUT with bits on.
821     expectations.statusVOUTValue = 0xFF;
822     // STATUS_IOUT with bits on.
823     expectations.statusIOUTValue = 0xFF;
824     // STATUS_FANS_1_2 with bits on.
825     expectations.statusFans12Value = 0xFF;
826     // STATUS_TEMPERATURE with bits on.
827     expectations.statusTempValue = 0xFF;
828 
829     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
830     {
831         setPMBusExpectations(mockPMBus, expectations);
832         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
833             .Times(1)
834             .WillOnce(Return("0"));
835         if (x == DEGLITCH_LIMIT)
836         {
837             EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
838         }
839         psu.analyze();
840         EXPECT_EQ(psu.isPresent(), true);
841         // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
842         // Rely on HasVoutUVFault() to verify this sets and clears.
843         EXPECT_EQ(psu.hasVoutUVFault(), false);
844         // All faults are deglitched up to DEGLITCH_LIMIT
845         EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT);
846         EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT);
847         EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT);
848         EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT);
849         EXPECT_EQ(psu.hasCommFault(), x >= DEGLITCH_LIMIT);
850         EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT);
851         EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT);
852         EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT);
853         EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT);
854         EXPECT_EQ(psu.hasPgoodFault(), x >= DEGLITCH_LIMIT);
855         EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT);
856         EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
857         EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
858     }
859 
860     EXPECT_CALL(mockPMBus, read(READ_VIN, _, _))
861         .Times(1)
862         .WillOnce(Return(207000));
863     // Clearing VIN_UV fault via in1_lcrit_alarm
864     EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
865         .Times(1)
866         .WillOnce(Return(1));
867     EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
868     psu.clearFaults();
869     EXPECT_EQ(psu.isPresent(), true);
870     EXPECT_EQ(psu.isFaulted(), false);
871     EXPECT_EQ(psu.hasInputFault(), false);
872     EXPECT_EQ(psu.hasMFRFault(), false);
873     EXPECT_EQ(psu.hasVINUVFault(), false);
874     EXPECT_EQ(psu.hasCommFault(), false);
875     EXPECT_EQ(psu.hasVoutOVFault(), false);
876     EXPECT_EQ(psu.hasIoutOCFault(), false);
877     EXPECT_EQ(psu.hasVoutUVFault(), false);
878     EXPECT_EQ(psu.hasFanFault(), false);
879     EXPECT_EQ(psu.hasTempFault(), false);
880     EXPECT_EQ(psu.hasPgoodFault(), false);
881     EXPECT_EQ(psu.hasPSKillFault(), false);
882     EXPECT_EQ(psu.hasPS12VcsFault(), false);
883     EXPECT_EQ(psu.hasPSCS12VFault(), false);
884 
885     // Faults clear on READ_VIN 0 -> !0
886     // STATUS_WORD with fault bits galore!
887     expectations.statusWordValue = 0xFFFF;
888     // STATUS_INPUT with fault bits on.
889     expectations.statusInputValue = 0xFF;
890     // STATUS_MFR_SPEFIC with bits on.
891     expectations.statusMFRValue = 0xFF;
892     // STATUS_CML with bits on.
893     expectations.statusCMLValue = 0xFF;
894     // STATUS_VOUT with bits on.
895     expectations.statusVOUTValue = 0xFF;
896     // STATUS_IOUT with bits on.
897     expectations.statusIOUTValue = 0xFF;
898     // STATUS_FANS_1_2 with bits on.
899     expectations.statusFans12Value = 0xFF;
900     // STATUS_TEMPERATURE with bits on.
901     expectations.statusTempValue = 0xFF;
902 
903     // All faults degltiched now. Check for false before limit above.
904     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
905     {
906         setPMBusExpectations(mockPMBus, expectations);
907         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
908             .Times(1)
909             .WillOnce(Return("0"));
910         if (x == DEGLITCH_LIMIT)
911         {
912             EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
913         }
914         psu.analyze();
915     }
916 
917     EXPECT_EQ(psu.isPresent(), true);
918     EXPECT_EQ(psu.isFaulted(), true);
919     EXPECT_EQ(psu.hasInputFault(), true);
920     EXPECT_EQ(psu.hasMFRFault(), true);
921     EXPECT_EQ(psu.hasVINUVFault(), true);
922     // True due to CML fault bits on
923     EXPECT_EQ(psu.hasCommFault(), true);
924     EXPECT_EQ(psu.hasVoutOVFault(), true);
925     EXPECT_EQ(psu.hasIoutOCFault(), true);
926     // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
927     // Rely on HasVoutUVFault() to verify this sets and clears.
928     EXPECT_EQ(psu.hasVoutUVFault(), false);
929     EXPECT_EQ(psu.hasFanFault(), true);
930     EXPECT_EQ(psu.hasTempFault(), true);
931     EXPECT_EQ(psu.hasPgoodFault(), true);
932     EXPECT_EQ(psu.hasPSKillFault(), true);
933     EXPECT_EQ(psu.hasPS12VcsFault(), true);
934     EXPECT_EQ(psu.hasPSCS12VFault(), true);
935     // STATUS_WORD with INPUT/VIN_UV fault bits off.
936     expectations.statusWordValue = 0xDFF7;
937     // STATUS_INPUT with VIN_UV_WARNING, VIN_UV_FAULT, and Unit Off For
938     // Insufficient Input Voltage bits off.
939     expectations.statusInputValue = 0xC7;
940     setPMBusExpectations(mockPMBus, expectations);
941     // READ_VIN back in range.
942     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
943         .Times(1)
944         .WillOnce(Return("206000"));
945     // VIN_UV cleared via in1_lcrit_alarm when voltage back in range.
946     EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
947         .Times(1)
948         .WillOnce(Return(1));
949     psu.analyze();
950     // We only cleared the VIN_UV and OFF faults.
951     EXPECT_EQ(psu.isPresent(), true);
952     EXPECT_EQ(psu.isFaulted(), true);
953     EXPECT_EQ(psu.hasInputFault(), false);
954     EXPECT_EQ(psu.hasMFRFault(), true);
955     EXPECT_EQ(psu.hasVINUVFault(), false);
956     EXPECT_EQ(psu.hasCommFault(), true);
957     EXPECT_EQ(psu.hasVoutOVFault(), true);
958     EXPECT_EQ(psu.hasIoutOCFault(), true);
959     EXPECT_EQ(psu.hasVoutUVFault(), false);
960     EXPECT_EQ(psu.hasFanFault(), true);
961     EXPECT_EQ(psu.hasTempFault(), true);
962     EXPECT_EQ(psu.hasPgoodFault(), true);
963     EXPECT_EQ(psu.hasPSKillFault(), true);
964     EXPECT_EQ(psu.hasPS12VcsFault(), true);
965     EXPECT_EQ(psu.hasPSCS12VFault(), true);
966 
967     // All faults cleared
968     expectations = {0};
969     setPMBusExpectations(mockPMBus, expectations);
970     // READ_VIN back in range.
971     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
972         .Times(1)
973         .WillOnce(Return("206000"));
974     EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
975     psu.analyze();
976     EXPECT_EQ(psu.isPresent(), true);
977     EXPECT_EQ(psu.isFaulted(), false);
978     EXPECT_EQ(psu.hasInputFault(), false);
979     EXPECT_EQ(psu.hasMFRFault(), false);
980     EXPECT_EQ(psu.hasVINUVFault(), false);
981     EXPECT_EQ(psu.hasCommFault(), false);
982     EXPECT_EQ(psu.hasVoutOVFault(), false);
983     EXPECT_EQ(psu.hasIoutOCFault(), false);
984     EXPECT_EQ(psu.hasVoutUVFault(), false);
985     EXPECT_EQ(psu.hasFanFault(), false);
986     EXPECT_EQ(psu.hasTempFault(), false);
987     EXPECT_EQ(psu.hasPgoodFault(), false);
988     EXPECT_EQ(psu.hasPSKillFault(), false);
989     EXPECT_EQ(psu.hasPS12VcsFault(), false);
990     EXPECT_EQ(psu.hasPSCS12VFault(), false);
991 
992     // TODO: Faults clear on missing/present?
993 }
994 
995 TEST_F(PowerSupplyTests, UpdateInventory)
996 {
997     auto bus = sdbusplus::bus::new_default();
998 
999     try
1000     {
1001         PowerSupply psu{bus,  PSUInventoryPath, 3,
1002                         0x68, "ibm-cffps",      PSUGPIOLineName};
1003         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1004         // If it is not present, I should not be trying to read a string
1005         EXPECT_CALL(mockPMBus, readString(_, _)).Times(0);
1006         psu.updateInventory();
1007     }
1008     catch (...)
1009     {
1010         ADD_FAILURE() << "Should not have caught exception.";
1011     }
1012 
1013     try
1014     {
1015         PowerSupply psu{bus,  PSUInventoryPath, 13,
1016                         0x69, "ibm-cffps",      PSUGPIOLineName};
1017         MockedGPIOInterface* mockPresenceGPIO =
1018             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1019         // GPIO read return 1 to indicate present.
1020         EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
1021         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1022         setMissingToPresentExpects(mockPMBus, mockedUtil);
1023         // STATUS_WORD 0x0000 is powered on, no faults.
1024         PMBusExpectations expectations;
1025         setPMBusExpectations(mockPMBus, expectations);
1026         // Call to analyze will read voltage, trigger clear faults for 0 to
1027         // within range.
1028         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1029             .Times(1)
1030             .WillOnce(Return("123456"));
1031         psu.analyze();
1032         EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return(""));
1033         psu.updateInventory();
1034 
1035 #if IBM_VPD
1036         EXPECT_CALL(mockPMBus, readString(_, _))
1037             .WillOnce(Return("CCIN"))
1038             .WillOnce(Return("PN3456"))
1039             .WillOnce(Return("FN3456"))
1040             .WillOnce(Return("HEADER"))
1041             .WillOnce(Return("SN3456"))
1042             .WillOnce(Return("FW3456"));
1043 #endif
1044         psu.updateInventory();
1045         // TODO: D-Bus mocking to verify values stored on D-Bus (???)
1046     }
1047     catch (...)
1048     {
1049         ADD_FAILURE() << "Should not have caught exception.";
1050     }
1051 }
1052 
1053 TEST_F(PowerSupplyTests, IsPresent)
1054 {
1055     auto bus = sdbusplus::bus::new_default();
1056 
1057     PowerSupply psu{bus,  PSUInventoryPath, 3,
1058                     0x68, "ibm-cffps",      PSUGPIOLineName};
1059     MockedGPIOInterface* mockPresenceGPIO =
1060         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1061     EXPECT_EQ(psu.isPresent(), false);
1062 
1063     // Change GPIO read to return 1 to indicate present.
1064     EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
1065     // Call to analyze() will update to present, that will trigger updating
1066     // to the correct/latest HWMON directory, in case it changes.
1067     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1068     setMissingToPresentExpects(mockPMBus, mockedUtil);
1069     // Call to analyze things will trigger read of STATUS_WORD and READ_VIN.
1070     // Default expectations will be on, no faults.
1071     PMBusExpectations expectations;
1072     setPMBusExpectations(mockPMBus, expectations);
1073     // Give it an input voltage in the 100-volt range.
1074     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1075         .Times(1)
1076         .WillOnce(Return("123456"));
1077     EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
1078     psu.analyze();
1079     EXPECT_EQ(psu.isPresent(), true);
1080 }
1081 
1082 TEST_F(PowerSupplyTests, IsFaulted)
1083 {
1084     auto bus = sdbusplus::bus::new_default();
1085 
1086     PowerSupply psu{bus,  PSUInventoryPath, 11,
1087                     0x6f, "ibm-cffps",      PSUGPIOLineName};
1088     MockedGPIOInterface* mockPresenceGPIO =
1089         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1090     // Always return 1 to indicate present.
1091     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1092     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1093     setMissingToPresentExpects(mockPMBus, mockedUtil);
1094     // Call to analyze things will trigger read of STATUS_WORD and READ_VIN.
1095     // Default expectations will be on, no faults.
1096     PMBusExpectations expectations;
1097     setPMBusExpectations(mockPMBus, expectations);
1098     // Give it an input voltage in the 100-volt range.
1099     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1100         .Times(1)
1101         .WillOnce(Return("124680"));
1102     psu.analyze();
1103     EXPECT_EQ(psu.isFaulted(), false);
1104     // STATUS_WORD with fault bits on.
1105     expectations.statusWordValue = 0xFFFF;
1106     // STATUS_INPUT with fault bits on.
1107     expectations.statusInputValue = 0xFF;
1108     // STATUS_MFR_SPECIFIC with faults bits on.
1109     expectations.statusMFRValue = 0xFF;
1110     // STATUS_CML with faults bits on.
1111     expectations.statusCMLValue = 0xFF;
1112     // STATUS_VOUT with fault bits on.
1113     expectations.statusVOUTValue = 0xFF;
1114     // STATUS_IOUT with fault bits on.
1115     expectations.statusIOUTValue = 0xFF;
1116     // STATUS_FANS_1_2 with bits on.
1117     expectations.statusFans12Value = 0xFF;
1118     // STATUS_TEMPERATURE with fault bits on.
1119     expectations.statusTempValue = 0xFF;
1120     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1121     {
1122         setPMBusExpectations(mockPMBus, expectations);
1123         // Also get another read of READ_VIN, faulted, so not in 100-volt range
1124         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1125             .Times(1)
1126             .WillOnce(Return("19000"));
1127         if (x == DEGLITCH_LIMIT)
1128         {
1129             EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1130         }
1131         psu.analyze();
1132         EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT);
1133     }
1134 }
1135 
1136 TEST_F(PowerSupplyTests, HasInputFault)
1137 {
1138     auto bus = sdbusplus::bus::new_default();
1139 
1140     PowerSupply psu{bus,  PSUInventoryPath, 3,
1141                     0x68, "ibm-cffps",      PSUGPIOLineName};
1142     MockedGPIOInterface* mockPresenceGPIO =
1143         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1144     // Always return 1 to indicate present.
1145     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1146     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1147     setMissingToPresentExpects(mockPMBus, mockedUtil);
1148     // STATUS_WORD 0x0000 is powered on, no faults.
1149     PMBusExpectations expectations;
1150     setPMBusExpectations(mockPMBus, expectations);
1151     // Analyze call will also need good READ_VIN value to check.
1152     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1153         .Times(1)
1154         .WillOnce(Return("201100"));
1155     psu.analyze();
1156     EXPECT_EQ(psu.hasInputFault(), false);
1157     // STATUS_WORD with input fault/warn on.
1158     expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
1159     // STATUS_INPUT with an input fault bit on.
1160     expectations.statusInputValue = 0x80;
1161     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1162     {
1163         setPMBusExpectations(mockPMBus, expectations);
1164         // Analyze call will also need good READ_VIN value to check.
1165         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1166             .Times(1)
1167             .WillOnce(Return("201200"));
1168         if (x == DEGLITCH_LIMIT)
1169         {
1170             EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1171         }
1172         psu.analyze();
1173         EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT);
1174     }
1175     // STATUS_WORD with no bits on.
1176     expectations.statusWordValue = 0;
1177     setPMBusExpectations(mockPMBus, expectations);
1178     // Analyze call will also need good READ_VIN value to check.
1179     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1180         .Times(1)
1181         .WillOnce(Return("201300"));
1182     EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
1183     psu.analyze();
1184     EXPECT_EQ(psu.hasInputFault(), false);
1185 }
1186 
1187 TEST_F(PowerSupplyTests, HasMFRFault)
1188 {
1189     auto bus = sdbusplus::bus::new_default();
1190 
1191     PowerSupply psu{bus,  PSUInventoryPath, 3,
1192                     0x68, "ibm-cffps",      PSUGPIOLineName};
1193     MockedGPIOInterface* mockPresenceGPIO =
1194         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1195     // Always return 1 to indicate present.
1196     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1197     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1198     setMissingToPresentExpects(mockPMBus, mockedUtil);
1199     // First return STATUS_WORD with no bits on.
1200     // STATUS_WORD 0x0000 is powered on, no faults.
1201     PMBusExpectations expectations;
1202     setPMBusExpectations(mockPMBus, expectations);
1203     // Analyze call will also need good READ_VIN value to check.
1204     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1205         .Times(1)
1206         .WillOnce(Return("202100"));
1207     psu.analyze();
1208     EXPECT_EQ(psu.hasMFRFault(), false);
1209     // Next return STATUS_WORD with MFR fault bit on.
1210     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1211     // STATUS_MFR_SPEFIC with bit(s) on.
1212     expectations.statusMFRValue = 0xFF;
1213     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1214     {
1215         setPMBusExpectations(mockPMBus, expectations);
1216         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1217             .Times(1)
1218             .WillOnce(Return("202200"));
1219         psu.analyze();
1220         EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT);
1221     }
1222     // Back to no bits on in STATUS_WORD
1223     expectations.statusWordValue = 0;
1224     setPMBusExpectations(mockPMBus, expectations);
1225     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1226         .Times(1)
1227         .WillOnce(Return("202300"));
1228     psu.analyze();
1229     EXPECT_EQ(psu.hasMFRFault(), false);
1230 }
1231 
1232 TEST_F(PowerSupplyTests, HasVINUVFault)
1233 {
1234     auto bus = sdbusplus::bus::new_default();
1235 
1236     PowerSupply psu{bus,  PSUInventoryPath, 3,
1237                     0x68, "ibm-cffps",      PSUGPIOLineName};
1238     MockedGPIOInterface* mockPresenceGPIO =
1239         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1240     // Always return 1 to indicate present.
1241     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1242     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1243     setMissingToPresentExpects(mockPMBus, mockedUtil);
1244 
1245     // Presence change from missing to present will trigger in1_input read in
1246     // an attempt to get CLEAR_FAULTS called. Return value ignored.
1247     // Zero to non-zero voltage, for missing/present change, triggers clear
1248     // faults call again. Return value ignored.
1249     // Fault (low voltage) to not faulted (voltage in range) triggers clear
1250     // faults call a third time.
1251 
1252     // STATUS_WORD 0x0000 is powered on, no faults.
1253     PMBusExpectations expectations;
1254     setPMBusExpectations(mockPMBus, expectations);
1255     // Analyze call will also need good READ_VIN value to check.
1256     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1257         .Times(1)
1258         .WillOnce(Return("201100"));
1259     psu.analyze();
1260     EXPECT_EQ(psu.hasVINUVFault(), false);
1261     // Turn fault on.
1262     expectations.statusWordValue = (status_word::VIN_UV_FAULT);
1263     // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by
1264     // Figure 16, and assume bits on in STATUS_INPUT.
1265     expectations.statusInputValue = 0x18;
1266     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1267     {
1268         setPMBusExpectations(mockPMBus, expectations);
1269         // If there is a VIN_UV fault, fake reading voltage of less than 20V
1270         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1271             .Times(1)
1272             .WillOnce(Return("19876"));
1273         if (x == DEGLITCH_LIMIT)
1274         {
1275             EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1276         }
1277         psu.analyze();
1278         EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT);
1279     }
1280     // Back to no fault bits on in STATUS_WORD
1281     expectations.statusWordValue = 0;
1282     setPMBusExpectations(mockPMBus, expectations);
1283     // Updates now result in clearing faults if read voltage goes from below the
1284     // minimum, to within a valid range.
1285     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1286         .Times(1)
1287         .WillOnce(Return("201300"));
1288     // Went from below minimum to within range, expect clearVinUVFault().
1289     EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
1290         .Times(1)
1291         .WillOnce(Return(1));
1292     EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
1293     psu.analyze();
1294     EXPECT_EQ(psu.hasVINUVFault(), false);
1295 }
1296 
1297 TEST_F(PowerSupplyTests, HasVoutOVFault)
1298 {
1299     auto bus = sdbusplus::bus::new_default();
1300 
1301     PowerSupply psu{bus,  PSUInventoryPath, 3,
1302                     0x69, "ibm-cffps",      PSUGPIOLineName};
1303     MockedGPIOInterface* mockPresenceGPIO =
1304         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1305     // Always return 1 to indicate present.
1306     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1307     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1308     setMissingToPresentExpects(mockPMBus, mockedUtil);
1309     // STATUS_WORD 0x0000 is powered on, no faults.
1310     PMBusExpectations expectations;
1311     setPMBusExpectations(mockPMBus, expectations);
1312     // Call to analyze will trigger read of "in1_input" to check voltage.
1313     // Initial value would be 0, so this read updates it to non-zero.
1314     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1315         .Times(1)
1316         .WillOnce(Return("202100"));
1317     psu.analyze();
1318     EXPECT_EQ(psu.hasVoutOVFault(), false);
1319     // Turn fault on.
1320     expectations.statusWordValue = (status_word::VOUT_OV_FAULT);
1321     // STATUS_VOUT fault bit(s)
1322     expectations.statusVOUTValue = 0x80;
1323     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1324     {
1325         setPMBusExpectations(mockPMBus, expectations);
1326         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1327             .Times(1)
1328             .WillOnce(Return("202200"));
1329         psu.analyze();
1330         EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT);
1331     }
1332     // Back to no fault bits on in STATUS_WORD
1333     expectations.statusWordValue = 0;
1334     setPMBusExpectations(mockPMBus, expectations);
1335     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1336         .Times(1)
1337         .WillOnce(Return("202300"));
1338     psu.analyze();
1339     EXPECT_EQ(psu.hasVoutOVFault(), false);
1340 }
1341 
1342 TEST_F(PowerSupplyTests, HasIoutOCFault)
1343 {
1344     auto bus = sdbusplus::bus::new_default();
1345 
1346     PowerSupply psu{bus,  PSUInventoryPath, 3,
1347                     0x6d, "ibm-cffps",      PSUGPIOLineName};
1348     MockedGPIOInterface* mockPresenceGPIO =
1349         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1350     // Always return 1 to indicate present.
1351     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1352     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1353     setMissingToPresentExpects(mockPMBus, mockedUtil);
1354     // STATUS_WORD 0x0000 is powered on, no faults.
1355     PMBusExpectations expectations;
1356     setPMBusExpectations(mockPMBus, expectations);
1357     // Call to analyze will trigger read of "in1_input" to check voltage.
1358     // Initial value would be 0, so this read updates it to non-zero.
1359     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1360         .Times(1)
1361         .WillOnce(Return("203100"));
1362     psu.analyze();
1363     EXPECT_EQ(psu.hasIoutOCFault(), false);
1364     // Turn fault on.
1365     expectations.statusWordValue = status_word::IOUT_OC_FAULT;
1366     // STATUS_IOUT fault bit(s)
1367     expectations.statusIOUTValue = 0x88;
1368     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1369     {
1370         setPMBusExpectations(mockPMBus, expectations);
1371         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1372             .Times(1)
1373             .WillOnce(Return("203200"));
1374         if (x == DEGLITCH_LIMIT)
1375         {
1376             EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1377         }
1378         psu.analyze();
1379         EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT);
1380     }
1381     // Back to no fault bits on in STATUS_WORD
1382     expectations.statusWordValue = 0;
1383     setPMBusExpectations(mockPMBus, expectations);
1384     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1385         .Times(1)
1386         .WillOnce(Return("203300"));
1387     EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
1388     psu.analyze();
1389     EXPECT_EQ(psu.hasIoutOCFault(), false);
1390 }
1391 
1392 TEST_F(PowerSupplyTests, HasVoutUVFault)
1393 {
1394     auto bus = sdbusplus::bus::new_default();
1395 
1396     PowerSupply psu{bus,  PSUInventoryPath, 3,
1397                     0x6a, "ibm-cffps",      PSUGPIOLineName};
1398     MockedGPIOInterface* mockPresenceGPIO =
1399         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1400     // Always return 1 to indicate present.
1401     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1402     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1403     setMissingToPresentExpects(mockPMBus, mockedUtil);
1404     // STATUS_WORD 0x0000 is powered on, no faults.
1405     PMBusExpectations expectations;
1406     setPMBusExpectations(mockPMBus, expectations);
1407     // Call to analyze will trigger read of "in1_input" to check voltage.
1408     // Initial value would be 0, so this read updates it to non-zero.
1409     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1410         .Times(1)
1411         .WillOnce(Return("204100"));
1412     psu.analyze();
1413     EXPECT_EQ(psu.hasVoutUVFault(), false);
1414     // Turn fault on.
1415     expectations.statusWordValue = (status_word::VOUT_FAULT);
1416     // STATUS_VOUT fault bit(s)
1417     expectations.statusVOUTValue = 0x30;
1418     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1419     {
1420         setPMBusExpectations(mockPMBus, expectations);
1421         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1422             .Times(1)
1423             .WillOnce(Return("204200"));
1424         psu.analyze();
1425         EXPECT_EQ(psu.hasVoutUVFault(), x >= DEGLITCH_LIMIT);
1426     }
1427     // Back to no fault bits on in STATUS_WORD
1428     expectations.statusWordValue = 0;
1429     setPMBusExpectations(mockPMBus, expectations);
1430     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1431         .Times(1)
1432         .WillOnce(Return("204300"));
1433     psu.analyze();
1434     EXPECT_EQ(psu.hasVoutUVFault(), false);
1435 }
1436 
1437 TEST_F(PowerSupplyTests, HasFanFault)
1438 {
1439     auto bus = sdbusplus::bus::new_default();
1440 
1441     EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1);
1442     EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0);
1443 
1444     PowerSupply psu{bus,  PSUInventoryPath, 3,
1445                     0x6d, "ibm-cffps",      PSUGPIOLineName};
1446     MockedGPIOInterface* mockPresenceGPIO =
1447         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1448     // Always return 1 to indicate present.
1449     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1450     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1451     setMissingToPresentExpects(mockPMBus, mockedUtil);
1452     // STATUS_WORD 0x0000 is powered on, no faults.
1453     PMBusExpectations expectations;
1454     setPMBusExpectations(mockPMBus, expectations);
1455     // Call to analyze will trigger read of "in1_input" to check voltage.
1456     // Initial value would be 0, so this read updates it to non-zero.
1457     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1458         .Times(1)
1459         .WillOnce(Return("205100"));
1460     psu.analyze();
1461     EXPECT_EQ(psu.hasFanFault(), false);
1462     // Turn fault on.
1463     expectations.statusWordValue = (status_word::FAN_FAULT);
1464     // STATUS_FANS_1_2 fault bit on (Fan 1 Fault)
1465     expectations.statusFans12Value = 0x80;
1466     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1467     {
1468         setPMBusExpectations(mockPMBus, expectations);
1469         // Call to analyze will trigger read of "in1_input" to check voltage.
1470         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1471             .Times(1)
1472             .WillOnce(Return("205200"));
1473         psu.analyze();
1474         EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT);
1475     }
1476     // Back to no fault bits on in STATUS_WORD
1477     expectations.statusWordValue = 0;
1478     setPMBusExpectations(mockPMBus, expectations);
1479     // Call to analyze will trigger read of "in1_input" to check voltage.
1480     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1481         .Times(1)
1482         .WillOnce(Return("205300"));
1483     psu.analyze();
1484     EXPECT_EQ(psu.hasFanFault(), false);
1485 }
1486 
1487 TEST_F(PowerSupplyTests, HasTempFault)
1488 {
1489     auto bus = sdbusplus::bus::new_default();
1490 
1491     EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1);
1492     EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0);
1493 
1494     PowerSupply psu{bus,  PSUInventoryPath, 3,
1495                     0x6a, "ibm-cffps",      PSUGPIOLineName};
1496     MockedGPIOInterface* mockPresenceGPIO =
1497         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1498     // Always return 1 to indicate present.
1499     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1500     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1501     setMissingToPresentExpects(mockPMBus, mockedUtil);
1502     // STATUS_WORD 0x0000 is powered on, no faults.
1503     PMBusExpectations expectations;
1504     setPMBusExpectations(mockPMBus, expectations);
1505     // Call to analyze will trigger read of "in1_input" to check voltage.
1506     // Initial value would be 0, so this read updates it to non-zero.
1507     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1508         .Times(1)
1509         .WillOnce(Return("206100"));
1510     psu.analyze();
1511     EXPECT_EQ(psu.hasTempFault(), false);
1512     // Turn fault on.
1513     expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
1514     // STATUS_TEMPERATURE fault bit on (OT Fault)
1515     expectations.statusTempValue = 0x80;
1516     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1517     {
1518         setPMBusExpectations(mockPMBus, expectations);
1519         // Call to analyze will trigger read of "in1_input" to check voltage.
1520         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1521             .Times(1)
1522             .WillOnce(Return("206200"));
1523         psu.analyze();
1524         EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT);
1525     }
1526     // Back to no fault bits on in STATUS_WORD
1527     expectations.statusWordValue = 0;
1528     setPMBusExpectations(mockPMBus, expectations);
1529     // Call to analyze will trigger read of "in1_input" to check voltage.
1530     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1531         .Times(1)
1532         .WillOnce(Return("206300"));
1533     psu.analyze();
1534     EXPECT_EQ(psu.hasTempFault(), false);
1535 }
1536 
1537 TEST_F(PowerSupplyTests, HasPgoodFault)
1538 {
1539     auto bus = sdbusplus::bus::new_default();
1540 
1541     PowerSupply psu{bus,  PSUInventoryPath, 3,
1542                     0x6b, "ibm-cffps",      PSUGPIOLineName};
1543     MockedGPIOInterface* mockPresenceGPIO =
1544         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1545     // Always return 1 to indicate present.
1546     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1547     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1548     setMissingToPresentExpects(mockPMBus, mockedUtil);
1549     // STATUS_WORD 0x0000 is powered on, no faults.
1550     PMBusExpectations expectations;
1551     setPMBusExpectations(mockPMBus, expectations);
1552     // Call to analyze will trigger read of "in1_input" to check voltage.
1553     // Initial value would be 0, so this read updates it to non-zero.
1554     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1555         .Times(1)
1556         .WillOnce(Return("207100"));
1557     psu.analyze();
1558     EXPECT_EQ(psu.hasPgoodFault(), false);
1559     // Setup another expectation of no faults.
1560     setPMBusExpectations(mockPMBus, expectations);
1561     // Call to analyze will trigger read of "in1_input" to check voltage.
1562     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1563         .Times(1)
1564         .WillOnce(Return("207200"));
1565     psu.analyze();
1566     EXPECT_EQ(psu.hasPgoodFault(), false);
1567     // Setup another expectation of no faults.
1568     setPMBusExpectations(mockPMBus, expectations);
1569     // Call to analyze will trigger read of "in1_input" to check voltage.
1570     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1571         .Times(1)
1572         .WillOnce(Return("207300"));
1573     psu.analyze();
1574     EXPECT_EQ(psu.hasPgoodFault(), false);
1575     // Turn PGOOD# off (fault on).
1576     expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED);
1577     setPMBusExpectations(mockPMBus, expectations);
1578     // Call to analyze will trigger read of "in1_input" to check voltage.
1579     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1580         .Times(1)
1581         .WillOnce(Return("207400"));
1582     psu.analyze();
1583     // Expect false until reaches DEGLITCH_LIMIT
1584     EXPECT_EQ(psu.hasPgoodFault(), false);
1585     setPMBusExpectations(mockPMBus, expectations);
1586     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1587         .Times(1)
1588         .WillOnce(Return("207500"));
1589     psu.analyze();
1590     // Expect false until reaches DEGLITCH_LIMIT
1591     EXPECT_EQ(psu.hasPgoodFault(), false);
1592     setPMBusExpectations(mockPMBus, expectations);
1593     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1594         .Times(1)
1595         .WillOnce(Return("207600"));
1596     psu.analyze();
1597     // DEGLITCH_LIMIT reached, expect true.
1598     EXPECT_EQ(psu.hasPgoodFault(), true);
1599     // Back to no fault bits on in STATUS_WORD
1600     expectations.statusWordValue = 0;
1601     setPMBusExpectations(mockPMBus, expectations);
1602     // Call to analyze will trigger read of "in1_input" to check voltage.
1603     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1604         .Times(1)
1605         .WillOnce(Return("207700"));
1606     psu.analyze();
1607     EXPECT_EQ(psu.hasPgoodFault(), false);
1608 
1609     // Turn OFF bit on
1610     expectations.statusWordValue = (status_word::UNIT_IS_OFF);
1611     setPMBusExpectations(mockPMBus, expectations);
1612     // Call to analyze will trigger read of "in1_input" to check voltage.
1613     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1614         .Times(1)
1615         .WillOnce(Return("208100"));
1616     psu.analyze();
1617     EXPECT_EQ(psu.hasPgoodFault(), false);
1618     setPMBusExpectations(mockPMBus, expectations);
1619     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1620         .Times(1)
1621         .WillOnce(Return("208200"));
1622     psu.analyze();
1623     EXPECT_EQ(psu.hasPgoodFault(), false);
1624     setPMBusExpectations(mockPMBus, expectations);
1625     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1626         .Times(1)
1627         .WillOnce(Return("208300"));
1628     psu.analyze();
1629     EXPECT_EQ(psu.hasPgoodFault(), true);
1630     // Back to no fault bits on in STATUS_WORD
1631     expectations.statusWordValue = 0;
1632     setPMBusExpectations(mockPMBus, expectations);
1633     // Call to analyze will trigger read of "in1_input" to check voltage.
1634     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1635         .Times(1)
1636         .WillOnce(Return("208400"));
1637     psu.analyze();
1638     EXPECT_EQ(psu.hasPgoodFault(), false);
1639 }
1640 
1641 TEST_F(PowerSupplyTests, HasPSKillFault)
1642 {
1643     auto bus = sdbusplus::bus::new_default();
1644     PowerSupply psu{bus,  PSUInventoryPath, 4,
1645                     0x6d, "ibm-cffps",      PSUGPIOLineName};
1646     MockedGPIOInterface* mockPresenceGPIO =
1647         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1648     // Always return 1 to indicate present.
1649     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1650     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1651     setMissingToPresentExpects(mockPMBus, mockedUtil);
1652     // STATUS_WORD 0x0000 is powered on, no faults.
1653     PMBusExpectations expectations;
1654     setPMBusExpectations(mockPMBus, expectations);
1655     // Call to analyze will trigger read of "in1_input" to check voltage.
1656     // Initial value would be 0, so this read updates it to non-zero.
1657     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1658         .Times(1)
1659         .WillOnce(Return("208100"));
1660     psu.analyze();
1661     EXPECT_EQ(psu.hasPSKillFault(), false);
1662     // Next return STATUS_WORD with MFR fault bit on.
1663     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1664     // STATUS_MFR_SPEFIC with bit(s) on.
1665     expectations.statusMFRValue = 0xFF;
1666 
1667     // Deglitching faults, false until read the fault bits on up to the limit.
1668     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1669     {
1670         setPMBusExpectations(mockPMBus, expectations);
1671         // Call to analyze will trigger read of "in1_input" to check voltage.
1672         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1673             .Times(1)
1674             .WillOnce(Return("208200"));
1675         if (x == DEGLITCH_LIMIT)
1676         {
1677             EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1678         }
1679         psu.analyze();
1680         EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT);
1681     }
1682 
1683     // Back to no bits on in STATUS_WORD
1684     expectations.statusWordValue = 0;
1685     setPMBusExpectations(mockPMBus, expectations);
1686     // Call to analyze will trigger read of "in1_input" to check voltage.
1687     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1688         .Times(1)
1689         .WillOnce(Return("208300"));
1690     EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
1691     psu.analyze();
1692     EXPECT_EQ(psu.hasPSKillFault(), false);
1693     // Next return STATUS_WORD with MFR fault bit on.
1694     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1695     // STATUS_MFR_SPEFIC with bit 4 on.
1696     expectations.statusMFRValue = 0x10;
1697 
1698     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1699     {
1700         setPMBusExpectations(mockPMBus, expectations);
1701         // Call to analyze will trigger read of "in1_input" to check voltage.
1702         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1703             .Times(1)
1704             .WillOnce(Return("208400"));
1705         if (x == DEGLITCH_LIMIT)
1706         {
1707             EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1708         }
1709         psu.analyze();
1710         EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT);
1711     }
1712 
1713     // Back to no bits on in STATUS_WORD
1714     expectations.statusWordValue = 0;
1715     setPMBusExpectations(mockPMBus, expectations);
1716     // Call to analyze will trigger read of "in1_input" to check voltage.
1717     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1718         .Times(1)
1719         .WillOnce(Return("208500"));
1720     EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
1721     psu.analyze();
1722     EXPECT_EQ(psu.hasPSKillFault(), false);
1723 }
1724 
1725 TEST_F(PowerSupplyTests, HasPS12VcsFault)
1726 {
1727     auto bus = sdbusplus::bus::new_default();
1728     PowerSupply psu{bus,  PSUInventoryPath, 5,
1729                     0x6e, "ibm-cffps",      PSUGPIOLineName};
1730     MockedGPIOInterface* mockPresenceGPIO =
1731         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1732     // Always return 1 to indicate present.
1733     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1734     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1735     setMissingToPresentExpects(mockPMBus, mockedUtil);
1736     // STATUS_WORD 0x0000 is powered on, no faults.
1737     PMBusExpectations expectations;
1738     setPMBusExpectations(mockPMBus, expectations);
1739     // Call to analyze will trigger read of "in1_input" to check voltage.
1740     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1741         .Times(1)
1742         .WillOnce(Return("209100"));
1743     psu.analyze();
1744     EXPECT_EQ(psu.hasPS12VcsFault(), false);
1745     // Next return STATUS_WORD with MFR fault bit on.
1746     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1747     // STATUS_MFR_SPEFIC with bit(s) on.
1748     expectations.statusMFRValue = 0xFF;
1749 
1750     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1751     {
1752         setPMBusExpectations(mockPMBus, expectations);
1753         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1754             .Times(1)
1755             .WillOnce(Return("209200"));
1756         psu.analyze();
1757         EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
1758     }
1759 
1760     // Back to no bits on in STATUS_WORD
1761     expectations.statusWordValue = 0;
1762     setPMBusExpectations(mockPMBus, expectations);
1763     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1764         .Times(1)
1765         .WillOnce(Return("209300"));
1766     psu.analyze();
1767     EXPECT_EQ(psu.hasPS12VcsFault(), false);
1768     // Next return STATUS_WORD with MFR fault bit on.
1769     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1770     // STATUS_MFR_SPEFIC with bit 6 on.
1771     expectations.statusMFRValue = 0x40;
1772 
1773     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1774     {
1775         setPMBusExpectations(mockPMBus, expectations);
1776         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1777             .Times(1)
1778             .WillOnce(Return("209400"));
1779         psu.analyze();
1780         EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
1781     }
1782 
1783     // Back to no bits on in STATUS_WORD
1784     expectations.statusWordValue = 0;
1785     setPMBusExpectations(mockPMBus, expectations);
1786     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1787         .Times(1)
1788         .WillOnce(Return("209500"));
1789     psu.analyze();
1790     EXPECT_EQ(psu.hasPS12VcsFault(), false);
1791 }
1792 
1793 TEST_F(PowerSupplyTests, HasPSCS12VFault)
1794 {
1795     auto bus = sdbusplus::bus::new_default();
1796     PowerSupply psu{bus,  PSUInventoryPath, 6,
1797                     0x6f, "ibm-cffps",      PSUGPIOLineName};
1798     MockedGPIOInterface* mockPresenceGPIO =
1799         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1800     // Always return 1 to indicate present.
1801     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1802     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1803     setMissingToPresentExpects(mockPMBus, mockedUtil);
1804     // STATUS_WORD 0x0000 is powered on, no faults.
1805     PMBusExpectations expectations;
1806     setPMBusExpectations(mockPMBus, expectations);
1807     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1808         .Times(1)
1809         .WillOnce(Return("209100"));
1810     psu.analyze();
1811     EXPECT_EQ(psu.hasPSCS12VFault(), false);
1812     // Next return STATUS_WORD with MFR fault bit on.
1813     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1814     // STATUS_MFR_SPEFIC with bit(s) on.
1815     expectations.statusMFRValue = 0xFF;
1816 
1817     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1818     {
1819         setPMBusExpectations(mockPMBus, expectations);
1820         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1821             .Times(1)
1822             .WillOnce(Return("209200"));
1823         psu.analyze();
1824         EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
1825     }
1826 
1827     // Back to no bits on in STATUS_WORD
1828     expectations.statusWordValue = 0;
1829     setPMBusExpectations(mockPMBus, expectations);
1830     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1831         .Times(1)
1832         .WillOnce(Return("209300"));
1833     psu.analyze();
1834     EXPECT_EQ(psu.hasPSCS12VFault(), false);
1835     // Next return STATUS_WORD with MFR fault bit on.
1836     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1837     // STATUS_MFR_SPEFIC with bit 7 on.
1838     expectations.statusMFRValue = 0x80;
1839 
1840     for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1841     {
1842         setPMBusExpectations(mockPMBus, expectations);
1843         EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1844             .Times(1)
1845             .WillOnce(Return("209400"));
1846         psu.analyze();
1847         EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
1848     }
1849 
1850     // Back to no bits on in STATUS_WORD
1851     expectations.statusWordValue = 0;
1852     setPMBusExpectations(mockPMBus, expectations);
1853     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1854         .Times(1)
1855         .WillOnce(Return("209500"));
1856     psu.analyze();
1857     EXPECT_EQ(psu.hasPSCS12VFault(), false);
1858 }
1859 
1860 TEST_F(PowerSupplyTests, SetupInputHistory)
1861 {
1862     auto bus = sdbusplus::bus::new_default();
1863     {
1864         PowerSupply psu{bus,  PSUInventoryPath, 6,
1865                         0x6f, "ibm-cffps",      PSUGPIOLineName};
1866         // Defaults to not present due to constructor and mock ordering.
1867         psu.setupInputHistory();
1868         EXPECT_EQ(psu.hasInputHistory(), false);
1869         MockedGPIOInterface* mockPresenceGPIO =
1870             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1871         // Always return 1 to indicate present.
1872         EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1873         psu.analyze();
1874         psu.setupInputHistory();
1875         EXPECT_EQ(psu.hasInputHistory(), true);
1876     }
1877     {
1878         PowerSupply psu{bus,  PSUInventoryPath, 11,
1879                         0x58, "inspur-ipsps",   PSUGPIOLineName};
1880         // Defaults to not present due to constructor and mock ordering.
1881         psu.setupInputHistory();
1882         EXPECT_EQ(psu.hasInputHistory(), false);
1883         MockedGPIOInterface* mockPresenceGPIO =
1884             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1885         // Always return 1 to indicate present.
1886         EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1887         psu.analyze();
1888         psu.setupInputHistory();
1889         // After updating to present, and retrying setup, expect inspur-ipsps to
1890         // still not support INPUT_HISTORY.
1891         EXPECT_EQ(psu.hasInputHistory(), false);
1892     }
1893 }
1894 
1895 TEST_F(PowerSupplyTests, UpdateHistory)
1896 {
1897     auto bus = sdbusplus::bus::new_default();
1898     PowerSupply psu{bus,  PSUInventoryPath, 7,
1899                     0x6e, "ibm-cffps",      PSUGPIOLineName};
1900     EXPECT_EQ(psu.hasInputHistory(), false);
1901     EXPECT_EQ(psu.getNumInputHistoryRecords(), 0);
1902     MockedGPIOInterface* mockPresenceGPIO =
1903         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1904     // Always return 1 to indicate present.
1905     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1906     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1907     setMissingToPresentExpects(mockPMBus, mockedUtil);
1908     PMBusExpectations expectations;
1909     setPMBusExpectations(mockPMBus, expectations);
1910     EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1911         .Times(6)
1912         .WillRepeatedly(Return("205000"));
1913     EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
1914     // First read after missing/present will have no data.
1915     std::vector<uint8_t> emptyHistory{};
1916     // Second read, after about 30 seconds, should have a record. 5-bytes.
1917     // Sequence Number: 0x00, Average: 0x50 0xf3 (212), Maximum: 0x54 0xf3 (213)
1918     std::vector<uint8_t> firstHistory{0x00, 0x50, 0xf3, 0x54, 0xf3};
1919     // Third read, after about 60 seconds, should have two records, 10-bytes,
1920     // but only reading 5 bytes, so make sure new/next sequence number
1921     std::vector<uint8_t> secondHistory{0x01, 0x54, 0xf3, 0x58, 0xf3};
1922     // Fourth read, 3rd sequence number (0x02).
1923     std::vector<uint8_t> thirdHistory{0x02, 0x54, 0xf3, 0x58, 0xf3};
1924     // Fifth read, out of sequence, clear and insert this one?
1925     std::vector<uint8_t> outseqHistory{0xff, 0x5c, 0xf3, 0x60, 0xf3};
1926     EXPECT_CALL(
1927         mockPMBus,
1928         readBinary(INPUT_HISTORY, Type::HwmonDeviceDebug,
1929                    phosphor::power::history::RecordManager::RAW_RECORD_SIZE))
1930         .Times(6)
1931         .WillOnce(Return(emptyHistory))
1932         .WillOnce(Return(firstHistory))
1933         .WillOnce(Return(secondHistory))
1934         .WillOnce(Return(thirdHistory))
1935         .WillOnce(Return(outseqHistory))
1936         .WillOnce(Return(emptyHistory));
1937     // Calling analyze will update the presence, which will setup the input
1938     // history if the power supply went from missing to present.
1939     psu.analyze();
1940     // The ibm-cffps power supply should support input history
1941     EXPECT_EQ(psu.hasInputHistory(), true);
1942     // Usually should have empty buffer right after missing to present.
1943     // Faked that out above with mocked readBinary with emptyHistory data.
1944     EXPECT_EQ(psu.getNumInputHistoryRecords(), 0);
1945     // Second run through...
1946     setPMBusExpectations(mockPMBus, expectations);
1947     psu.analyze();
1948     EXPECT_EQ(psu.hasInputHistory(), true);
1949     EXPECT_EQ(psu.getNumInputHistoryRecords(), 1);
1950     // Third run through
1951     setPMBusExpectations(mockPMBus, expectations);
1952     psu.analyze();
1953     EXPECT_EQ(psu.hasInputHistory(), true);
1954     EXPECT_EQ(psu.getNumInputHistoryRecords(), 2);
1955     // Fourth run through. Up to 3 records now?
1956     setPMBusExpectations(mockPMBus, expectations);
1957     psu.analyze();
1958     EXPECT_EQ(psu.hasInputHistory(), true);
1959     EXPECT_EQ(psu.getNumInputHistoryRecords(), 3);
1960     // Out of sequencer, reset, insert new one.
1961     setPMBusExpectations(mockPMBus, expectations);
1962     psu.analyze();
1963     EXPECT_EQ(psu.hasInputHistory(), true);
1964     EXPECT_EQ(psu.getNumInputHistoryRecords(), 1);
1965     // Empty one after last one good. Reset/clear.
1966     setPMBusExpectations(mockPMBus, expectations);
1967     psu.analyze();
1968     EXPECT_EQ(psu.hasInputHistory(), true);
1969     EXPECT_EQ(psu.getNumInputHistoryRecords(), 0);
1970 }
1971