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