blob: 5d96fea995fda0eed46cadeb57ba36d8aa66d4e5 [file] [log] [blame]
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001#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
10using namespace phosphor::power::psu;
11using namespace phosphor::pmbus;
12
13using ::testing::_;
Brandon Wyman59a35792020-06-04 12:37:40 -050014using ::testing::Args;
Brandon Wyman3f1242f2020-01-28 13:11:25 -060015using ::testing::Assign;
16using ::testing::DoAll;
Brandon Wyman59a35792020-06-04 12:37:40 -050017using ::testing::ElementsAre;
18using ::testing::NotNull;
Brandon Wyman3f1242f2020-01-28 13:11:25 -060019using ::testing::Return;
20using ::testing::StrEq;
21
22static auto PSUInventoryPath = "/xyz/bmc/inv/sys/chassis/board/powersupply0";
B. J. Wyman681b2a32021-04-20 22:31:22 +000023static auto PSUGPIOLineName = "presence-ps0";
Brandon Wyman3f1242f2020-01-28 13:11:25 -060024
Brandon Wymanb654c612021-11-05 23:24:51 +000025struct 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};
Brandon Wyman96893a42021-11-05 19:56:57 +000032 uint8_t statusTempValue{0x00};
Brandon Wymanb654c612021-11-05 23:24:51 +000033};
34
Brandon Wyman8da35c52021-10-28 22:45:08 +000035// Helper function to setup expectations for various STATUS_* commands
Brandon Wymanb654c612021-11-05 23:24:51 +000036void setPMBusExpectations(MockedPMBus& mockPMBus,
37 const PMBusExpectations& expectations)
Brandon Wyman8da35c52021-10-28 22:45:08 +000038{
39 EXPECT_CALL(mockPMBus, read(STATUS_WORD, _))
40 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000041 .WillOnce(Return(expectations.statusWordValue));
Brandon Wyman8da35c52021-10-28 22:45:08 +000042
Brandon Wymanb654c612021-11-05 23:24:51 +000043 if (expectations.statusWordValue != 0)
Brandon Wyman8da35c52021-10-28 22:45:08 +000044 {
45 // If fault bits are on in STATUS_WORD, there will also be a read of
Brandon Wyman96893a42021-11-05 19:56:57 +000046 // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT (page 0), and
47 // STATUS_TEMPERATURE.
Brandon Wyman8da35c52021-10-28 22:45:08 +000048 EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _))
49 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000050 .WillOnce(Return(expectations.statusInputValue));
Brandon Wyman8da35c52021-10-28 22:45:08 +000051 EXPECT_CALL(mockPMBus, read(STATUS_MFR, _))
52 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000053 .WillOnce(Return(expectations.statusMFRValue));
Brandon Wyman8da35c52021-10-28 22:45:08 +000054 EXPECT_CALL(mockPMBus, read(STATUS_CML, _))
55 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000056 .WillOnce(Return(expectations.statusCMLValue));
Brandon Wyman6710ba22021-10-27 17:39:31 +000057 // Page will need to be set to 0 to read STATUS_VOUT.
58 EXPECT_CALL(mockPMBus, insertPageNum(STATUS_VOUT, 0))
59 .Times(1)
60 .WillOnce(Return("status0_vout"));
61 EXPECT_CALL(mockPMBus, read("status0_vout", _))
62 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000063 .WillOnce(Return(expectations.statusVOUTValue));
Brandon Wyman96893a42021-11-05 19:56:57 +000064 EXPECT_CALL(mockPMBus, read(STATUS_TEMPERATURE, _))
65 .Times(1)
66 .WillOnce(Return(expectations.statusTempValue));
Brandon Wyman8da35c52021-10-28 22:45:08 +000067 }
68}
69
Brandon Wyman3f1242f2020-01-28 13:11:25 -060070class PowerSupplyTests : public ::testing::Test
71{
72 public:
73 PowerSupplyTests() :
74 mockedUtil(reinterpret_cast<const MockedUtil&>(getUtils()))
75 {
76 ON_CALL(mockedUtil, getPresence(_, _)).WillByDefault(Return(false));
77 }
78
79 ~PowerSupplyTests() override
80 {
81 freeUtils();
82 }
83
84 const MockedUtil& mockedUtil;
85};
86
87TEST_F(PowerSupplyTests, Constructor)
88{
89 /**
90 * @param[in] invpath - String for inventory path to use
91 * @param[in] i2cbus - The bus number this power supply is on
92 * @param[in] i2caddr - The 16-bit I2C address of the power supply
B. J. Wyman681b2a32021-04-20 22:31:22 +000093 * @param[in] gpioLineName - The string for the gpio-line-name to read for
94 * presence.
95 * @param[in] bindDelay - Time in milliseconds to delay binding the device
96 * driver after seeing the presence line go active.
Brandon Wyman3f1242f2020-01-28 13:11:25 -060097 */
98 auto bus = sdbusplus::bus::new_default();
Brandon Wyman3f1242f2020-01-28 13:11:25 -060099
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500100 // Try where inventory path is empty, constructor should fail.
101 try
102 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000103 auto psu =
104 std::make_unique<PowerSupply>(bus, "", 3, 0x68, PSUGPIOLineName);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500105 ADD_FAILURE() << "Should not have reached this line.";
106 }
107 catch (const std::invalid_argument& e)
108 {
109 EXPECT_STREQ(e.what(), "Invalid empty inventoryPath");
110 }
111 catch (...)
112 {
113 ADD_FAILURE() << "Should not have caught exception.";
114 }
115
B. J. Wyman681b2a32021-04-20 22:31:22 +0000116 // TODO: Try invalid i2c address?
117
118 // Try where gpioLineName is empty.
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500119 try
120 {
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500121 auto psu =
B. J. Wyman681b2a32021-04-20 22:31:22 +0000122 std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, "");
123 ADD_FAILURE()
124 << "Should not have reached this line. Invalid gpioLineName.";
125 }
126 catch (const std::invalid_argument& e)
127 {
128 EXPECT_STREQ(e.what(), "Invalid empty gpioLineName");
129 }
130 catch (...)
131 {
132 ADD_FAILURE() << "Should not have caught exception.";
133 }
134
135 // Test with valid arguments
136 // NOT using D-Bus inventory path for presence.
137 try
138 {
139 auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68,
140 PSUGPIOLineName);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500141
142 EXPECT_EQ(psu->isPresent(), false);
143 EXPECT_EQ(psu->isFaulted(), false);
Brandon Wyman8da35c52021-10-28 22:45:08 +0000144 EXPECT_EQ(psu->hasCommFault(), false);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500145 EXPECT_EQ(psu->hasInputFault(), false);
146 EXPECT_EQ(psu->hasMFRFault(), false);
147 EXPECT_EQ(psu->hasVINUVFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000148 EXPECT_EQ(psu->hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000149 EXPECT_EQ(psu->hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000150 EXPECT_EQ(psu->hasPgoodFault(), false);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500151 }
152 catch (...)
153 {
154 ADD_FAILURE() << "Should not have caught exception.";
155 }
B. J. Wyman681b2a32021-04-20 22:31:22 +0000156
157 // Test with valid arguments
158 // TODO: Using D-Bus inventory path for presence.
159 try
160 {
161 // FIXME: How do I get that presenceGPIO.read() in the startup to throw
162 // an exception?
163
164 // EXPECT_CALL(mockedUtil, getPresence(_,
165 // StrEq(PSUInventoryPath)))
166 // .Times(1);
167 }
168 catch (...)
169 {
170 ADD_FAILURE() << "Should not have caught exception.";
171 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600172}
173
174TEST_F(PowerSupplyTests, Analyze)
175{
176 auto bus = sdbusplus::bus::new_default();
177
Brandon Wymanb654c612021-11-05 23:24:51 +0000178 {
179 // If I default to reading the GPIO, I will NOT expect a call to
180 // getPresence().
B. J. Wyman681b2a32021-04-20 22:31:22 +0000181
Brandon Wymanb654c612021-11-05 23:24:51 +0000182 PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
183 MockedGPIOInterface* mockPresenceGPIO =
184 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
185 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000186
Brandon Wymanb654c612021-11-05 23:24:51 +0000187 psu.analyze();
188 // By default, nothing should change.
189 EXPECT_EQ(psu.isPresent(), false);
190 EXPECT_EQ(psu.isFaulted(), false);
191 EXPECT_EQ(psu.hasInputFault(), false);
192 EXPECT_EQ(psu.hasMFRFault(), false);
193 EXPECT_EQ(psu.hasVINUVFault(), false);
194 EXPECT_EQ(psu.hasCommFault(), false);
195 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000196 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000197 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000198 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600199
B. J. Wyman681b2a32021-04-20 22:31:22 +0000200 PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
201 // In order to get the various faults tested, the power supply needs to
202 // be present in order to read from the PMBus device(s).
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000203 MockedGPIOInterface* mockPresenceGPIO2 =
204 static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000205 ON_CALL(*mockPresenceGPIO2, read()).WillByDefault(Return(1));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000206 EXPECT_EQ(psu2.isPresent(), false);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600207
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600208 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus());
Brandon Wyman8da35c52021-10-28 22:45:08 +0000209 // Presence change from missing to present will trigger write to
210 // ON_OFF_CONFIG.
211 EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, _, _));
Brandon Wymanb654c612021-11-05 23:24:51 +0000212 // Presence change from missing to present will trigger in1_input read
213 // in an attempt to get CLEAR_FAULTS called.
Brandon Wymanf07bc792021-10-12 19:00:35 +0000214 EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(206000));
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600215
Brandon Wymanb654c612021-11-05 23:24:51 +0000216 // STATUS_WORD INPUT fault.
217 {
218 // Start with STATUS_WORD 0x0000. Powered on, no faults.
219 // Set expectations for a no fault
220 PMBusExpectations expectations;
221 setPMBusExpectations(mockPMBus, expectations);
222 psu2.analyze();
223 EXPECT_EQ(psu2.isPresent(), true);
224 EXPECT_EQ(psu2.isFaulted(), false);
225 EXPECT_EQ(psu2.hasInputFault(), false);
226 EXPECT_EQ(psu2.hasMFRFault(), false);
227 EXPECT_EQ(psu2.hasVINUVFault(), false);
228 EXPECT_EQ(psu2.hasCommFault(), false);
229 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000230 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000231 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000232
233 // Update expectations for STATUS_WORD input fault/warn
Brandon Wyman96893a42021-11-05 19:56:57 +0000234 // STATUS_INPUT fault bits ... on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000235 expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
236 expectations.statusInputValue = 0x38;
237 setPMBusExpectations(mockPMBus, expectations);
238 psu2.analyze();
239 EXPECT_EQ(psu2.isPresent(), true);
240 EXPECT_EQ(psu2.isFaulted(), true);
241 EXPECT_EQ(psu2.hasInputFault(), true);
242 EXPECT_EQ(psu2.hasMFRFault(), false);
243 EXPECT_EQ(psu2.hasVINUVFault(), false);
244 EXPECT_EQ(psu2.hasCommFault(), false);
245 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000246 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000247 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000248 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600249
250 // STATUS_WORD INPUT/UV fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000251 {
252 // First need it to return good status, then the fault
253 PMBusExpectations expectations;
254 setPMBusExpectations(mockPMBus, expectations);
255 psu2.analyze();
256 // Now set fault bits in STATUS_WORD
257 expectations.statusWordValue =
258 (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT);
259 // STATUS_INPUT fault bits ... on.
260 expectations.statusInputValue = 0x38;
261 setPMBusExpectations(mockPMBus, expectations);
262 psu2.analyze();
263 EXPECT_EQ(psu2.isPresent(), true);
264 EXPECT_EQ(psu2.isFaulted(), true);
265 EXPECT_EQ(psu2.hasInputFault(), true);
266 EXPECT_EQ(psu2.hasMFRFault(), false);
267 EXPECT_EQ(psu2.hasVINUVFault(), true);
268 EXPECT_EQ(psu2.hasCommFault(), false);
269 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000270 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000271 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000272 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600273
274 // STATUS_WORD MFR fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000275 {
276 // First need it to return good status, then the fault
277 PMBusExpectations expectations;
278 setPMBusExpectations(mockPMBus, expectations);
279 psu2.analyze();
280 // Now STATUS_WORD with MFR fault bit on.
281 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
282 // STATUS_MFR bits on.
283 expectations.statusMFRValue = 0xFF;
284 setPMBusExpectations(mockPMBus, expectations);
285 psu2.analyze();
286 EXPECT_EQ(psu2.isPresent(), true);
287 EXPECT_EQ(psu2.isFaulted(), true);
288 EXPECT_EQ(psu2.hasInputFault(), false);
289 EXPECT_EQ(psu2.hasMFRFault(), true);
290 EXPECT_EQ(psu2.hasVINUVFault(), false);
291 EXPECT_EQ(psu2.hasCommFault(), false);
292 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000293 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000294 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000295 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600296
Brandon Wyman96893a42021-11-05 19:56:57 +0000297 // Temperature fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000298 {
299 // First STATUS_WORD with no bits set, then with temperature fault.
300 PMBusExpectations expectations;
301 setPMBusExpectations(mockPMBus, expectations);
302 psu2.analyze();
303 // STATUS_WORD with temperature fault bit on.
304 expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
Brandon Wyman96893a42021-11-05 19:56:57 +0000305 // STATUS_TEMPERATURE with fault bit(s) on.
306 expectations.statusTempValue = 0x10;
Brandon Wymanb654c612021-11-05 23:24:51 +0000307 setPMBusExpectations(mockPMBus, expectations);
308 psu2.analyze();
309 EXPECT_EQ(psu2.isPresent(), true);
Brandon Wyman96893a42021-11-05 19:56:57 +0000310 EXPECT_EQ(psu2.isFaulted(), true);
Brandon Wymanb654c612021-11-05 23:24:51 +0000311 EXPECT_EQ(psu2.hasInputFault(), false);
312 EXPECT_EQ(psu2.hasMFRFault(), false);
313 EXPECT_EQ(psu2.hasVINUVFault(), false);
314 EXPECT_EQ(psu2.hasCommFault(), false);
315 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000316 EXPECT_EQ(psu2.hasTempFault(), true);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000317 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000318 }
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000319
320 // CML fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000321 {
322 // First STATUS_WORD wit no bits set, then with CML fault.
323 PMBusExpectations expectations;
324 setPMBusExpectations(mockPMBus, expectations);
325 psu2.analyze();
326 // STATUS_WORD with CML fault bit on.
327 expectations.statusWordValue = (status_word::CML_FAULT);
328 // Turn on STATUS_CML fault bit(s)
329 expectations.statusCMLValue = 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(), false);
336 EXPECT_EQ(psu2.hasVINUVFault(), false);
337 EXPECT_EQ(psu2.hasCommFault(), true);
338 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000339 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000340 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000341 }
Brandon Wyman6710ba22021-10-27 17:39:31 +0000342
343 // VOUT_OV_FAULT fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000344 {
345 // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault.
346 PMBusExpectations expectations;
347 setPMBusExpectations(mockPMBus, expectations);
348 psu2.analyze();
349 // STATUS_WORD with VOUT/VOUT_OV fault.
350 expectations.statusWordValue =
351 ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT));
352 // Turn on STATUS_VOUT fault bit(s)
353 expectations.statusVOUTValue = 0xA0;
Brandon Wyman96893a42021-11-05 19:56:57 +0000354 // STATUS_TEMPERATURE don't care (default)
Brandon Wymanb654c612021-11-05 23:24:51 +0000355 setPMBusExpectations(mockPMBus, expectations);
356 psu2.analyze();
357 EXPECT_EQ(psu2.isPresent(), true);
358 EXPECT_EQ(psu2.isFaulted(), true);
359 EXPECT_EQ(psu2.hasInputFault(), false);
360 EXPECT_EQ(psu2.hasMFRFault(), false);
361 EXPECT_EQ(psu2.hasVINUVFault(), false);
362 EXPECT_EQ(psu2.hasCommFault(), false);
363 EXPECT_EQ(psu2.hasVoutOVFault(), true);
Brandon Wyman96893a42021-11-05 19:56:57 +0000364 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000365 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000366 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600367
368 // Ignore fan fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000369 {
370 // First STATUS_WORD with no bits set, then with fan fault.
371 PMBusExpectations expectations;
372 setPMBusExpectations(mockPMBus, expectations);
373 psu2.analyze();
374 expectations.statusWordValue = (status_word::FAN_FAULT);
375 setPMBusExpectations(mockPMBus, expectations);
376 psu2.analyze();
377 EXPECT_EQ(psu2.isPresent(), true);
378 EXPECT_EQ(psu2.isFaulted(), false);
379 EXPECT_EQ(psu2.hasInputFault(), false);
380 EXPECT_EQ(psu2.hasMFRFault(), false);
381 EXPECT_EQ(psu2.hasVINUVFault(), false);
382 EXPECT_EQ(psu2.hasCommFault(), false);
383 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000384 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000385 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000386 }
Brandon Wyman2916ea52021-11-06 03:31:18 +0000387
388 {
389 // PGOOD/OFF fault.
390 // First STATUS_WORD with no bits set.
391 PMBusExpectations expectations;
392 setPMBusExpectations(mockPMBus, expectations);
393 psu2.analyze();
394 EXPECT_EQ(psu2.isFaulted(), false);
395 // POWER_GOOD# inactive, and OFF bit on.
396 expectations.statusWordValue =
397 ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF));
398 // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and
399 // STATUS_TEMPERATURE: Don't care if bits set or not (defaults).
400 setPMBusExpectations(mockPMBus, expectations);
401 psu2.analyze();
402 EXPECT_EQ(psu2.isPresent(), true);
403 EXPECT_EQ(psu2.isFaulted(), true);
404 EXPECT_EQ(psu2.hasInputFault(), false);
405 EXPECT_EQ(psu2.hasMFRFault(), false);
406 EXPECT_EQ(psu2.hasVINUVFault(), false);
407 EXPECT_EQ(psu2.hasCommFault(), false);
408 EXPECT_EQ(psu2.hasVoutOVFault(), false);
409 EXPECT_EQ(psu2.hasTempFault(), false);
410 EXPECT_EQ(psu2.hasPgoodFault(), true);
411 }
412
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600413 // TODO: ReadFailure
414}
415
Brandon Wyman59a35792020-06-04 12:37:40 -0500416TEST_F(PowerSupplyTests, OnOffConfig)
417{
418 auto bus = sdbusplus::bus::new_default();
419 uint8_t data = 0x15;
420
421 // Test where PSU is NOT present
422 try
423 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000424 // Assume GPIO presence, not inventory presence?
425 PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
426
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000427 MockedGPIOInterface* mockPresenceGPIO =
428 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000429 ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0));
Brandon Wyman59a35792020-06-04 12:37:40 -0500430 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000431 // Constructor should set initial presence, default read returns 0.
Brandon Wyman59a35792020-06-04 12:37:40 -0500432 // If it is not present, I should not be trying to write to it.
433 EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0);
434 psu.onOffConfig(data);
435 }
436 catch (...)
Adriana Kobylak0c9a33d2021-09-13 18:05:09 +0000437 {}
Brandon Wyman59a35792020-06-04 12:37:40 -0500438
439 // Test where PSU is present
440 try
441 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000442 // Assume GPIO presence, not inventory presence?
443 PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000444 MockedGPIOInterface* mockPresenceGPIO =
445 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000446 ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(1));
Brandon Wyman59a35792020-06-04 12:37:40 -0500447 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000448 // TODO: expect setPresence call?
449 // updatePresence() private function reads gpio, called by analyze().
450 psu.analyze();
Brandon Wyman59a35792020-06-04 12:37:40 -0500451 // TODO: ???should I check the filename?
452 EXPECT_CALL(mockPMBus,
453 writeBinary(_, ElementsAre(0x15), Type::HwmonDeviceDebug))
454 .Times(1);
455 psu.onOffConfig(data);
456 }
457 catch (...)
Adriana Kobylak0c9a33d2021-09-13 18:05:09 +0000458 {}
Brandon Wyman59a35792020-06-04 12:37:40 -0500459}
460
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600461TEST_F(PowerSupplyTests, ClearFaults)
462{
463 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000464 PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000465 MockedGPIOInterface* mockPresenceGPIO =
466 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000467 // GPIO read return 1 to indicate present.
468 ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(1));
469 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman8da35c52021-10-28 22:45:08 +0000470 // Presence change from missing to present will trigger in1_input read in
471 // an attempt to get CLEAR_FAULTS called.
472 EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(206000));
473 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000474 PMBusExpectations expectations;
475 setPMBusExpectations(mockPMBus, expectations);
B. J. Wyman681b2a32021-04-20 22:31:22 +0000476 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600477 EXPECT_EQ(psu.isPresent(), true);
478 EXPECT_EQ(psu.isFaulted(), false);
479 EXPECT_EQ(psu.hasInputFault(), false);
480 EXPECT_EQ(psu.hasMFRFault(), false);
481 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000482 EXPECT_EQ(psu.hasCommFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000483 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000484 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000485 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000486
Brandon Wymanf07bc792021-10-12 19:00:35 +0000487 // STATUS_WORD with fault bits galore!
Brandon Wymanb654c612021-11-05 23:24:51 +0000488 expectations.statusWordValue = 0xFFFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000489 // STATUS_INPUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000490 expectations.statusInputValue = 0xFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000491 // STATUS_MFR_SPEFIC with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000492 expectations.statusMFRValue = 0xFF;
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000493 // STATUS_CML with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000494 expectations.statusCMLValue = 0xFF;
Brandon Wyman6710ba22021-10-27 17:39:31 +0000495 // STATUS_VOUT with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000496 expectations.statusVOUTValue = 0xFF;
Brandon Wyman96893a42021-11-05 19:56:57 +0000497 // STATUS_TEMPERATURE with bits on.
498 expectations.statusTempValue = 0xFF;
Brandon Wymanb654c612021-11-05 23:24:51 +0000499 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600500 psu.analyze();
501 EXPECT_EQ(psu.isPresent(), true);
502 EXPECT_EQ(psu.isFaulted(), true);
503 EXPECT_EQ(psu.hasInputFault(), true);
504 EXPECT_EQ(psu.hasMFRFault(), true);
505 EXPECT_EQ(psu.hasVINUVFault(), true);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000506 EXPECT_EQ(psu.hasCommFault(), true);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000507 EXPECT_EQ(psu.hasVoutOVFault(), true);
Brandon Wyman96893a42021-11-05 19:56:57 +0000508 EXPECT_EQ(psu.hasTempFault(), true);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000509 EXPECT_EQ(psu.hasPgoodFault(), true);
Brandon Wyman3c208462020-05-13 16:25:58 -0500510 EXPECT_CALL(mockPMBus, read("in1_input", _))
511 .Times(1)
512 .WillOnce(Return(209000));
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600513 psu.clearFaults();
514 EXPECT_EQ(psu.isPresent(), true);
515 EXPECT_EQ(psu.isFaulted(), false);
516 EXPECT_EQ(psu.hasInputFault(), false);
517 EXPECT_EQ(psu.hasMFRFault(), false);
518 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000519 EXPECT_EQ(psu.hasCommFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000520 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000521 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000522 EXPECT_EQ(psu.hasPgoodFault(), false);
B. J. Wyman681b2a32021-04-20 22:31:22 +0000523
524 // TODO: Faults clear on missing/present?
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600525}
526
527TEST_F(PowerSupplyTests, UpdateInventory)
528{
529 auto bus = sdbusplus::bus::new_default();
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500530
531 try
532 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000533 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500534 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
535 // If it is not present, I should not be trying to read a string
536 EXPECT_CALL(mockPMBus, readString(_, _)).Times(0);
537 psu.updateInventory();
538 }
539 catch (...)
540 {
541 ADD_FAILURE() << "Should not have caught exception.";
542 }
543
544 try
545 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000546 PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000547 MockedGPIOInterface* mockPresenceGPIO =
548 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000549 // GPIO read return 1 to indicate present.
550 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
551 psu.analyze();
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500552 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
553 EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return(""));
554 psu.updateInventory();
555
Brandon Wyman3c530fb2021-04-13 13:13:22 -0500556#if IBM_VPD
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500557 EXPECT_CALL(mockPMBus, readString(_, _))
558 .WillOnce(Return("CCIN"))
559 .WillOnce(Return("PN3456"))
560 .WillOnce(Return("FN3456"))
561 .WillOnce(Return("HEADER"))
562 .WillOnce(Return("SN3456"))
563 .WillOnce(Return("FW3456"));
Brandon Wyman3c530fb2021-04-13 13:13:22 -0500564#endif
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500565 psu.updateInventory();
566 // TODO: D-Bus mocking to verify values stored on D-Bus (???)
567 }
568 catch (...)
569 {
570 ADD_FAILURE() << "Should not have caught exception.";
571 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600572}
573
574TEST_F(PowerSupplyTests, IsPresent)
575{
576 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000577
578 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000579 MockedGPIOInterface* mockPresenceGPIO =
580 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600581 EXPECT_EQ(psu.isPresent(), false);
582
B. J. Wyman681b2a32021-04-20 22:31:22 +0000583 // Change GPIO read to return 1 to indicate present.
584 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
585 psu.analyze();
586 EXPECT_EQ(psu.isPresent(), true);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600587}
588
589TEST_F(PowerSupplyTests, IsFaulted)
590{
591 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000592
593 PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000594 MockedGPIOInterface* mockPresenceGPIO =
595 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000596 // Always return 1 to indicate present.
597 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
598 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600599 EXPECT_EQ(psu.isFaulted(), false);
600 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wymanb654c612021-11-05 23:24:51 +0000601 PMBusExpectations expectations;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000602 // STATUS_WORD with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000603 expectations.statusWordValue = 0xFFFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000604 // STATUS_INPUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000605 expectations.statusInputValue = 0xFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000606 // STATUS_MFR_SPECIFIC with faults bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000607 expectations.statusMFRValue = 0xFF;
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000608 // STATUS_CML with faults bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000609 expectations.statusCMLValue = 0xFF;
Brandon Wyman6710ba22021-10-27 17:39:31 +0000610 // STATUS_VOUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000611 expectations.statusVOUTValue = 0xFF;
Brandon Wyman96893a42021-11-05 19:56:57 +0000612 // STATUS_TEMPERATURE with fault bits on.
613 expectations.statusTempValue = 0xFF;
Brandon Wymanb654c612021-11-05 23:24:51 +0000614 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600615 psu.analyze();
616 EXPECT_EQ(psu.isFaulted(), true);
617}
618
619TEST_F(PowerSupplyTests, HasInputFault)
620{
621 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000622
623 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000624 MockedGPIOInterface* mockPresenceGPIO =
625 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000626 // Always return 1 to indicate present.
627 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
628 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600629 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
630 EXPECT_EQ(psu.hasInputFault(), false);
Brandon Wyman8da35c52021-10-28 22:45:08 +0000631 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000632 PMBusExpectations expectations;
633 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600634 psu.analyze();
635 EXPECT_EQ(psu.hasInputFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000636 // STATUS_WORD with input fault/warn on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000637 expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000638 // STATUS_INPUT with an input fault bit on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000639 expectations.statusInputValue = 0x80;
640 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600641 psu.analyze();
642 EXPECT_EQ(psu.hasInputFault(), true);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000643 // STATUS_WORD with no bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000644 expectations.statusWordValue = 0;
645 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600646 psu.analyze();
647 EXPECT_EQ(psu.hasInputFault(), false);
648}
649
650TEST_F(PowerSupplyTests, HasMFRFault)
651{
652 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000653
654 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000655 MockedGPIOInterface* mockPresenceGPIO =
656 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000657 // Always return 1 to indicate present.
658 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
659 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600660 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
661 EXPECT_EQ(psu.hasMFRFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000662 // First return STATUS_WORD with no bits on.
Brandon Wyman8da35c52021-10-28 22:45:08 +0000663 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000664 PMBusExpectations expectations;
665 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600666 psu.analyze();
667 EXPECT_EQ(psu.hasMFRFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000668 // Next return STATUS_WORD with MFR fault bit on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000669 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000670 // STATUS_MFR_SPEFIC with bit(s) on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000671 expectations.statusMFRValue = 0xFF;
672 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600673 psu.analyze();
674 EXPECT_EQ(psu.hasMFRFault(), true);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000675 // Back to no bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +0000676 expectations.statusWordValue = 0;
677 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600678 psu.analyze();
679 EXPECT_EQ(psu.hasMFRFault(), false);
680}
681
682TEST_F(PowerSupplyTests, HasVINUVFault)
683{
684 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000685
686 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000687 MockedGPIOInterface* mockPresenceGPIO =
688 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000689 // Always return 1 to indicate present.
690 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
691 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600692 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
693 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wyman8da35c52021-10-28 22:45:08 +0000694 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000695 PMBusExpectations expectations;
696 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600697 psu.analyze();
698 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000699 // Turn fault on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000700 expectations.statusWordValue = (status_word::VIN_UV_FAULT);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000701 // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by
702 // Figure 16, and assume bits on in STATUS_INPUT.
Brandon Wymanb654c612021-11-05 23:24:51 +0000703 expectations.statusInputValue = 0x18;
704 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600705 psu.analyze();
706 EXPECT_EQ(psu.hasVINUVFault(), true);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000707 // Back to no fault bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +0000708 expectations.statusWordValue = 0;
709 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600710 psu.analyze();
711 EXPECT_EQ(psu.hasVINUVFault(), false);
712}
Brandon Wyman6710ba22021-10-27 17:39:31 +0000713
714TEST_F(PowerSupplyTests, HasVoutOVFault)
715{
716 auto bus = sdbusplus::bus::new_default();
717
718 PowerSupply psu{bus, PSUInventoryPath, 3, 0x69, PSUGPIOLineName};
719 MockedGPIOInterface* mockPresenceGPIO =
720 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
721 // Always return 1 to indicate present.
722 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
723 psu.analyze();
724 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
725 EXPECT_EQ(psu.hasVoutOVFault(), false);
726 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000727 PMBusExpectations expectations;
728 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000729 psu.analyze();
730 EXPECT_EQ(psu.hasVoutOVFault(), false);
731 // Turn fault on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000732 expectations.statusWordValue = (status_word::VOUT_OV_FAULT);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000733 // STATUS_VOUT fault bit(s)
Brandon Wymanb654c612021-11-05 23:24:51 +0000734 expectations.statusVOUTValue = 0x80;
Brandon Wyman96893a42021-11-05 19:56:57 +0000735 // STATUS_TEMPERATURE default.
Brandon Wymanb654c612021-11-05 23:24:51 +0000736 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000737 psu.analyze();
738 EXPECT_EQ(psu.hasVoutOVFault(), true);
739 // Back to no fault bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +0000740 expectations.statusWordValue = 0;
741 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000742 psu.analyze();
743 EXPECT_EQ(psu.hasVoutOVFault(), false);
744}
Brandon Wyman96893a42021-11-05 19:56:57 +0000745
746TEST_F(PowerSupplyTests, HasTempFault)
747{
748 auto bus = sdbusplus::bus::new_default();
749
750 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName};
751 MockedGPIOInterface* mockPresenceGPIO =
752 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
753 // Always return 1 to indicate present.
754 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
755 psu.analyze();
756 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
757 EXPECT_EQ(psu.hasTempFault(), false);
758 // STATUS_WORD 0x0000 is powered on, no faults.
759 PMBusExpectations expectations;
760 setPMBusExpectations(mockPMBus, expectations);
761 psu.analyze();
762 EXPECT_EQ(psu.hasTempFault(), false);
763 // Turn fault on.
764 expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
765 // STATUS_TEMPERATURE fault bit on (OT Fault)
766 expectations.statusTempValue = 0x80;
767 setPMBusExpectations(mockPMBus, expectations);
768 psu.analyze();
769 EXPECT_EQ(psu.hasTempFault(), true);
770 // Back to no fault bits on in STATUS_WORD
771 expectations.statusWordValue = 0;
772 setPMBusExpectations(mockPMBus, expectations);
773 psu.analyze();
774 EXPECT_EQ(psu.hasTempFault(), false);
775}
Brandon Wyman2916ea52021-11-06 03:31:18 +0000776
777TEST_F(PowerSupplyTests, HasPgoodFault)
778{
779 auto bus = sdbusplus::bus::new_default();
780
781 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6b, PSUGPIOLineName};
782 MockedGPIOInterface* mockPresenceGPIO =
783 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
784 // Always return 1 to indicate present.
785 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
786 psu.analyze();
787 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
788 EXPECT_EQ(psu.hasPgoodFault(), false);
789 // STATUS_WORD 0x0000 is powered on, no faults.
790 PMBusExpectations expectations;
791 setPMBusExpectations(mockPMBus, expectations);
792 psu.analyze();
793 EXPECT_EQ(psu.hasPgoodFault(), false);
794 // Turn PGOOD# off (fault on).
795 expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED);
796 setPMBusExpectations(mockPMBus, expectations);
797 psu.analyze();
798 EXPECT_EQ(psu.hasPgoodFault(), true);
799 // Back to no fault bits on in STATUS_WORD
800 expectations.statusWordValue = 0;
801 setPMBusExpectations(mockPMBus, expectations);
802 psu.analyze();
803 EXPECT_EQ(psu.hasPgoodFault(), false);
804 // Turn OFF bit on
805 expectations.statusWordValue = (status_word::UNIT_IS_OFF);
806 setPMBusExpectations(mockPMBus, expectations);
807 psu.analyze();
808 EXPECT_EQ(psu.hasPgoodFault(), true);
809 // Back to no fault bits on in STATUS_WORD
810 expectations.statusWordValue = 0;
811 setPMBusExpectations(mockPMBus, expectations);
812 psu.analyze();
813 EXPECT_EQ(psu.hasPgoodFault(), false);
814}