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     EXPECT_CALL(pmbus, read(READ_VIN, _)).Times(1).WillOnce(Return(1));
107     // Missing/present call will update Presence in inventory.
108     // EXPECT_CALL(mockedUtil, setPresence(_, _, true, _));
109     EXPECT_CALL(util, setPresence(_, _, true, _));
110 }
111 
112 TEST_F(PowerSupplyTests, Constructor)
113 {
114     /**
115      * @param[in] invpath - String for inventory path to use
116      * @param[in] i2cbus - The bus number this power supply is on
117      * @param[in] i2caddr - The 16-bit I2C address of the power supply
118      * @param[in] gpioLineName - The string for the gpio-line-name to read for
119      * presence.
120      * @param[in] bindDelay - Time in milliseconds to delay binding the device
121      * driver after seeing the presence line go active.
122      */
123     auto bus = sdbusplus::bus::new_default();
124 
125     // Try where inventory path is empty, constructor should fail.
126     try
127     {
128         auto psu =
129             std::make_unique<PowerSupply>(bus, "", 3, 0x68, PSUGPIOLineName);
130         ADD_FAILURE() << "Should not have reached this line.";
131     }
132     catch (const std::invalid_argument& e)
133     {
134         EXPECT_STREQ(e.what(), "Invalid empty inventoryPath");
135     }
136     catch (...)
137     {
138         ADD_FAILURE() << "Should not have caught exception.";
139     }
140 
141     // TODO: Try invalid i2c address?
142 
143     // Try where gpioLineName is empty.
144     try
145     {
146         auto psu =
147             std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, "");
148         ADD_FAILURE()
149             << "Should not have reached this line. Invalid gpioLineName.";
150     }
151     catch (const std::invalid_argument& e)
152     {
153         EXPECT_STREQ(e.what(), "Invalid empty gpioLineName");
154     }
155     catch (...)
156     {
157         ADD_FAILURE() << "Should not have caught exception.";
158     }
159 
160     // Test with valid arguments
161     // NOT using D-Bus inventory path for presence.
162     try
163     {
164         auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68,
165                                                  PSUGPIOLineName);
166 
167         EXPECT_EQ(psu->isPresent(), false);
168         EXPECT_EQ(psu->isFaulted(), false);
169         EXPECT_EQ(psu->hasCommFault(), false);
170         EXPECT_EQ(psu->hasInputFault(), false);
171         EXPECT_EQ(psu->hasMFRFault(), false);
172         EXPECT_EQ(psu->hasVINUVFault(), false);
173         EXPECT_EQ(psu->hasVoutOVFault(), false);
174         EXPECT_EQ(psu->hasIoutOCFault(), false);
175         EXPECT_EQ(psu->hasVoutUVFault(), false);
176         EXPECT_EQ(psu->hasFanFault(), false);
177         EXPECT_EQ(psu->hasTempFault(), false);
178         EXPECT_EQ(psu->hasPgoodFault(), false);
179         EXPECT_EQ(psu->hasPSKillFault(), false);
180         EXPECT_EQ(psu->hasPS12VcsFault(), false);
181         EXPECT_EQ(psu->hasPSCS12VFault(), false);
182     }
183     catch (...)
184     {
185         ADD_FAILURE() << "Should not have caught exception.";
186     }
187 
188     // Test with valid arguments
189     // TODO: Using D-Bus inventory path for presence.
190     try
191     {
192         // FIXME: How do I get that presenceGPIO.read() in the startup to throw
193         // an exception?
194 
195         // EXPECT_CALL(mockedUtil, getPresence(_,
196         // StrEq(PSUInventoryPath)))
197         //    .Times(1);
198     }
199     catch (...)
200     {
201         ADD_FAILURE() << "Should not have caught exception.";
202     }
203 }
204 
205 TEST_F(PowerSupplyTests, Analyze)
206 {
207     auto bus = sdbusplus::bus::new_default();
208 
209     {
210         // If I default to reading the GPIO, I will NOT expect a call to
211         // getPresence().
212 
213         PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
214         MockedGPIOInterface* mockPresenceGPIO =
215             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
216         EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0));
217 
218         psu.analyze();
219         // By default, nothing should change.
220         EXPECT_EQ(psu.isPresent(), false);
221         EXPECT_EQ(psu.isFaulted(), false);
222         EXPECT_EQ(psu.hasInputFault(), false);
223         EXPECT_EQ(psu.hasMFRFault(), false);
224         EXPECT_EQ(psu.hasVINUVFault(), false);
225         EXPECT_EQ(psu.hasCommFault(), false);
226         EXPECT_EQ(psu.hasVoutOVFault(), false);
227         EXPECT_EQ(psu.hasIoutOCFault(), false);
228         EXPECT_EQ(psu.hasVoutUVFault(), false);
229         EXPECT_EQ(psu.hasFanFault(), false);
230         EXPECT_EQ(psu.hasTempFault(), false);
231         EXPECT_EQ(psu.hasPgoodFault(), false);
232         EXPECT_EQ(psu.hasPSKillFault(), false);
233         EXPECT_EQ(psu.hasPS12VcsFault(), false);
234         EXPECT_EQ(psu.hasPSCS12VFault(), false);
235     }
236 
237     PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
238     // In order to get the various faults tested, the power supply needs to
239     // be present in order to read from the PMBus device(s).
240     MockedGPIOInterface* mockPresenceGPIO2 =
241         static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO());
242     // Always return 1 to indicate present.
243     // Each analyze() call will trigger a read of the presence GPIO.
244     EXPECT_CALL(*mockPresenceGPIO2, read()).WillRepeatedly(Return(1));
245     EXPECT_EQ(psu2.isPresent(), false);
246 
247     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus());
248     setMissingToPresentExpects(mockPMBus, mockedUtil);
249 
250     // STATUS_WORD INPUT fault.
251     {
252         // Start with STATUS_WORD 0x0000. Powered on, no faults.
253         // Set expectations for a no fault
254         PMBusExpectations expectations;
255         setPMBusExpectations(mockPMBus, expectations);
256         psu2.analyze();
257         EXPECT_EQ(psu2.isPresent(), true);
258         EXPECT_EQ(psu2.isFaulted(), false);
259         EXPECT_EQ(psu2.hasInputFault(), false);
260         EXPECT_EQ(psu2.hasMFRFault(), false);
261         EXPECT_EQ(psu2.hasVINUVFault(), false);
262         EXPECT_EQ(psu2.hasCommFault(), false);
263         EXPECT_EQ(psu2.hasVoutOVFault(), false);
264         EXPECT_EQ(psu2.hasIoutOCFault(), false);
265         EXPECT_EQ(psu2.hasVoutUVFault(), false);
266         EXPECT_EQ(psu2.hasFanFault(), false);
267         EXPECT_EQ(psu2.hasTempFault(), false);
268         EXPECT_EQ(psu2.hasPgoodFault(), false);
269         EXPECT_EQ(psu2.hasPSKillFault(), false);
270         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
271         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
272 
273         // Update expectations for STATUS_WORD input fault/warn
274         // STATUS_INPUT fault bits ... on.
275         expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
276         expectations.statusInputValue = 0x38;
277         setPMBusExpectations(mockPMBus, expectations);
278         psu2.analyze();
279         EXPECT_EQ(psu2.isPresent(), true);
280         EXPECT_EQ(psu2.isFaulted(), true);
281         EXPECT_EQ(psu2.hasInputFault(), true);
282         EXPECT_EQ(psu2.hasMFRFault(), false);
283         EXPECT_EQ(psu2.hasVINUVFault(), false);
284         EXPECT_EQ(psu2.hasCommFault(), false);
285         EXPECT_EQ(psu2.hasVoutOVFault(), false);
286         EXPECT_EQ(psu2.hasIoutOCFault(), false);
287         EXPECT_EQ(psu2.hasVoutUVFault(), false);
288         EXPECT_EQ(psu2.hasFanFault(), false);
289         EXPECT_EQ(psu2.hasTempFault(), false);
290         EXPECT_EQ(psu2.hasPgoodFault(), false);
291         EXPECT_EQ(psu2.hasPSKillFault(), false);
292         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
293         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
294     }
295 
296     // STATUS_WORD INPUT/UV fault.
297     {
298         // First need it to return good status, then the fault
299         PMBusExpectations expectations;
300         setPMBusExpectations(mockPMBus, expectations);
301         psu2.analyze();
302         // Now set fault bits in STATUS_WORD
303         expectations.statusWordValue =
304             (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT);
305         // STATUS_INPUT fault bits ... on.
306         expectations.statusInputValue = 0x38;
307         setPMBusExpectations(mockPMBus, expectations);
308         psu2.analyze();
309         EXPECT_EQ(psu2.isPresent(), true);
310         EXPECT_EQ(psu2.isFaulted(), true);
311         EXPECT_EQ(psu2.hasInputFault(), true);
312         EXPECT_EQ(psu2.hasMFRFault(), false);
313         EXPECT_EQ(psu2.hasVINUVFault(), true);
314         EXPECT_EQ(psu2.hasCommFault(), false);
315         EXPECT_EQ(psu2.hasVoutOVFault(), false);
316         EXPECT_EQ(psu2.hasIoutOCFault(), false);
317         EXPECT_EQ(psu2.hasVoutUVFault(), false);
318         EXPECT_EQ(psu2.hasFanFault(), false);
319         EXPECT_EQ(psu2.hasTempFault(), false);
320         EXPECT_EQ(psu2.hasPgoodFault(), false);
321         EXPECT_EQ(psu2.hasPSKillFault(), false);
322         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
323         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
324     }
325 
326     // STATUS_WORD MFR fault.
327     {
328         // First need it to return good status, then the fault
329         PMBusExpectations expectations;
330         setPMBusExpectations(mockPMBus, expectations);
331         psu2.analyze();
332         // Now STATUS_WORD with MFR fault bit on.
333         expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
334         // STATUS_MFR bits on.
335         expectations.statusMFRValue = 0xFF;
336         setPMBusExpectations(mockPMBus, expectations);
337         psu2.analyze();
338         EXPECT_EQ(psu2.isPresent(), true);
339         EXPECT_EQ(psu2.isFaulted(), true);
340         EXPECT_EQ(psu2.hasInputFault(), false);
341         EXPECT_EQ(psu2.hasMFRFault(), true);
342         EXPECT_EQ(psu2.hasVINUVFault(), false);
343         EXPECT_EQ(psu2.hasCommFault(), false);
344         EXPECT_EQ(psu2.hasVoutOVFault(), false);
345         EXPECT_EQ(psu2.hasIoutOCFault(), false);
346         EXPECT_EQ(psu2.hasVoutUVFault(), false);
347         EXPECT_EQ(psu2.hasFanFault(), false);
348         EXPECT_EQ(psu2.hasTempFault(), false);
349         EXPECT_EQ(psu2.hasPgoodFault(), false);
350         EXPECT_EQ(psu2.hasPSKillFault(), true);
351         EXPECT_EQ(psu2.hasPS12VcsFault(), true);
352         EXPECT_EQ(psu2.hasPSCS12VFault(), true);
353     }
354 
355     // Temperature fault.
356     {
357         // First STATUS_WORD with no bits set, then with temperature fault.
358         PMBusExpectations expectations;
359         setPMBusExpectations(mockPMBus, expectations);
360         psu2.analyze();
361         // STATUS_WORD with temperature fault bit on.
362         expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
363         // STATUS_TEMPERATURE with fault bit(s) on.
364         expectations.statusTempValue = 0x10;
365         setPMBusExpectations(mockPMBus, expectations);
366         psu2.analyze();
367         EXPECT_EQ(psu2.isPresent(), true);
368         EXPECT_EQ(psu2.isFaulted(), true);
369         EXPECT_EQ(psu2.hasInputFault(), false);
370         EXPECT_EQ(psu2.hasMFRFault(), false);
371         EXPECT_EQ(psu2.hasVINUVFault(), false);
372         EXPECT_EQ(psu2.hasCommFault(), false);
373         EXPECT_EQ(psu2.hasVoutOVFault(), false);
374         EXPECT_EQ(psu2.hasIoutOCFault(), false);
375         EXPECT_EQ(psu2.hasVoutUVFault(), false);
376         EXPECT_EQ(psu2.hasFanFault(), false);
377         EXPECT_EQ(psu2.hasTempFault(), true);
378         EXPECT_EQ(psu2.hasPgoodFault(), false);
379         EXPECT_EQ(psu2.hasPSKillFault(), false);
380         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
381         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
382     }
383 
384     // CML fault
385     {
386         // First STATUS_WORD wit no bits set, then with CML fault.
387         PMBusExpectations expectations;
388         setPMBusExpectations(mockPMBus, expectations);
389         psu2.analyze();
390         // STATUS_WORD with CML fault bit on.
391         expectations.statusWordValue = (status_word::CML_FAULT);
392         // Turn on STATUS_CML fault bit(s)
393         expectations.statusCMLValue = 0xFF;
394         setPMBusExpectations(mockPMBus, expectations);
395         psu2.analyze();
396         EXPECT_EQ(psu2.isPresent(), true);
397         EXPECT_EQ(psu2.isFaulted(), true);
398         EXPECT_EQ(psu2.hasInputFault(), false);
399         EXPECT_EQ(psu2.hasMFRFault(), false);
400         EXPECT_EQ(psu2.hasVINUVFault(), false);
401         EXPECT_EQ(psu2.hasCommFault(), true);
402         EXPECT_EQ(psu2.hasVoutOVFault(), false);
403         EXPECT_EQ(psu2.hasIoutOCFault(), false);
404         EXPECT_EQ(psu2.hasVoutUVFault(), false);
405         EXPECT_EQ(psu2.hasFanFault(), false);
406         EXPECT_EQ(psu2.hasTempFault(), false);
407         EXPECT_EQ(psu2.hasPgoodFault(), false);
408         EXPECT_EQ(psu2.hasPSKillFault(), false);
409         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
410         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
411     }
412 
413     // VOUT_OV_FAULT fault
414     {
415         // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault.
416         PMBusExpectations expectations;
417         setPMBusExpectations(mockPMBus, expectations);
418         psu2.analyze();
419         // STATUS_WORD with VOUT/VOUT_OV fault.
420         expectations.statusWordValue =
421             ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT));
422         // Turn on STATUS_VOUT fault bit(s)
423         expectations.statusVOUTValue = 0xA0;
424         // STATUS_TEMPERATURE don't care (default)
425         setPMBusExpectations(mockPMBus, expectations);
426         psu2.analyze();
427         EXPECT_EQ(psu2.isPresent(), true);
428         EXPECT_EQ(psu2.isFaulted(), true);
429         EXPECT_EQ(psu2.hasInputFault(), false);
430         EXPECT_EQ(psu2.hasMFRFault(), false);
431         EXPECT_EQ(psu2.hasVINUVFault(), false);
432         EXPECT_EQ(psu2.hasCommFault(), false);
433         EXPECT_EQ(psu2.hasVoutOVFault(), true);
434         EXPECT_EQ(psu2.hasVoutUVFault(), false);
435         EXPECT_EQ(psu2.hasIoutOCFault(), false);
436         EXPECT_EQ(psu2.hasFanFault(), false);
437         EXPECT_EQ(psu2.hasTempFault(), false);
438         EXPECT_EQ(psu2.hasPgoodFault(), false);
439         EXPECT_EQ(psu2.hasPSKillFault(), false);
440         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
441         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
442     }
443 
444     // IOUT_OC_FAULT fault
445     {
446         // First STATUS_WORD with no bits set, then with IOUT_OC fault.
447         PMBusExpectations expectations;
448         setPMBusExpectations(mockPMBus, expectations);
449         psu2.analyze();
450         // STATUS_WORD with IOUT_OC fault.
451         expectations.statusWordValue = status_word::IOUT_OC_FAULT;
452         // Turn on STATUS_IOUT fault bit(s)
453         expectations.statusIOUTValue = 0x88;
454         setPMBusExpectations(mockPMBus, expectations);
455         psu2.analyze();
456         EXPECT_EQ(psu2.isPresent(), true);
457         EXPECT_EQ(psu2.isFaulted(), true);
458         EXPECT_EQ(psu2.hasInputFault(), false);
459         EXPECT_EQ(psu2.hasMFRFault(), false);
460         EXPECT_EQ(psu2.hasVINUVFault(), false);
461         EXPECT_EQ(psu2.hasCommFault(), false);
462         EXPECT_EQ(psu2.hasVoutOVFault(), false);
463         EXPECT_EQ(psu2.hasIoutOCFault(), true);
464         EXPECT_EQ(psu2.hasVoutUVFault(), false);
465         EXPECT_EQ(psu2.hasFanFault(), false);
466         EXPECT_EQ(psu2.hasTempFault(), false);
467         EXPECT_EQ(psu2.hasPgoodFault(), false);
468         EXPECT_EQ(psu2.hasPSKillFault(), false);
469         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
470         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
471     }
472 
473     // VOUT_UV_FAULT
474     {
475         // First STATUS_WORD with no bits set, then with VOUT fault.
476         PMBusExpectations expectations;
477         setPMBusExpectations(mockPMBus, expectations);
478         psu2.analyze();
479         // Change STATUS_WORD to indicate VOUT fault.
480         expectations.statusWordValue = (status_word::VOUT_FAULT);
481         // Turn on STATUS_VOUT fault bit(s)
482         expectations.statusVOUTValue = 0x30;
483         setPMBusExpectations(mockPMBus, expectations);
484         psu2.analyze();
485         EXPECT_EQ(psu2.isPresent(), true);
486         EXPECT_EQ(psu2.isFaulted(), true);
487         EXPECT_EQ(psu2.hasInputFault(), false);
488         EXPECT_EQ(psu2.hasMFRFault(), false);
489         EXPECT_EQ(psu2.hasVINUVFault(), false);
490         EXPECT_EQ(psu2.hasCommFault(), false);
491         EXPECT_EQ(psu2.hasVoutOVFault(), false);
492         EXPECT_EQ(psu2.hasIoutOCFault(), false);
493         EXPECT_EQ(psu2.hasVoutUVFault(), true);
494         EXPECT_EQ(psu2.hasFanFault(), false);
495         EXPECT_EQ(psu2.hasTempFault(), false);
496         EXPECT_EQ(psu2.hasPgoodFault(), false);
497         EXPECT_EQ(psu2.hasPSKillFault(), false);
498         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
499         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
500     }
501 
502     // Fan fault
503     {
504         // First STATUS_WORD with no bits set, then with fan fault.
505         PMBusExpectations expectations;
506         setPMBusExpectations(mockPMBus, expectations);
507         psu2.analyze();
508         expectations.statusWordValue = (status_word::FAN_FAULT);
509         // STATUS_FANS_1_2 with fan 1 warning & fault bits on.
510         expectations.statusFans12Value = 0xA0;
511         setPMBusExpectations(mockPMBus, expectations);
512         psu2.analyze();
513         EXPECT_EQ(psu2.isPresent(), true);
514         EXPECT_EQ(psu2.isFaulted(), true);
515         EXPECT_EQ(psu2.hasInputFault(), false);
516         EXPECT_EQ(psu2.hasMFRFault(), false);
517         EXPECT_EQ(psu2.hasVINUVFault(), false);
518         EXPECT_EQ(psu2.hasCommFault(), false);
519         EXPECT_EQ(psu2.hasVoutOVFault(), false);
520         EXPECT_EQ(psu2.hasIoutOCFault(), false);
521         EXPECT_EQ(psu2.hasVoutUVFault(), false);
522         EXPECT_EQ(psu2.hasFanFault(), true);
523         EXPECT_EQ(psu2.hasTempFault(), false);
524         EXPECT_EQ(psu2.hasPgoodFault(), false);
525         EXPECT_EQ(psu2.hasPSKillFault(), false);
526         EXPECT_EQ(psu2.hasPS12VcsFault(), false);
527         EXPECT_EQ(psu2.hasPSCS12VFault(), false);
528     }
529 
530     // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT.
531     {
532         // First STATUS_WORD with no bits set.
533         PMBusExpectations expectations;
534         setPMBusExpectations(mockPMBus, expectations);
535         psu2.analyze();
536         EXPECT_EQ(psu2.isFaulted(), false);
537         // POWER_GOOD# inactive, and OFF bit on.
538         expectations.statusWordValue =
539             ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF));
540         for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
541         {
542             // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and
543             // STATUS_TEMPERATURE: Don't care if bits set or not (defaults).
544             setPMBusExpectations(mockPMBus, expectations);
545             psu2.analyze();
546             EXPECT_EQ(psu2.isPresent(), true);
547             if (x < DEGLITCH_LIMIT)
548             {
549                 EXPECT_EQ(psu2.isFaulted(), false);
550             }
551             else
552             {
553                 EXPECT_EQ(psu2.isFaulted(), true);
554             }
555             EXPECT_EQ(psu2.hasInputFault(), false);
556             EXPECT_EQ(psu2.hasMFRFault(), false);
557             EXPECT_EQ(psu2.hasVINUVFault(), false);
558             EXPECT_EQ(psu2.hasCommFault(), false);
559             EXPECT_EQ(psu2.hasVoutOVFault(), false);
560             EXPECT_EQ(psu2.hasVoutUVFault(), false);
561             EXPECT_EQ(psu2.hasIoutOCFault(), false);
562             EXPECT_EQ(psu2.hasFanFault(), false);
563             EXPECT_EQ(psu2.hasTempFault(), false);
564             if (x < DEGLITCH_LIMIT)
565             {
566                 EXPECT_EQ(psu2.hasPgoodFault(), false);
567             }
568             else
569             {
570                 EXPECT_EQ(psu2.hasPgoodFault(), true);
571             }
572         }
573     }
574 
575     // TODO: ReadFailure
576 }
577 
578 TEST_F(PowerSupplyTests, OnOffConfig)
579 {
580     auto bus = sdbusplus::bus::new_default();
581     uint8_t data = 0x15;
582 
583     // Test where PSU is NOT present
584     try
585     {
586         // Assume GPIO presence, not inventory presence?
587         PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
588 
589         MockedGPIOInterface* mockPresenceGPIO =
590             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
591         ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0));
592         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
593         // Constructor should set initial presence, default read returns 0.
594         // If it is not present, I should not be trying to write to it.
595         EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0);
596         psu.onOffConfig(data);
597     }
598     catch (...)
599     {}
600 
601     // Test where PSU is present
602     try
603     {
604         // Assume GPIO presence, not inventory presence?
605         PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
606         MockedGPIOInterface* mockPresenceGPIO =
607             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
608         // There will potentially be multiple calls, we want it to continue
609         // returning 1 for the GPIO read to keep the power supply present.
610         EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
611         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
612         setMissingToPresentExpects(mockPMBus, mockedUtil);
613         // If I am calling analyze(), I should probably give it good data.
614         // STATUS_WORD 0x0000 is powered on, no faults.
615         PMBusExpectations expectations;
616         setPMBusExpectations(mockPMBus, expectations);
617         psu.analyze();
618         // I definitely should be writting ON_OFF_CONFIG if I call the function
619         EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, ElementsAre(0x15),
620                                            Type::HwmonDeviceDebug))
621             .Times(1);
622         psu.onOffConfig(data);
623     }
624     catch (...)
625     {}
626 }
627 
628 TEST_F(PowerSupplyTests, ClearFaults)
629 {
630     auto bus = sdbusplus::bus::new_default();
631     PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, PSUGPIOLineName};
632     MockedGPIOInterface* mockPresenceGPIO =
633         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
634     // Always return 1 to indicate present.
635     // Each analyze() call will trigger a read of the presence GPIO.
636     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
637     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
638     setMissingToPresentExpects(mockPMBus, mockedUtil);
639     // STATUS_WORD 0x0000 is powered on, no faults.
640     PMBusExpectations expectations;
641     setPMBusExpectations(mockPMBus, expectations);
642     psu.analyze();
643     EXPECT_EQ(psu.isPresent(), true);
644     EXPECT_EQ(psu.isFaulted(), false);
645     EXPECT_EQ(psu.hasInputFault(), false);
646     EXPECT_EQ(psu.hasMFRFault(), false);
647     EXPECT_EQ(psu.hasVINUVFault(), false);
648     EXPECT_EQ(psu.hasCommFault(), false);
649     EXPECT_EQ(psu.hasVoutOVFault(), false);
650     EXPECT_EQ(psu.hasIoutOCFault(), false);
651     EXPECT_EQ(psu.hasVoutUVFault(), false);
652     EXPECT_EQ(psu.hasFanFault(), false);
653     EXPECT_EQ(psu.hasTempFault(), false);
654     EXPECT_EQ(psu.hasPgoodFault(), false);
655     EXPECT_EQ(psu.hasPSKillFault(), false);
656     EXPECT_EQ(psu.hasPS12VcsFault(), false);
657     EXPECT_EQ(psu.hasPSCS12VFault(), false);
658 
659     // STATUS_WORD with fault bits galore!
660     expectations.statusWordValue = 0xFFFF;
661     // STATUS_INPUT with fault bits on.
662     expectations.statusInputValue = 0xFF;
663     // STATUS_MFR_SPEFIC with bits on.
664     expectations.statusMFRValue = 0xFF;
665     // STATUS_CML with bits on.
666     expectations.statusCMLValue = 0xFF;
667     // STATUS_VOUT with bits on.
668     expectations.statusVOUTValue = 0xFF;
669     // STATUS_IOUT with bits on.
670     expectations.statusIOUTValue = 0xFF;
671     // STATUS_FANS_1_2 with bits on.
672     expectations.statusFans12Value = 0xFF;
673     // STATUS_TEMPERATURE with bits on.
674     expectations.statusTempValue = 0xFF;
675     setPMBusExpectations(mockPMBus, expectations);
676     psu.analyze();
677     EXPECT_EQ(psu.isPresent(), true);
678     EXPECT_EQ(psu.isFaulted(), true);
679     EXPECT_EQ(psu.hasInputFault(), true);
680     EXPECT_EQ(psu.hasMFRFault(), true);
681     EXPECT_EQ(psu.hasVINUVFault(), true);
682     EXPECT_EQ(psu.hasCommFault(), true);
683     EXPECT_EQ(psu.hasVoutOVFault(), true);
684     EXPECT_EQ(psu.hasIoutOCFault(), true);
685     // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
686     // Rely on HasVoutUVFault() to verify this sets and clears.
687     EXPECT_EQ(psu.hasVoutUVFault(), false);
688     EXPECT_EQ(psu.hasFanFault(), true);
689     EXPECT_EQ(psu.hasTempFault(), true);
690     // pgoodFault is deglitched up to DEGLITCH_LIMIT
691     EXPECT_EQ(psu.hasPgoodFault(), false);
692     setPMBusExpectations(mockPMBus, expectations);
693     psu.analyze();
694     EXPECT_EQ(psu.hasPgoodFault(), false);
695     setPMBusExpectations(mockPMBus, expectations);
696     psu.analyze();
697     // DEGLITCH_LIMIT reached for pgoodFault
698     EXPECT_EQ(psu.hasPgoodFault(), true);
699     EXPECT_EQ(psu.hasPSKillFault(), true);
700     EXPECT_EQ(psu.hasPS12VcsFault(), true);
701     EXPECT_EQ(psu.hasPSCS12VFault(), true);
702 
703     EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(207000));
704     psu.clearFaults();
705     EXPECT_EQ(psu.isPresent(), true);
706     EXPECT_EQ(psu.isFaulted(), false);
707     EXPECT_EQ(psu.hasInputFault(), false);
708     EXPECT_EQ(psu.hasMFRFault(), false);
709     EXPECT_EQ(psu.hasVINUVFault(), false);
710     EXPECT_EQ(psu.hasCommFault(), false);
711     EXPECT_EQ(psu.hasVoutOVFault(), false);
712     EXPECT_EQ(psu.hasIoutOCFault(), false);
713     EXPECT_EQ(psu.hasVoutUVFault(), false);
714     EXPECT_EQ(psu.hasFanFault(), false);
715     EXPECT_EQ(psu.hasTempFault(), false);
716     EXPECT_EQ(psu.hasPgoodFault(), false);
717     EXPECT_EQ(psu.hasPSKillFault(), false);
718     EXPECT_EQ(psu.hasPS12VcsFault(), false);
719     EXPECT_EQ(psu.hasPSCS12VFault(), false);
720 
721     // TODO: Faults clear on missing/present?
722 }
723 
724 TEST_F(PowerSupplyTests, UpdateInventory)
725 {
726     auto bus = sdbusplus::bus::new_default();
727 
728     try
729     {
730         PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
731         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
732         // If it is not present, I should not be trying to read a string
733         EXPECT_CALL(mockPMBus, readString(_, _)).Times(0);
734         psu.updateInventory();
735     }
736     catch (...)
737     {
738         ADD_FAILURE() << "Should not have caught exception.";
739     }
740 
741     try
742     {
743         PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, PSUGPIOLineName};
744         MockedGPIOInterface* mockPresenceGPIO =
745             static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
746         // GPIO read return 1 to indicate present.
747         EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
748         MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
749         setMissingToPresentExpects(mockPMBus, mockedUtil);
750         // STATUS_WORD 0x0000 is powered on, no faults.
751         PMBusExpectations expectations;
752         setPMBusExpectations(mockPMBus, expectations);
753         // Need analyze call to update power supply from missing to present.
754         psu.analyze();
755         EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return(""));
756         psu.updateInventory();
757 
758 #if IBM_VPD
759         EXPECT_CALL(mockPMBus, readString(_, _))
760             .WillOnce(Return("CCIN"))
761             .WillOnce(Return("PN3456"))
762             .WillOnce(Return("FN3456"))
763             .WillOnce(Return("HEADER"))
764             .WillOnce(Return("SN3456"))
765             .WillOnce(Return("FW3456"));
766 #endif
767         psu.updateInventory();
768         // TODO: D-Bus mocking to verify values stored on D-Bus (???)
769     }
770     catch (...)
771     {
772         ADD_FAILURE() << "Should not have caught exception.";
773     }
774 }
775 
776 TEST_F(PowerSupplyTests, IsPresent)
777 {
778     auto bus = sdbusplus::bus::new_default();
779 
780     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
781     MockedGPIOInterface* mockPresenceGPIO =
782         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
783     EXPECT_EQ(psu.isPresent(), false);
784 
785     // Change GPIO read to return 1 to indicate present.
786     EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
787     // Call to analyze() will update to present, that will trigger updating
788     // to the correct/latest HWMON directory, in case it changes.
789     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
790     setMissingToPresentExpects(mockPMBus, mockedUtil);
791     // Call to analyze things will trigger read of STATUS_WORD and READ_VIN.
792     // Default expectations will be on, no faults.
793     PMBusExpectations expectations;
794     setPMBusExpectations(mockPMBus, expectations);
795     psu.analyze();
796     EXPECT_EQ(psu.isPresent(), true);
797 }
798 
799 TEST_F(PowerSupplyTests, IsFaulted)
800 {
801     auto bus = sdbusplus::bus::new_default();
802 
803     PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, PSUGPIOLineName};
804     MockedGPIOInterface* mockPresenceGPIO =
805         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
806     // Always return 1 to indicate present.
807     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
808     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
809     setMissingToPresentExpects(mockPMBus, mockedUtil);
810     // Call to analyze things will trigger read of STATUS_WORD and READ_VIN.
811     // Default expectations will be on, no faults.
812     PMBusExpectations expectations;
813     setPMBusExpectations(mockPMBus, expectations);
814     psu.analyze();
815     EXPECT_EQ(psu.isFaulted(), false);
816     // STATUS_WORD with fault bits on.
817     expectations.statusWordValue = 0xFFFF;
818     // STATUS_INPUT with fault bits on.
819     expectations.statusInputValue = 0xFF;
820     // STATUS_MFR_SPECIFIC with faults bits on.
821     expectations.statusMFRValue = 0xFF;
822     // STATUS_CML with faults bits on.
823     expectations.statusCMLValue = 0xFF;
824     // STATUS_VOUT with fault bits on.
825     expectations.statusVOUTValue = 0xFF;
826     // STATUS_IOUT with fault bits on.
827     expectations.statusIOUTValue = 0xFF;
828     // STATUS_FANS_1_2 with bits on.
829     expectations.statusFans12Value = 0xFF;
830     // STATUS_TEMPERATURE with fault bits on.
831     expectations.statusTempValue = 0xFF;
832     setPMBusExpectations(mockPMBus, expectations);
833     psu.analyze();
834     EXPECT_EQ(psu.isFaulted(), true);
835 }
836 
837 TEST_F(PowerSupplyTests, HasInputFault)
838 {
839     auto bus = sdbusplus::bus::new_default();
840 
841     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
842     MockedGPIOInterface* mockPresenceGPIO =
843         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
844     // Always return 1 to indicate present.
845     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
846     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
847     setMissingToPresentExpects(mockPMBus, mockedUtil);
848     // STATUS_WORD 0x0000 is powered on, no faults.
849     PMBusExpectations expectations;
850     setPMBusExpectations(mockPMBus, expectations);
851     psu.analyze();
852     EXPECT_EQ(psu.hasInputFault(), false);
853     // STATUS_WORD with input fault/warn on.
854     expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
855     // STATUS_INPUT with an input fault bit on.
856     expectations.statusInputValue = 0x80;
857     setPMBusExpectations(mockPMBus, expectations);
858     psu.analyze();
859     EXPECT_EQ(psu.hasInputFault(), true);
860     // STATUS_WORD with no bits on.
861     expectations.statusWordValue = 0;
862     setPMBusExpectations(mockPMBus, expectations);
863     psu.analyze();
864     EXPECT_EQ(psu.hasInputFault(), false);
865 }
866 
867 TEST_F(PowerSupplyTests, HasMFRFault)
868 {
869     auto bus = sdbusplus::bus::new_default();
870 
871     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
872     MockedGPIOInterface* mockPresenceGPIO =
873         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
874     // Always return 1 to indicate present.
875     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
876     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
877     setMissingToPresentExpects(mockPMBus, mockedUtil);
878     // First return STATUS_WORD with no bits on.
879     // STATUS_WORD 0x0000 is powered on, no faults.
880     PMBusExpectations expectations;
881     setPMBusExpectations(mockPMBus, expectations);
882     psu.analyze();
883     EXPECT_EQ(psu.hasMFRFault(), false);
884     // Next return STATUS_WORD with MFR fault bit on.
885     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
886     // STATUS_MFR_SPEFIC with bit(s) on.
887     expectations.statusMFRValue = 0xFF;
888     setPMBusExpectations(mockPMBus, expectations);
889     psu.analyze();
890     EXPECT_EQ(psu.hasMFRFault(), true);
891     // Back to no bits on in STATUS_WORD
892     expectations.statusWordValue = 0;
893     setPMBusExpectations(mockPMBus, expectations);
894     psu.analyze();
895     EXPECT_EQ(psu.hasMFRFault(), false);
896 }
897 
898 TEST_F(PowerSupplyTests, HasVINUVFault)
899 {
900     auto bus = sdbusplus::bus::new_default();
901 
902     PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
903     MockedGPIOInterface* mockPresenceGPIO =
904         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
905     // Always return 1 to indicate present.
906     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
907     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
908     setMissingToPresentExpects(mockPMBus, mockedUtil);
909     // STATUS_WORD 0x0000 is powered on, no faults.
910     PMBusExpectations expectations;
911     setPMBusExpectations(mockPMBus, expectations);
912     psu.analyze();
913     EXPECT_EQ(psu.hasVINUVFault(), false);
914     // Turn fault on.
915     expectations.statusWordValue = (status_word::VIN_UV_FAULT);
916     // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by
917     // Figure 16, and assume bits on in STATUS_INPUT.
918     expectations.statusInputValue = 0x18;
919     setPMBusExpectations(mockPMBus, expectations);
920     psu.analyze();
921     EXPECT_EQ(psu.hasVINUVFault(), true);
922     // Back to no fault bits on in STATUS_WORD
923     expectations.statusWordValue = 0;
924     setPMBusExpectations(mockPMBus, expectations);
925     psu.analyze();
926     EXPECT_EQ(psu.hasVINUVFault(), false);
927 }
928 
929 TEST_F(PowerSupplyTests, HasVoutOVFault)
930 {
931     auto bus = sdbusplus::bus::new_default();
932 
933     PowerSupply psu{bus, PSUInventoryPath, 3, 0x69, PSUGPIOLineName};
934     MockedGPIOInterface* mockPresenceGPIO =
935         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
936     // Always return 1 to indicate present.
937     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
938     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
939     setMissingToPresentExpects(mockPMBus, mockedUtil);
940     // STATUS_WORD 0x0000 is powered on, no faults.
941     PMBusExpectations expectations;
942     setPMBusExpectations(mockPMBus, expectations);
943     psu.analyze();
944     EXPECT_EQ(psu.hasVoutOVFault(), false);
945     // Turn fault on.
946     expectations.statusWordValue = (status_word::VOUT_OV_FAULT);
947     // STATUS_VOUT fault bit(s)
948     expectations.statusVOUTValue = 0x80;
949     // STATUS_TEMPERATURE default.
950     setPMBusExpectations(mockPMBus, expectations);
951     psu.analyze();
952     EXPECT_EQ(psu.hasVoutOVFault(), true);
953     // Back to no fault bits on in STATUS_WORD
954     expectations.statusWordValue = 0;
955     setPMBusExpectations(mockPMBus, expectations);
956     psu.analyze();
957     EXPECT_EQ(psu.hasVoutOVFault(), false);
958 }
959 
960 TEST_F(PowerSupplyTests, HasIoutOCFault)
961 {
962     auto bus = sdbusplus::bus::new_default();
963 
964     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName};
965     MockedGPIOInterface* mockPresenceGPIO =
966         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
967     // Always return 1 to indicate present.
968     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
969     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
970     setMissingToPresentExpects(mockPMBus, mockedUtil);
971     // STATUS_WORD 0x0000 is powered on, no faults.
972     PMBusExpectations expectations;
973     setPMBusExpectations(mockPMBus, expectations);
974     psu.analyze();
975     EXPECT_EQ(psu.hasIoutOCFault(), false);
976     // Turn fault on.
977     expectations.statusWordValue = status_word::IOUT_OC_FAULT;
978     // STATUS_IOUT fault bit(s)
979     expectations.statusIOUTValue = 0x88;
980     setPMBusExpectations(mockPMBus, expectations);
981     psu.analyze();
982     EXPECT_EQ(psu.hasIoutOCFault(), true);
983     // Back to no fault bits on in STATUS_WORD
984     expectations.statusWordValue = 0;
985     setPMBusExpectations(mockPMBus, expectations);
986     psu.analyze();
987     EXPECT_EQ(psu.hasIoutOCFault(), false);
988 }
989 
990 TEST_F(PowerSupplyTests, HasVoutUVFault)
991 {
992     auto bus = sdbusplus::bus::new_default();
993 
994     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName};
995     MockedGPIOInterface* mockPresenceGPIO =
996         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
997     // Always return 1 to indicate present.
998     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
999     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1000     setMissingToPresentExpects(mockPMBus, mockedUtil);
1001     // STATUS_WORD 0x0000 is powered on, no faults.
1002     PMBusExpectations expectations;
1003     setPMBusExpectations(mockPMBus, expectations);
1004     psu.analyze();
1005     EXPECT_EQ(psu.hasVoutUVFault(), false);
1006     // Turn fault on.
1007     expectations.statusWordValue = (status_word::VOUT_FAULT);
1008     // STATUS_VOUT fault bit(s)
1009     expectations.statusVOUTValue = 0x30;
1010     setPMBusExpectations(mockPMBus, expectations);
1011     psu.analyze();
1012     EXPECT_EQ(psu.hasVoutUVFault(), true);
1013     // Back to no fault bits on in STATUS_WORD
1014     expectations.statusWordValue = 0;
1015     setPMBusExpectations(mockPMBus, expectations);
1016     psu.analyze();
1017     EXPECT_EQ(psu.hasVoutUVFault(), false);
1018 }
1019 
1020 TEST_F(PowerSupplyTests, HasFanFault)
1021 {
1022     auto bus = sdbusplus::bus::new_default();
1023 
1024     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName};
1025     MockedGPIOInterface* mockPresenceGPIO =
1026         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1027     // Always return 1 to indicate present.
1028     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1029     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1030     setMissingToPresentExpects(mockPMBus, mockedUtil);
1031     // STATUS_WORD 0x0000 is powered on, no faults.
1032     PMBusExpectations expectations;
1033     setPMBusExpectations(mockPMBus, expectations);
1034     psu.analyze();
1035     EXPECT_EQ(psu.hasFanFault(), false);
1036     // Turn fault on.
1037     expectations.statusWordValue = (status_word::FAN_FAULT);
1038     // STATUS_FANS_1_2 fault bit on (Fan 1 Fault)
1039     expectations.statusFans12Value = 0x80;
1040     setPMBusExpectations(mockPMBus, expectations);
1041     psu.analyze();
1042     EXPECT_EQ(psu.hasFanFault(), true);
1043     // Back to no fault bits on in STATUS_WORD
1044     expectations.statusWordValue = 0;
1045     setPMBusExpectations(mockPMBus, expectations);
1046     psu.analyze();
1047     EXPECT_EQ(psu.hasFanFault(), false);
1048 }
1049 
1050 TEST_F(PowerSupplyTests, HasTempFault)
1051 {
1052     auto bus = sdbusplus::bus::new_default();
1053 
1054     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName};
1055     MockedGPIOInterface* mockPresenceGPIO =
1056         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1057     // Always return 1 to indicate present.
1058     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1059     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1060     setMissingToPresentExpects(mockPMBus, mockedUtil);
1061     // STATUS_WORD 0x0000 is powered on, no faults.
1062     PMBusExpectations expectations;
1063     setPMBusExpectations(mockPMBus, expectations);
1064     psu.analyze();
1065     EXPECT_EQ(psu.hasTempFault(), false);
1066     // Turn fault on.
1067     expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
1068     // STATUS_TEMPERATURE fault bit on (OT Fault)
1069     expectations.statusTempValue = 0x80;
1070     setPMBusExpectations(mockPMBus, expectations);
1071     psu.analyze();
1072     EXPECT_EQ(psu.hasTempFault(), true);
1073     // Back to no fault bits on in STATUS_WORD
1074     expectations.statusWordValue = 0;
1075     setPMBusExpectations(mockPMBus, expectations);
1076     psu.analyze();
1077     EXPECT_EQ(psu.hasTempFault(), false);
1078 }
1079 
1080 TEST_F(PowerSupplyTests, HasPgoodFault)
1081 {
1082     auto bus = sdbusplus::bus::new_default();
1083 
1084     PowerSupply psu{bus, PSUInventoryPath, 3, 0x6b, PSUGPIOLineName};
1085     MockedGPIOInterface* mockPresenceGPIO =
1086         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1087     // Always return 1 to indicate present.
1088     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1089     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1090     setMissingToPresentExpects(mockPMBus, mockedUtil);
1091     // STATUS_WORD 0x0000 is powered on, no faults.
1092     PMBusExpectations expectations;
1093     setPMBusExpectations(mockPMBus, expectations);
1094     psu.analyze();
1095     EXPECT_EQ(psu.hasPgoodFault(), false);
1096     // Setup another expectation of no faults.
1097     setPMBusExpectations(mockPMBus, expectations);
1098     psu.analyze();
1099     EXPECT_EQ(psu.hasPgoodFault(), false);
1100     // Turn PGOOD# off (fault on).
1101     expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED);
1102     setPMBusExpectations(mockPMBus, expectations);
1103     psu.analyze();
1104     // Expect false until reaches DEGLITCH_LIMIT
1105     EXPECT_EQ(psu.hasPgoodFault(), false);
1106     setPMBusExpectations(mockPMBus, expectations);
1107     psu.analyze();
1108     // Expect false until reaches DEGLITCH_LIMIT
1109     EXPECT_EQ(psu.hasPgoodFault(), false);
1110     setPMBusExpectations(mockPMBus, expectations);
1111     psu.analyze();
1112     // DEGLITCH_LIMIT reached, expect true.
1113     EXPECT_EQ(psu.hasPgoodFault(), true);
1114     // Back to no fault bits on in STATUS_WORD
1115     expectations.statusWordValue = 0;
1116     setPMBusExpectations(mockPMBus, expectations);
1117     psu.analyze();
1118     EXPECT_EQ(psu.hasPgoodFault(), false);
1119     // Turn OFF bit on
1120     expectations.statusWordValue = (status_word::UNIT_IS_OFF);
1121     setPMBusExpectations(mockPMBus, expectations);
1122     psu.analyze();
1123     EXPECT_EQ(psu.hasPgoodFault(), false);
1124     setPMBusExpectations(mockPMBus, expectations);
1125     psu.analyze();
1126     EXPECT_EQ(psu.hasPgoodFault(), false);
1127     setPMBusExpectations(mockPMBus, expectations);
1128     psu.analyze();
1129     EXPECT_EQ(psu.hasPgoodFault(), true);
1130     // Back to no fault bits on in STATUS_WORD
1131     expectations.statusWordValue = 0;
1132     setPMBusExpectations(mockPMBus, expectations);
1133     psu.analyze();
1134     EXPECT_EQ(psu.hasPgoodFault(), false);
1135 }
1136 
1137 TEST_F(PowerSupplyTests, HasPSKillFault)
1138 {
1139     auto bus = sdbusplus::bus::new_default();
1140     PowerSupply psu{bus, PSUInventoryPath, 4, 0x6d, PSUGPIOLineName};
1141     MockedGPIOInterface* mockPresenceGPIO =
1142         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1143     // Always return 1 to indicate present.
1144     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1145     psu.analyze();
1146     EXPECT_EQ(psu.hasPSKillFault(), false);
1147     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1148     // STATUS_WORD 0x0000 is powered on, no faults.
1149     PMBusExpectations expectations;
1150     setPMBusExpectations(mockPMBus, expectations);
1151     psu.analyze();
1152     EXPECT_EQ(psu.hasPSKillFault(), false);
1153     // Next return STATUS_WORD with MFR fault bit on.
1154     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1155     // STATUS_MFR_SPEFIC with bit(s) on.
1156     expectations.statusMFRValue = 0xFF;
1157     setPMBusExpectations(mockPMBus, expectations);
1158     psu.analyze();
1159     EXPECT_EQ(psu.hasPSKillFault(), true);
1160     // Back to no bits on in STATUS_WORD
1161     expectations.statusWordValue = 0;
1162     setPMBusExpectations(mockPMBus, expectations);
1163     psu.analyze();
1164     EXPECT_EQ(psu.hasPSKillFault(), false);
1165     // Next return STATUS_WORD with MFR fault bit on.
1166     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1167     // STATUS_MFR_SPEFIC with bit 4 on.
1168     expectations.statusMFRValue = 0x10;
1169     setPMBusExpectations(mockPMBus, expectations);
1170     psu.analyze();
1171     EXPECT_EQ(psu.hasPSKillFault(), true);
1172     // Back to no bits on in STATUS_WORD
1173     expectations.statusWordValue = 0;
1174     setPMBusExpectations(mockPMBus, expectations);
1175     psu.analyze();
1176     EXPECT_EQ(psu.hasPSKillFault(), false);
1177 }
1178 
1179 TEST_F(PowerSupplyTests, HasPS12VcsFault)
1180 {
1181     auto bus = sdbusplus::bus::new_default();
1182     PowerSupply psu{bus, PSUInventoryPath, 5, 0x6e, PSUGPIOLineName};
1183     MockedGPIOInterface* mockPresenceGPIO =
1184         static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1185     // Always return 1 to indicate present.
1186     EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1187     psu.analyze();
1188     EXPECT_EQ(psu.hasPS12VcsFault(), false);
1189     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1190     // STATUS_WORD 0x0000 is powered on, no faults.
1191     PMBusExpectations expectations;
1192     setPMBusExpectations(mockPMBus, expectations);
1193     psu.analyze();
1194     EXPECT_EQ(psu.hasPS12VcsFault(), false);
1195     // Next return STATUS_WORD with MFR fault bit on.
1196     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1197     // STATUS_MFR_SPEFIC with bit(s) on.
1198     expectations.statusMFRValue = 0xFF;
1199     setPMBusExpectations(mockPMBus, expectations);
1200     psu.analyze();
1201     EXPECT_EQ(psu.hasPS12VcsFault(), true);
1202     // Back to no bits on in STATUS_WORD
1203     expectations.statusWordValue = 0;
1204     setPMBusExpectations(mockPMBus, expectations);
1205     psu.analyze();
1206     EXPECT_EQ(psu.hasPS12VcsFault(), false);
1207     // Next return STATUS_WORD with MFR fault bit on.
1208     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1209     // STATUS_MFR_SPEFIC with bit 6 on.
1210     expectations.statusMFRValue = 0x40;
1211     setPMBusExpectations(mockPMBus, expectations);
1212     psu.analyze();
1213     EXPECT_EQ(psu.hasPS12VcsFault(), true);
1214     // Back to no bits on in STATUS_WORD
1215     expectations.statusWordValue = 0;
1216     setPMBusExpectations(mockPMBus, expectations);
1217     psu.analyze();
1218     EXPECT_EQ(psu.hasPS12VcsFault(), false);
1219 }
1220 
1221 TEST_F(PowerSupplyTests, HasPSCS12VFault)
1222 {
1223     auto bus = sdbusplus::bus::new_default();
1224     PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f, 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     psu.analyze();
1230     EXPECT_EQ(psu.hasPSCS12VFault(), false);
1231     MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1232     // STATUS_WORD 0x0000 is powered on, no faults.
1233     PMBusExpectations expectations;
1234     setPMBusExpectations(mockPMBus, expectations);
1235     psu.analyze();
1236     EXPECT_EQ(psu.hasPSCS12VFault(), false);
1237     // Next return STATUS_WORD with MFR fault bit on.
1238     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1239     // STATUS_MFR_SPEFIC with bit(s) on.
1240     expectations.statusMFRValue = 0xFF;
1241     setPMBusExpectations(mockPMBus, expectations);
1242     psu.analyze();
1243     EXPECT_EQ(psu.hasPSCS12VFault(), true);
1244     // Back to no bits on in STATUS_WORD
1245     expectations.statusWordValue = 0;
1246     setPMBusExpectations(mockPMBus, expectations);
1247     psu.analyze();
1248     EXPECT_EQ(psu.hasPSCS12VFault(), false);
1249     // Next return STATUS_WORD with MFR fault bit on.
1250     expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1251     // STATUS_MFR_SPEFIC with bit 7 on.
1252     expectations.statusMFRValue = 0x80;
1253     setPMBusExpectations(mockPMBus, expectations);
1254     psu.analyze();
1255     EXPECT_EQ(psu.hasPSCS12VFault(), true);
1256     // Back to no bits on in STATUS_WORD
1257     expectations.statusWordValue = 0;
1258     setPMBusExpectations(mockPMBus, expectations);
1259     psu.analyze();
1260     EXPECT_EQ(psu.hasPSCS12VFault(), false);
1261 }
1262