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