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