blob: 7fb7d03c728fe32cc2645b9ea94c615d76cad7fe [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 Wyman1d7a7df2020-03-26 10:14:05 -0500150 }
151 catch (...)
152 {
153 ADD_FAILURE() << "Should not have caught exception.";
154 }
B. J. Wyman681b2a32021-04-20 22:31:22 +0000155
156 // Test with valid arguments
157 // TODO: Using D-Bus inventory path for presence.
158 try
159 {
160 // FIXME: How do I get that presenceGPIO.read() in the startup to throw
161 // an exception?
162
163 // EXPECT_CALL(mockedUtil, getPresence(_,
164 // StrEq(PSUInventoryPath)))
165 // .Times(1);
166 }
167 catch (...)
168 {
169 ADD_FAILURE() << "Should not have caught exception.";
170 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600171}
172
173TEST_F(PowerSupplyTests, Analyze)
174{
175 auto bus = sdbusplus::bus::new_default();
176
Brandon Wymanb654c612021-11-05 23:24:51 +0000177 {
178 // If I default to reading the GPIO, I will NOT expect a call to
179 // getPresence().
B. J. Wyman681b2a32021-04-20 22:31:22 +0000180
Brandon Wymanb654c612021-11-05 23:24:51 +0000181 PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
182 MockedGPIOInterface* mockPresenceGPIO =
183 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
184 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000185
Brandon Wymanb654c612021-11-05 23:24:51 +0000186 psu.analyze();
187 // By default, nothing should change.
188 EXPECT_EQ(psu.isPresent(), false);
189 EXPECT_EQ(psu.isFaulted(), false);
190 EXPECT_EQ(psu.hasInputFault(), false);
191 EXPECT_EQ(psu.hasMFRFault(), false);
192 EXPECT_EQ(psu.hasVINUVFault(), false);
193 EXPECT_EQ(psu.hasCommFault(), false);
194 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000195 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000196 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600197
B. J. Wyman681b2a32021-04-20 22:31:22 +0000198 PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
199 // In order to get the various faults tested, the power supply needs to
200 // be present in order to read from the PMBus device(s).
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000201 MockedGPIOInterface* mockPresenceGPIO2 =
202 static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000203 ON_CALL(*mockPresenceGPIO2, read()).WillByDefault(Return(1));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000204 EXPECT_EQ(psu2.isPresent(), false);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600205
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600206 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus());
Brandon Wyman8da35c52021-10-28 22:45:08 +0000207 // Presence change from missing to present will trigger write to
208 // ON_OFF_CONFIG.
209 EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, _, _));
Brandon Wymanb654c612021-11-05 23:24:51 +0000210 // Presence change from missing to present will trigger in1_input read
211 // in an attempt to get CLEAR_FAULTS called.
Brandon Wymanf07bc792021-10-12 19:00:35 +0000212 EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(206000));
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600213
Brandon Wymanb654c612021-11-05 23:24:51 +0000214 // STATUS_WORD INPUT fault.
215 {
216 // Start with STATUS_WORD 0x0000. Powered on, no faults.
217 // Set expectations for a no fault
218 PMBusExpectations expectations;
219 setPMBusExpectations(mockPMBus, expectations);
220 psu2.analyze();
221 EXPECT_EQ(psu2.isPresent(), true);
222 EXPECT_EQ(psu2.isFaulted(), false);
223 EXPECT_EQ(psu2.hasInputFault(), false);
224 EXPECT_EQ(psu2.hasMFRFault(), false);
225 EXPECT_EQ(psu2.hasVINUVFault(), false);
226 EXPECT_EQ(psu2.hasCommFault(), false);
227 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000228 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000229
230 // Update expectations for STATUS_WORD input fault/warn
Brandon Wyman96893a42021-11-05 19:56:57 +0000231 // STATUS_INPUT fault bits ... on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000232 expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
233 expectations.statusInputValue = 0x38;
234 setPMBusExpectations(mockPMBus, expectations);
235 psu2.analyze();
236 EXPECT_EQ(psu2.isPresent(), true);
237 EXPECT_EQ(psu2.isFaulted(), true);
238 EXPECT_EQ(psu2.hasInputFault(), true);
239 EXPECT_EQ(psu2.hasMFRFault(), false);
240 EXPECT_EQ(psu2.hasVINUVFault(), false);
241 EXPECT_EQ(psu2.hasCommFault(), false);
242 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000243 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000244 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600245
246 // STATUS_WORD INPUT/UV fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000247 {
248 // First need it to return good status, then the fault
249 PMBusExpectations expectations;
250 setPMBusExpectations(mockPMBus, expectations);
251 psu2.analyze();
252 // Now set fault bits in STATUS_WORD
253 expectations.statusWordValue =
254 (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT);
255 // STATUS_INPUT fault bits ... on.
256 expectations.statusInputValue = 0x38;
257 setPMBusExpectations(mockPMBus, expectations);
258 psu2.analyze();
259 EXPECT_EQ(psu2.isPresent(), true);
260 EXPECT_EQ(psu2.isFaulted(), true);
261 EXPECT_EQ(psu2.hasInputFault(), true);
262 EXPECT_EQ(psu2.hasMFRFault(), false);
263 EXPECT_EQ(psu2.hasVINUVFault(), true);
264 EXPECT_EQ(psu2.hasCommFault(), false);
265 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000266 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000267 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600268
269 // STATUS_WORD MFR fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000270 {
271 // First need it to return good status, then the fault
272 PMBusExpectations expectations;
273 setPMBusExpectations(mockPMBus, expectations);
274 psu2.analyze();
275 // Now STATUS_WORD with MFR fault bit on.
276 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
277 // STATUS_MFR bits on.
278 expectations.statusMFRValue = 0xFF;
279 setPMBusExpectations(mockPMBus, expectations);
280 psu2.analyze();
281 EXPECT_EQ(psu2.isPresent(), true);
282 EXPECT_EQ(psu2.isFaulted(), true);
283 EXPECT_EQ(psu2.hasInputFault(), false);
284 EXPECT_EQ(psu2.hasMFRFault(), true);
285 EXPECT_EQ(psu2.hasVINUVFault(), false);
286 EXPECT_EQ(psu2.hasCommFault(), false);
287 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000288 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000289 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600290
Brandon Wyman96893a42021-11-05 19:56:57 +0000291 // Temperature fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000292 {
293 // First STATUS_WORD with no bits set, then with temperature fault.
294 PMBusExpectations expectations;
295 setPMBusExpectations(mockPMBus, expectations);
296 psu2.analyze();
297 // STATUS_WORD with temperature fault bit on.
298 expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
Brandon Wyman96893a42021-11-05 19:56:57 +0000299 // STATUS_TEMPERATURE with fault bit(s) on.
300 expectations.statusTempValue = 0x10;
Brandon Wymanb654c612021-11-05 23:24:51 +0000301 setPMBusExpectations(mockPMBus, expectations);
302 psu2.analyze();
303 EXPECT_EQ(psu2.isPresent(), true);
Brandon Wyman96893a42021-11-05 19:56:57 +0000304 EXPECT_EQ(psu2.isFaulted(), true);
Brandon Wymanb654c612021-11-05 23:24:51 +0000305 EXPECT_EQ(psu2.hasInputFault(), false);
306 EXPECT_EQ(psu2.hasMFRFault(), false);
307 EXPECT_EQ(psu2.hasVINUVFault(), false);
308 EXPECT_EQ(psu2.hasCommFault(), false);
309 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000310 EXPECT_EQ(psu2.hasTempFault(), true);
Brandon Wymanb654c612021-11-05 23:24:51 +0000311 }
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000312
313 // CML fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000314 {
315 // First STATUS_WORD wit no bits set, then with CML fault.
316 PMBusExpectations expectations;
317 setPMBusExpectations(mockPMBus, expectations);
318 psu2.analyze();
319 // STATUS_WORD with CML fault bit on.
320 expectations.statusWordValue = (status_word::CML_FAULT);
321 // Turn on STATUS_CML fault bit(s)
322 expectations.statusCMLValue = 0xFF;
323 setPMBusExpectations(mockPMBus, expectations);
324 psu2.analyze();
325 EXPECT_EQ(psu2.isPresent(), true);
326 EXPECT_EQ(psu2.isFaulted(), true);
327 EXPECT_EQ(psu2.hasInputFault(), false);
328 EXPECT_EQ(psu2.hasMFRFault(), false);
329 EXPECT_EQ(psu2.hasVINUVFault(), false);
330 EXPECT_EQ(psu2.hasCommFault(), true);
331 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000332 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000333 }
Brandon Wyman6710ba22021-10-27 17:39:31 +0000334
335 // VOUT_OV_FAULT fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000336 {
337 // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault.
338 PMBusExpectations expectations;
339 setPMBusExpectations(mockPMBus, expectations);
340 psu2.analyze();
341 // STATUS_WORD with VOUT/VOUT_OV fault.
342 expectations.statusWordValue =
343 ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT));
344 // Turn on STATUS_VOUT fault bit(s)
345 expectations.statusVOUTValue = 0xA0;
Brandon Wyman96893a42021-11-05 19:56:57 +0000346 // STATUS_TEMPERATURE don't care (default)
Brandon Wymanb654c612021-11-05 23:24:51 +0000347 setPMBusExpectations(mockPMBus, expectations);
348 psu2.analyze();
349 EXPECT_EQ(psu2.isPresent(), true);
350 EXPECT_EQ(psu2.isFaulted(), true);
351 EXPECT_EQ(psu2.hasInputFault(), false);
352 EXPECT_EQ(psu2.hasMFRFault(), false);
353 EXPECT_EQ(psu2.hasVINUVFault(), false);
354 EXPECT_EQ(psu2.hasCommFault(), false);
355 EXPECT_EQ(psu2.hasVoutOVFault(), true);
Brandon Wyman96893a42021-11-05 19:56:57 +0000356 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000357 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600358
359 // Ignore fan fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000360 {
361 // First STATUS_WORD with no bits set, then with fan fault.
362 PMBusExpectations expectations;
363 setPMBusExpectations(mockPMBus, expectations);
364 psu2.analyze();
365 expectations.statusWordValue = (status_word::FAN_FAULT);
366 setPMBusExpectations(mockPMBus, expectations);
367 psu2.analyze();
368 EXPECT_EQ(psu2.isPresent(), true);
369 EXPECT_EQ(psu2.isFaulted(), false);
370 EXPECT_EQ(psu2.hasInputFault(), false);
371 EXPECT_EQ(psu2.hasMFRFault(), false);
372 EXPECT_EQ(psu2.hasVINUVFault(), false);
373 EXPECT_EQ(psu2.hasCommFault(), false);
374 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000375 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000376 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600377 // TODO: ReadFailure
378}
379
Brandon Wyman59a35792020-06-04 12:37:40 -0500380TEST_F(PowerSupplyTests, OnOffConfig)
381{
382 auto bus = sdbusplus::bus::new_default();
383 uint8_t data = 0x15;
384
385 // Test where PSU is NOT present
386 try
387 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000388 // Assume GPIO presence, not inventory presence?
389 PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
390
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000391 MockedGPIOInterface* mockPresenceGPIO =
392 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000393 ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0));
Brandon Wyman59a35792020-06-04 12:37:40 -0500394 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000395 // Constructor should set initial presence, default read returns 0.
Brandon Wyman59a35792020-06-04 12:37:40 -0500396 // If it is not present, I should not be trying to write to it.
397 EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0);
398 psu.onOffConfig(data);
399 }
400 catch (...)
Adriana Kobylak0c9a33d2021-09-13 18:05:09 +0000401 {}
Brandon Wyman59a35792020-06-04 12:37:40 -0500402
403 // Test where PSU is present
404 try
405 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000406 // Assume GPIO presence, not inventory presence?
407 PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000408 MockedGPIOInterface* mockPresenceGPIO =
409 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000410 ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(1));
Brandon Wyman59a35792020-06-04 12:37:40 -0500411 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000412 // TODO: expect setPresence call?
413 // updatePresence() private function reads gpio, called by analyze().
414 psu.analyze();
Brandon Wyman59a35792020-06-04 12:37:40 -0500415 // TODO: ???should I check the filename?
416 EXPECT_CALL(mockPMBus,
417 writeBinary(_, ElementsAre(0x15), Type::HwmonDeviceDebug))
418 .Times(1);
419 psu.onOffConfig(data);
420 }
421 catch (...)
Adriana Kobylak0c9a33d2021-09-13 18:05:09 +0000422 {}
Brandon Wyman59a35792020-06-04 12:37:40 -0500423}
424
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600425TEST_F(PowerSupplyTests, ClearFaults)
426{
427 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000428 PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000429 MockedGPIOInterface* mockPresenceGPIO =
430 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000431 // GPIO read return 1 to indicate present.
432 ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(1));
433 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman8da35c52021-10-28 22:45:08 +0000434 // Presence change from missing to present will trigger in1_input read in
435 // an attempt to get CLEAR_FAULTS called.
436 EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(206000));
437 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000438 PMBusExpectations expectations;
439 setPMBusExpectations(mockPMBus, expectations);
B. J. Wyman681b2a32021-04-20 22:31:22 +0000440 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600441 EXPECT_EQ(psu.isPresent(), true);
442 EXPECT_EQ(psu.isFaulted(), false);
443 EXPECT_EQ(psu.hasInputFault(), false);
444 EXPECT_EQ(psu.hasMFRFault(), false);
445 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000446 EXPECT_EQ(psu.hasCommFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000447 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000448 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000449
Brandon Wymanf07bc792021-10-12 19:00:35 +0000450 // STATUS_WORD with fault bits galore!
Brandon Wymanb654c612021-11-05 23:24:51 +0000451 expectations.statusWordValue = 0xFFFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000452 // STATUS_INPUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000453 expectations.statusInputValue = 0xFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000454 // STATUS_MFR_SPEFIC with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000455 expectations.statusMFRValue = 0xFF;
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000456 // STATUS_CML with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000457 expectations.statusCMLValue = 0xFF;
Brandon Wyman6710ba22021-10-27 17:39:31 +0000458 // STATUS_VOUT with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000459 expectations.statusVOUTValue = 0xFF;
Brandon Wyman96893a42021-11-05 19:56:57 +0000460 // STATUS_TEMPERATURE with bits on.
461 expectations.statusTempValue = 0xFF;
Brandon Wymanb654c612021-11-05 23:24:51 +0000462 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600463 psu.analyze();
464 EXPECT_EQ(psu.isPresent(), true);
465 EXPECT_EQ(psu.isFaulted(), true);
466 EXPECT_EQ(psu.hasInputFault(), true);
467 EXPECT_EQ(psu.hasMFRFault(), true);
468 EXPECT_EQ(psu.hasVINUVFault(), true);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000469 EXPECT_EQ(psu.hasCommFault(), true);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000470 EXPECT_EQ(psu.hasVoutOVFault(), true);
Brandon Wyman96893a42021-11-05 19:56:57 +0000471 EXPECT_EQ(psu.hasTempFault(), true);
Brandon Wyman3c208462020-05-13 16:25:58 -0500472 EXPECT_CALL(mockPMBus, read("in1_input", _))
473 .Times(1)
474 .WillOnce(Return(209000));
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600475 psu.clearFaults();
476 EXPECT_EQ(psu.isPresent(), true);
477 EXPECT_EQ(psu.isFaulted(), false);
478 EXPECT_EQ(psu.hasInputFault(), false);
479 EXPECT_EQ(psu.hasMFRFault(), false);
480 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000481 EXPECT_EQ(psu.hasCommFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000482 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000483 EXPECT_EQ(psu.hasTempFault(), false);
B. J. Wyman681b2a32021-04-20 22:31:22 +0000484
485 // TODO: Faults clear on missing/present?
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600486}
487
488TEST_F(PowerSupplyTests, UpdateInventory)
489{
490 auto bus = sdbusplus::bus::new_default();
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500491
492 try
493 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000494 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500495 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
496 // If it is not present, I should not be trying to read a string
497 EXPECT_CALL(mockPMBus, readString(_, _)).Times(0);
498 psu.updateInventory();
499 }
500 catch (...)
501 {
502 ADD_FAILURE() << "Should not have caught exception.";
503 }
504
505 try
506 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000507 PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000508 MockedGPIOInterface* mockPresenceGPIO =
509 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000510 // GPIO read return 1 to indicate present.
511 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
512 psu.analyze();
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500513 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
514 EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return(""));
515 psu.updateInventory();
516
Brandon Wyman3c530fb2021-04-13 13:13:22 -0500517#if IBM_VPD
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500518 EXPECT_CALL(mockPMBus, readString(_, _))
519 .WillOnce(Return("CCIN"))
520 .WillOnce(Return("PN3456"))
521 .WillOnce(Return("FN3456"))
522 .WillOnce(Return("HEADER"))
523 .WillOnce(Return("SN3456"))
524 .WillOnce(Return("FW3456"));
Brandon Wyman3c530fb2021-04-13 13:13:22 -0500525#endif
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500526 psu.updateInventory();
527 // TODO: D-Bus mocking to verify values stored on D-Bus (???)
528 }
529 catch (...)
530 {
531 ADD_FAILURE() << "Should not have caught exception.";
532 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600533}
534
535TEST_F(PowerSupplyTests, IsPresent)
536{
537 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000538
539 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000540 MockedGPIOInterface* mockPresenceGPIO =
541 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600542 EXPECT_EQ(psu.isPresent(), false);
543
B. J. Wyman681b2a32021-04-20 22:31:22 +0000544 // Change GPIO read to return 1 to indicate present.
545 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
546 psu.analyze();
547 EXPECT_EQ(psu.isPresent(), true);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600548}
549
550TEST_F(PowerSupplyTests, IsFaulted)
551{
552 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000553
554 PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000555 MockedGPIOInterface* mockPresenceGPIO =
556 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000557 // Always return 1 to indicate present.
558 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
559 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600560 EXPECT_EQ(psu.isFaulted(), false);
561 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wymanb654c612021-11-05 23:24:51 +0000562 PMBusExpectations expectations;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000563 // STATUS_WORD with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000564 expectations.statusWordValue = 0xFFFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000565 // STATUS_INPUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000566 expectations.statusInputValue = 0xFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000567 // STATUS_MFR_SPECIFIC with faults bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000568 expectations.statusMFRValue = 0xFF;
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000569 // STATUS_CML with faults bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000570 expectations.statusCMLValue = 0xFF;
Brandon Wyman6710ba22021-10-27 17:39:31 +0000571 // STATUS_VOUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000572 expectations.statusVOUTValue = 0xFF;
Brandon Wyman96893a42021-11-05 19:56:57 +0000573 // STATUS_TEMPERATURE with fault bits on.
574 expectations.statusTempValue = 0xFF;
Brandon Wymanb654c612021-11-05 23:24:51 +0000575 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600576 psu.analyze();
577 EXPECT_EQ(psu.isFaulted(), true);
578}
579
580TEST_F(PowerSupplyTests, HasInputFault)
581{
582 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000583
584 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000585 MockedGPIOInterface* mockPresenceGPIO =
586 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000587 // Always return 1 to indicate present.
588 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
589 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600590 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
591 EXPECT_EQ(psu.hasInputFault(), false);
Brandon Wyman8da35c52021-10-28 22:45:08 +0000592 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000593 PMBusExpectations expectations;
594 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600595 psu.analyze();
596 EXPECT_EQ(psu.hasInputFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000597 // STATUS_WORD with input fault/warn on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000598 expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000599 // STATUS_INPUT with an input fault bit on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000600 expectations.statusInputValue = 0x80;
601 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600602 psu.analyze();
603 EXPECT_EQ(psu.hasInputFault(), true);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000604 // STATUS_WORD with no bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000605 expectations.statusWordValue = 0;
606 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600607 psu.analyze();
608 EXPECT_EQ(psu.hasInputFault(), false);
609}
610
611TEST_F(PowerSupplyTests, HasMFRFault)
612{
613 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000614
615 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000616 MockedGPIOInterface* mockPresenceGPIO =
617 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000618 // Always return 1 to indicate present.
619 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
620 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600621 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
622 EXPECT_EQ(psu.hasMFRFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000623 // First return STATUS_WORD with no bits on.
Brandon Wyman8da35c52021-10-28 22:45:08 +0000624 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000625 PMBusExpectations expectations;
626 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600627 psu.analyze();
628 EXPECT_EQ(psu.hasMFRFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000629 // Next return STATUS_WORD with MFR fault bit on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000630 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000631 // STATUS_MFR_SPEFIC with bit(s) on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000632 expectations.statusMFRValue = 0xFF;
633 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600634 psu.analyze();
635 EXPECT_EQ(psu.hasMFRFault(), true);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000636 // Back to no bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +0000637 expectations.statusWordValue = 0;
638 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600639 psu.analyze();
640 EXPECT_EQ(psu.hasMFRFault(), false);
641}
642
643TEST_F(PowerSupplyTests, HasVINUVFault)
644{
645 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000646
647 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000648 MockedGPIOInterface* mockPresenceGPIO =
649 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000650 // Always return 1 to indicate present.
651 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
652 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600653 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
654 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wyman8da35c52021-10-28 22:45:08 +0000655 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000656 PMBusExpectations expectations;
657 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600658 psu.analyze();
659 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000660 // Turn fault on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000661 expectations.statusWordValue = (status_word::VIN_UV_FAULT);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000662 // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by
663 // Figure 16, and assume bits on in STATUS_INPUT.
Brandon Wymanb654c612021-11-05 23:24:51 +0000664 expectations.statusInputValue = 0x18;
665 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600666 psu.analyze();
667 EXPECT_EQ(psu.hasVINUVFault(), true);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000668 // Back to no fault bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +0000669 expectations.statusWordValue = 0;
670 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600671 psu.analyze();
672 EXPECT_EQ(psu.hasVINUVFault(), false);
673}
Brandon Wyman6710ba22021-10-27 17:39:31 +0000674
675TEST_F(PowerSupplyTests, HasVoutOVFault)
676{
677 auto bus = sdbusplus::bus::new_default();
678
679 PowerSupply psu{bus, PSUInventoryPath, 3, 0x69, PSUGPIOLineName};
680 MockedGPIOInterface* mockPresenceGPIO =
681 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
682 // Always return 1 to indicate present.
683 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
684 psu.analyze();
685 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
686 EXPECT_EQ(psu.hasVoutOVFault(), false);
687 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000688 PMBusExpectations expectations;
689 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000690 psu.analyze();
691 EXPECT_EQ(psu.hasVoutOVFault(), false);
692 // Turn fault on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000693 expectations.statusWordValue = (status_word::VOUT_OV_FAULT);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000694 // STATUS_VOUT fault bit(s)
Brandon Wymanb654c612021-11-05 23:24:51 +0000695 expectations.statusVOUTValue = 0x80;
Brandon Wyman96893a42021-11-05 19:56:57 +0000696 // STATUS_TEMPERATURE default.
Brandon Wymanb654c612021-11-05 23:24:51 +0000697 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000698 psu.analyze();
699 EXPECT_EQ(psu.hasVoutOVFault(), true);
700 // Back to no fault bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +0000701 expectations.statusWordValue = 0;
702 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000703 psu.analyze();
704 EXPECT_EQ(psu.hasVoutOVFault(), false);
705}
Brandon Wyman96893a42021-11-05 19:56:57 +0000706
707TEST_F(PowerSupplyTests, HasTempFault)
708{
709 auto bus = sdbusplus::bus::new_default();
710
711 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName};
712 MockedGPIOInterface* mockPresenceGPIO =
713 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
714 // Always return 1 to indicate present.
715 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
716 psu.analyze();
717 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
718 EXPECT_EQ(psu.hasTempFault(), false);
719 // STATUS_WORD 0x0000 is powered on, no faults.
720 PMBusExpectations expectations;
721 setPMBusExpectations(mockPMBus, expectations);
722 psu.analyze();
723 EXPECT_EQ(psu.hasTempFault(), false);
724 // Turn fault on.
725 expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
726 // STATUS_TEMPERATURE fault bit on (OT Fault)
727 expectations.statusTempValue = 0x80;
728 setPMBusExpectations(mockPMBus, expectations);
729 psu.analyze();
730 EXPECT_EQ(psu.hasTempFault(), true);
731 // Back to no fault bits on in STATUS_WORD
732 expectations.statusWordValue = 0;
733 setPMBusExpectations(mockPMBus, expectations);
734 psu.analyze();
735 EXPECT_EQ(psu.hasTempFault(), false);
736}