blob: 222d9c383a60e0908b0737ba37e7f042ee9b9548 [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 Wymanb10b3be2021-11-09 22:12:15 +000032 uint8_t statusIOUTValue{0x00};
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +000033 uint8_t statusFans12Value{0x00};
Brandon Wyman96893a42021-11-05 19:56:57 +000034 uint8_t statusTempValue{0x00};
Brandon Wymanb654c612021-11-05 23:24:51 +000035};
36
Brandon Wyman8da35c52021-10-28 22:45:08 +000037// Helper function to setup expectations for various STATUS_* commands
Brandon Wymanb654c612021-11-05 23:24:51 +000038void setPMBusExpectations(MockedPMBus& mockPMBus,
39 const PMBusExpectations& expectations)
Brandon Wyman8da35c52021-10-28 22:45:08 +000040{
41 EXPECT_CALL(mockPMBus, read(STATUS_WORD, _))
42 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000043 .WillOnce(Return(expectations.statusWordValue));
Brandon Wyman8da35c52021-10-28 22:45:08 +000044
Brandon Wymanb654c612021-11-05 23:24:51 +000045 if (expectations.statusWordValue != 0)
Brandon Wyman8da35c52021-10-28 22:45:08 +000046 {
47 // If fault bits are on in STATUS_WORD, there will also be a read of
Brandon Wyman96893a42021-11-05 19:56:57 +000048 // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT (page 0), and
49 // STATUS_TEMPERATURE.
Brandon Wyman8da35c52021-10-28 22:45:08 +000050 EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _))
51 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000052 .WillOnce(Return(expectations.statusInputValue));
Brandon Wyman8da35c52021-10-28 22:45:08 +000053 EXPECT_CALL(mockPMBus, read(STATUS_MFR, _))
54 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000055 .WillOnce(Return(expectations.statusMFRValue));
Brandon Wyman8da35c52021-10-28 22:45:08 +000056 EXPECT_CALL(mockPMBus, read(STATUS_CML, _))
57 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000058 .WillOnce(Return(expectations.statusCMLValue));
Brandon Wyman6710ba22021-10-27 17:39:31 +000059 // 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)
Brandon Wymanb654c612021-11-05 23:24:51 +000065 .WillOnce(Return(expectations.statusVOUTValue));
Brandon Wymanb10b3be2021-11-09 22:12:15 +000066 EXPECT_CALL(mockPMBus, read(STATUS_IOUT, _))
67 .Times(1)
68 .WillOnce(Return(expectations.statusIOUTValue));
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +000069 EXPECT_CALL(mockPMBus, read(STATUS_FANS_1_2, _))
70 .Times(1)
71 .WillOnce(Return(expectations.statusFans12Value));
Brandon Wyman96893a42021-11-05 19:56:57 +000072 EXPECT_CALL(mockPMBus, read(STATUS_TEMPERATURE, _))
73 .Times(1)
74 .WillOnce(Return(expectations.statusTempValue));
Brandon Wyman8da35c52021-10-28 22:45:08 +000075 }
76}
77
Brandon Wyman3f1242f2020-01-28 13:11:25 -060078class 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
95TEST_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
B. J. Wyman681b2a32021-04-20 22:31:22 +0000101 * @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.
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600105 */
106 auto bus = sdbusplus::bus::new_default();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600107
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500108 // Try where inventory path is empty, constructor should fail.
109 try
110 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000111 auto psu =
112 std::make_unique<PowerSupply>(bus, "", 3, 0x68, PSUGPIOLineName);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500113 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
B. J. Wyman681b2a32021-04-20 22:31:22 +0000124 // TODO: Try invalid i2c address?
125
126 // Try where gpioLineName is empty.
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500127 try
128 {
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500129 auto psu =
B. J. Wyman681b2a32021-04-20 22:31:22 +0000130 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);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500149
150 EXPECT_EQ(psu->isPresent(), false);
151 EXPECT_EQ(psu->isFaulted(), false);
Brandon Wyman8da35c52021-10-28 22:45:08 +0000152 EXPECT_EQ(psu->hasCommFault(), false);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500153 EXPECT_EQ(psu->hasInputFault(), false);
154 EXPECT_EQ(psu->hasMFRFault(), false);
155 EXPECT_EQ(psu->hasVINUVFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000156 EXPECT_EQ(psu->hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000157 EXPECT_EQ(psu->hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000158 EXPECT_EQ(psu->hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000159 EXPECT_EQ(psu->hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000160 EXPECT_EQ(psu->hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000161 EXPECT_EQ(psu->hasPgoodFault(), false);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500162 }
163 catch (...)
164 {
165 ADD_FAILURE() << "Should not have caught exception.";
166 }
B. J. Wyman681b2a32021-04-20 22:31:22 +0000167
168 // Test with valid arguments
169 // TODO: Using D-Bus inventory path for presence.
170 try
171 {
172 // FIXME: How do I get that presenceGPIO.read() in the startup to throw
173 // an exception?
174
175 // EXPECT_CALL(mockedUtil, getPresence(_,
176 // StrEq(PSUInventoryPath)))
177 // .Times(1);
178 }
179 catch (...)
180 {
181 ADD_FAILURE() << "Should not have caught exception.";
182 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600183}
184
185TEST_F(PowerSupplyTests, Analyze)
186{
187 auto bus = sdbusplus::bus::new_default();
188
Brandon Wymanb654c612021-11-05 23:24:51 +0000189 {
190 // If I default to reading the GPIO, I will NOT expect a call to
191 // getPresence().
B. J. Wyman681b2a32021-04-20 22:31:22 +0000192
Brandon Wymanb654c612021-11-05 23:24:51 +0000193 PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
194 MockedGPIOInterface* mockPresenceGPIO =
195 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
196 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000197
Brandon Wymanb654c612021-11-05 23:24:51 +0000198 psu.analyze();
199 // By default, nothing should change.
200 EXPECT_EQ(psu.isPresent(), false);
201 EXPECT_EQ(psu.isFaulted(), false);
202 EXPECT_EQ(psu.hasInputFault(), false);
203 EXPECT_EQ(psu.hasMFRFault(), false);
204 EXPECT_EQ(psu.hasVINUVFault(), false);
205 EXPECT_EQ(psu.hasCommFault(), false);
206 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000207 EXPECT_EQ(psu.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000208 EXPECT_EQ(psu.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000209 EXPECT_EQ(psu.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000210 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000211 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000212 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600213
B. J. Wyman681b2a32021-04-20 22:31:22 +0000214 PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
215 // In order to get the various faults tested, the power supply needs to
216 // be present in order to read from the PMBus device(s).
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000217 MockedGPIOInterface* mockPresenceGPIO2 =
218 static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO());
Brandon Wyman06ca4592021-12-06 22:52:23 +0000219 // Always return 1 to indicate present.
220 // Each analyze() call will trigger a read of the presence GPIO.
221 EXPECT_CALL(*mockPresenceGPIO2, read()).WillRepeatedly(Return(1));
222 // Not present until analyze() does the GPIO read.
B. J. Wyman681b2a32021-04-20 22:31:22 +0000223 EXPECT_EQ(psu2.isPresent(), false);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600224
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600225 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus());
Brandon Wyman06ca4592021-12-06 22:52:23 +0000226 // First analyze() call will trigger missing to present, requiring update
227 // to find the new HWMON directory.
228 EXPECT_CALL(mockPMBus, findHwmonDir());
Brandon Wyman8da35c52021-10-28 22:45:08 +0000229 // Presence change from missing to present will trigger write to
230 // ON_OFF_CONFIG.
231 EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, _, _));
Brandon Wymanb654c612021-11-05 23:24:51 +0000232 // Presence change from missing to present will trigger in1_input read
233 // in an attempt to get CLEAR_FAULTS called.
Brandon Wymanf07bc792021-10-12 19:00:35 +0000234 EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(206000));
Brandon Wyman06ca4592021-12-06 22:52:23 +0000235 // Change from missing to present will trigger call to update Present
236 // property in the inventory
237 EXPECT_CALL(mockedUtil, setPresence(_, _, true, _));
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600238
Brandon Wymanb654c612021-11-05 23:24:51 +0000239 // STATUS_WORD INPUT fault.
240 {
241 // Start with STATUS_WORD 0x0000. Powered on, no faults.
242 // Set expectations for a no fault
243 PMBusExpectations expectations;
244 setPMBusExpectations(mockPMBus, expectations);
245 psu2.analyze();
246 EXPECT_EQ(psu2.isPresent(), true);
247 EXPECT_EQ(psu2.isFaulted(), false);
248 EXPECT_EQ(psu2.hasInputFault(), false);
249 EXPECT_EQ(psu2.hasMFRFault(), false);
250 EXPECT_EQ(psu2.hasVINUVFault(), false);
251 EXPECT_EQ(psu2.hasCommFault(), false);
252 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000253 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000254 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000255 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000256 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000257 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000258
259 // Update expectations for STATUS_WORD input fault/warn
Brandon Wyman96893a42021-11-05 19:56:57 +0000260 // STATUS_INPUT fault bits ... on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000261 expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
262 expectations.statusInputValue = 0x38;
263 setPMBusExpectations(mockPMBus, expectations);
264 psu2.analyze();
265 EXPECT_EQ(psu2.isPresent(), true);
266 EXPECT_EQ(psu2.isFaulted(), true);
267 EXPECT_EQ(psu2.hasInputFault(), true);
268 EXPECT_EQ(psu2.hasMFRFault(), false);
269 EXPECT_EQ(psu2.hasVINUVFault(), false);
270 EXPECT_EQ(psu2.hasCommFault(), false);
271 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000272 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000273 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000274 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000275 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000276 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000277 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600278
279 // STATUS_WORD INPUT/UV fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000280 {
281 // First need it to return good status, then the fault
282 PMBusExpectations expectations;
283 setPMBusExpectations(mockPMBus, expectations);
284 psu2.analyze();
285 // Now set fault bits in STATUS_WORD
286 expectations.statusWordValue =
287 (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT);
288 // STATUS_INPUT fault bits ... on.
289 expectations.statusInputValue = 0x38;
290 setPMBusExpectations(mockPMBus, expectations);
291 psu2.analyze();
292 EXPECT_EQ(psu2.isPresent(), true);
293 EXPECT_EQ(psu2.isFaulted(), true);
294 EXPECT_EQ(psu2.hasInputFault(), true);
295 EXPECT_EQ(psu2.hasMFRFault(), false);
296 EXPECT_EQ(psu2.hasVINUVFault(), true);
297 EXPECT_EQ(psu2.hasCommFault(), false);
298 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000299 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000300 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000301 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000302 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000303 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000304 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600305
306 // STATUS_WORD MFR fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000307 {
308 // First need it to return good status, then the fault
309 PMBusExpectations expectations;
310 setPMBusExpectations(mockPMBus, expectations);
311 psu2.analyze();
312 // Now STATUS_WORD with MFR fault bit on.
313 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
314 // STATUS_MFR bits on.
315 expectations.statusMFRValue = 0xFF;
316 setPMBusExpectations(mockPMBus, expectations);
317 psu2.analyze();
318 EXPECT_EQ(psu2.isPresent(), true);
319 EXPECT_EQ(psu2.isFaulted(), true);
320 EXPECT_EQ(psu2.hasInputFault(), false);
321 EXPECT_EQ(psu2.hasMFRFault(), true);
322 EXPECT_EQ(psu2.hasVINUVFault(), false);
323 EXPECT_EQ(psu2.hasCommFault(), false);
324 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000325 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000326 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000327 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000328 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000329 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000330 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600331
Brandon Wyman96893a42021-11-05 19:56:57 +0000332 // Temperature fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000333 {
334 // First STATUS_WORD with no bits set, then with temperature fault.
335 PMBusExpectations expectations;
336 setPMBusExpectations(mockPMBus, expectations);
337 psu2.analyze();
338 // STATUS_WORD with temperature fault bit on.
339 expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
Brandon Wyman96893a42021-11-05 19:56:57 +0000340 // STATUS_TEMPERATURE with fault bit(s) on.
341 expectations.statusTempValue = 0x10;
Brandon Wymanb654c612021-11-05 23:24:51 +0000342 setPMBusExpectations(mockPMBus, expectations);
343 psu2.analyze();
344 EXPECT_EQ(psu2.isPresent(), true);
Brandon Wyman96893a42021-11-05 19:56:57 +0000345 EXPECT_EQ(psu2.isFaulted(), true);
Brandon Wymanb654c612021-11-05 23:24:51 +0000346 EXPECT_EQ(psu2.hasInputFault(), false);
347 EXPECT_EQ(psu2.hasMFRFault(), false);
348 EXPECT_EQ(psu2.hasVINUVFault(), false);
349 EXPECT_EQ(psu2.hasCommFault(), false);
350 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000351 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000352 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000353 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000354 EXPECT_EQ(psu2.hasTempFault(), true);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000355 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000356 }
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000357
358 // CML fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000359 {
360 // First STATUS_WORD wit no bits set, then with CML fault.
361 PMBusExpectations expectations;
362 setPMBusExpectations(mockPMBus, expectations);
363 psu2.analyze();
364 // STATUS_WORD with CML fault bit on.
365 expectations.statusWordValue = (status_word::CML_FAULT);
366 // Turn on STATUS_CML fault bit(s)
367 expectations.statusCMLValue = 0xFF;
368 setPMBusExpectations(mockPMBus, expectations);
369 psu2.analyze();
370 EXPECT_EQ(psu2.isPresent(), true);
371 EXPECT_EQ(psu2.isFaulted(), true);
372 EXPECT_EQ(psu2.hasInputFault(), false);
373 EXPECT_EQ(psu2.hasMFRFault(), false);
374 EXPECT_EQ(psu2.hasVINUVFault(), false);
375 EXPECT_EQ(psu2.hasCommFault(), true);
376 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000377 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000378 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000379 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000380 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000381 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000382 }
Brandon Wyman6710ba22021-10-27 17:39:31 +0000383
384 // VOUT_OV_FAULT fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000385 {
386 // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault.
387 PMBusExpectations expectations;
388 setPMBusExpectations(mockPMBus, expectations);
389 psu2.analyze();
390 // STATUS_WORD with VOUT/VOUT_OV fault.
391 expectations.statusWordValue =
392 ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT));
393 // Turn on STATUS_VOUT fault bit(s)
394 expectations.statusVOUTValue = 0xA0;
Brandon Wyman96893a42021-11-05 19:56:57 +0000395 // STATUS_TEMPERATURE don't care (default)
Brandon Wymanb654c612021-11-05 23:24:51 +0000396 setPMBusExpectations(mockPMBus, expectations);
397 psu2.analyze();
398 EXPECT_EQ(psu2.isPresent(), true);
399 EXPECT_EQ(psu2.isFaulted(), true);
400 EXPECT_EQ(psu2.hasInputFault(), false);
401 EXPECT_EQ(psu2.hasMFRFault(), false);
402 EXPECT_EQ(psu2.hasVINUVFault(), false);
403 EXPECT_EQ(psu2.hasCommFault(), false);
404 EXPECT_EQ(psu2.hasVoutOVFault(), true);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000405 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000406 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000407 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000408 EXPECT_EQ(psu2.hasTempFault(), false);
409 EXPECT_EQ(psu2.hasPgoodFault(), false);
410 }
411
412 // IOUT_OC_FAULT fault
413 {
414 // First STATUS_WORD with no bits set, then with IOUT_OC fault.
415 PMBusExpectations expectations;
416 setPMBusExpectations(mockPMBus, expectations);
417 psu2.analyze();
418 // STATUS_WORD with IOUT_OC fault.
419 expectations.statusWordValue = status_word::IOUT_OC_FAULT;
420 // Turn on STATUS_IOUT fault bit(s)
421 expectations.statusIOUTValue = 0x88;
422 setPMBusExpectations(mockPMBus, expectations);
423 psu2.analyze();
424 EXPECT_EQ(psu2.isPresent(), true);
425 EXPECT_EQ(psu2.isFaulted(), true);
426 EXPECT_EQ(psu2.hasInputFault(), false);
427 EXPECT_EQ(psu2.hasMFRFault(), false);
428 EXPECT_EQ(psu2.hasVINUVFault(), false);
429 EXPECT_EQ(psu2.hasCommFault(), false);
430 EXPECT_EQ(psu2.hasVoutOVFault(), false);
431 EXPECT_EQ(psu2.hasIoutOCFault(), true);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000432 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000433 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000434 EXPECT_EQ(psu2.hasTempFault(), false);
435 EXPECT_EQ(psu2.hasPgoodFault(), false);
436 }
437
438 // VOUT_UV_FAULT
439 {
440 // First STATUS_WORD with no bits set, then with VOUT fault.
441 PMBusExpectations expectations;
442 setPMBusExpectations(mockPMBus, expectations);
443 psu2.analyze();
444 // Change STATUS_WORD to indicate VOUT fault.
445 expectations.statusWordValue = (status_word::VOUT_FAULT);
446 // Turn on STATUS_VOUT fault bit(s)
447 expectations.statusVOUTValue = 0x30;
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(), false);
458 EXPECT_EQ(psu2.hasVoutUVFault(), true);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000459 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000460 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000461 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000462 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600463
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000464 // Fan fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000465 {
466 // First STATUS_WORD with no bits set, then with fan fault.
467 PMBusExpectations expectations;
468 setPMBusExpectations(mockPMBus, expectations);
469 psu2.analyze();
470 expectations.statusWordValue = (status_word::FAN_FAULT);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000471 // STATUS_FANS_1_2 with fan 1 warning & fault bits on.
472 expectations.statusFans12Value = 0xA0;
Brandon Wymanb654c612021-11-05 23:24:51 +0000473 setPMBusExpectations(mockPMBus, expectations);
474 psu2.analyze();
475 EXPECT_EQ(psu2.isPresent(), true);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000476 EXPECT_EQ(psu2.isFaulted(), true);
Brandon Wymanb654c612021-11-05 23:24:51 +0000477 EXPECT_EQ(psu2.hasInputFault(), false);
478 EXPECT_EQ(psu2.hasMFRFault(), false);
479 EXPECT_EQ(psu2.hasVINUVFault(), false);
480 EXPECT_EQ(psu2.hasCommFault(), false);
481 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000482 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000483 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000484 EXPECT_EQ(psu2.hasFanFault(), true);
Brandon Wyman96893a42021-11-05 19:56:57 +0000485 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000486 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000487 }
Brandon Wyman2916ea52021-11-06 03:31:18 +0000488
Brandon Wyman06ca4592021-12-06 22:52:23 +0000489 // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT.
Brandon Wyman2916ea52021-11-06 03:31:18 +0000490 {
Brandon Wyman2916ea52021-11-06 03:31:18 +0000491 // First STATUS_WORD with no bits set.
492 PMBusExpectations expectations;
493 setPMBusExpectations(mockPMBus, expectations);
494 psu2.analyze();
495 EXPECT_EQ(psu2.isFaulted(), false);
496 // POWER_GOOD# inactive, and OFF bit on.
497 expectations.statusWordValue =
498 ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF));
Brandon Wyman06ca4592021-12-06 22:52:23 +0000499 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
500 {
501 // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and
502 // STATUS_TEMPERATURE: Don't care if bits set or not (defaults).
503 setPMBusExpectations(mockPMBus, expectations);
504 psu2.analyze();
505 EXPECT_EQ(psu2.isPresent(), true);
506 if (x < DEGLITCH_LIMIT)
507 {
508 EXPECT_EQ(psu2.isFaulted(), false);
509 }
510 else
511 {
512 EXPECT_EQ(psu2.isFaulted(), true);
513 }
514 EXPECT_EQ(psu2.hasInputFault(), false);
515 EXPECT_EQ(psu2.hasMFRFault(), false);
516 EXPECT_EQ(psu2.hasVINUVFault(), false);
517 EXPECT_EQ(psu2.hasCommFault(), false);
518 EXPECT_EQ(psu2.hasVoutOVFault(), false);
519 EXPECT_EQ(psu2.hasVoutUVFault(), false);
520 EXPECT_EQ(psu2.hasIoutOCFault(), false);
521 EXPECT_EQ(psu2.hasFanFault(), false);
522 EXPECT_EQ(psu2.hasTempFault(), false);
523 if (x < DEGLITCH_LIMIT)
524 {
525 EXPECT_EQ(psu2.hasPgoodFault(), false);
526 }
527 else
528 {
529 EXPECT_EQ(psu2.hasPgoodFault(), true);
530 }
531 }
Brandon Wyman2916ea52021-11-06 03:31:18 +0000532 }
533
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600534 // TODO: ReadFailure
535}
536
Brandon Wyman59a35792020-06-04 12:37:40 -0500537TEST_F(PowerSupplyTests, OnOffConfig)
538{
539 auto bus = sdbusplus::bus::new_default();
540 uint8_t data = 0x15;
541
542 // Test where PSU is NOT present
543 try
544 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000545 // Assume GPIO presence, not inventory presence?
546 PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
547
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000548 MockedGPIOInterface* mockPresenceGPIO =
549 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000550 ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0));
Brandon Wyman59a35792020-06-04 12:37:40 -0500551 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000552 // Constructor should set initial presence, default read returns 0.
Brandon Wyman59a35792020-06-04 12:37:40 -0500553 // If it is not present, I should not be trying to write to it.
554 EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0);
555 psu.onOffConfig(data);
556 }
557 catch (...)
Adriana Kobylak0c9a33d2021-09-13 18:05:09 +0000558 {}
Brandon Wyman59a35792020-06-04 12:37:40 -0500559
560 // Test where PSU is present
561 try
562 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000563 // Assume GPIO presence, not inventory presence?
564 PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000565 MockedGPIOInterface* mockPresenceGPIO =
566 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000567 ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(1));
Brandon Wyman59a35792020-06-04 12:37:40 -0500568 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000569 // TODO: expect setPresence call?
570 // updatePresence() private function reads gpio, called by analyze().
571 psu.analyze();
Brandon Wyman59a35792020-06-04 12:37:40 -0500572 // TODO: ???should I check the filename?
573 EXPECT_CALL(mockPMBus,
574 writeBinary(_, ElementsAre(0x15), Type::HwmonDeviceDebug))
575 .Times(1);
576 psu.onOffConfig(data);
577 }
578 catch (...)
Adriana Kobylak0c9a33d2021-09-13 18:05:09 +0000579 {}
Brandon Wyman59a35792020-06-04 12:37:40 -0500580}
581
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600582TEST_F(PowerSupplyTests, ClearFaults)
583{
584 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000585 PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000586 MockedGPIOInterface* mockPresenceGPIO =
587 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wyman06ca4592021-12-06 22:52:23 +0000588 // Always return 1 to indicate present.
589 // Each analyze() call will trigger a read of the presence GPIO.
590 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000591 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman06ca4592021-12-06 22:52:23 +0000592 // Change from missing to present will trigger HWMON directory update.
593 EXPECT_CALL(mockPMBus, findHwmonDir());
594 // Change from missing to present will trigger ON_OFF_CONFIG write.
595 EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, _, _));
Brandon Wyman8da35c52021-10-28 22:45:08 +0000596 // Presence change from missing to present will trigger in1_input read in
597 // an attempt to get CLEAR_FAULTS called.
598 EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(206000));
Brandon Wyman06ca4592021-12-06 22:52:23 +0000599 // Missing/present call will update Presence in inventory.
600 EXPECT_CALL(mockedUtil, setPresence(_, _, true, _));
Brandon Wyman8da35c52021-10-28 22:45:08 +0000601 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000602 PMBusExpectations expectations;
603 setPMBusExpectations(mockPMBus, expectations);
B. J. Wyman681b2a32021-04-20 22:31:22 +0000604 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600605 EXPECT_EQ(psu.isPresent(), true);
606 EXPECT_EQ(psu.isFaulted(), false);
607 EXPECT_EQ(psu.hasInputFault(), false);
608 EXPECT_EQ(psu.hasMFRFault(), false);
609 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000610 EXPECT_EQ(psu.hasCommFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000611 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000612 EXPECT_EQ(psu.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000613 EXPECT_EQ(psu.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000614 EXPECT_EQ(psu.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000615 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000616 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000617
Brandon Wymanf07bc792021-10-12 19:00:35 +0000618 // STATUS_WORD with fault bits galore!
Brandon Wymanb654c612021-11-05 23:24:51 +0000619 expectations.statusWordValue = 0xFFFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000620 // STATUS_INPUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000621 expectations.statusInputValue = 0xFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000622 // STATUS_MFR_SPEFIC with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000623 expectations.statusMFRValue = 0xFF;
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000624 // STATUS_CML with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000625 expectations.statusCMLValue = 0xFF;
Brandon Wyman6710ba22021-10-27 17:39:31 +0000626 // STATUS_VOUT with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000627 expectations.statusVOUTValue = 0xFF;
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000628 // STATUS_IOUT with bits on.
629 expectations.statusIOUTValue = 0xFF;
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000630 // STATUS_FANS_1_2 with bits on.
631 expectations.statusFans12Value = 0xFF;
Brandon Wyman96893a42021-11-05 19:56:57 +0000632 // STATUS_TEMPERATURE with bits on.
633 expectations.statusTempValue = 0xFF;
Brandon Wymanb654c612021-11-05 23:24:51 +0000634 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600635 psu.analyze();
636 EXPECT_EQ(psu.isPresent(), true);
637 EXPECT_EQ(psu.isFaulted(), true);
638 EXPECT_EQ(psu.hasInputFault(), true);
639 EXPECT_EQ(psu.hasMFRFault(), true);
640 EXPECT_EQ(psu.hasVINUVFault(), true);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000641 EXPECT_EQ(psu.hasCommFault(), true);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000642 EXPECT_EQ(psu.hasVoutOVFault(), true);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000643 EXPECT_EQ(psu.hasIoutOCFault(), true);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000644 // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
645 // Rely on HasVoutUVFault() to verify this sets and clears.
646 EXPECT_EQ(psu.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000647 EXPECT_EQ(psu.hasFanFault(), true);
Brandon Wyman96893a42021-11-05 19:56:57 +0000648 EXPECT_EQ(psu.hasTempFault(), true);
Brandon Wyman06ca4592021-12-06 22:52:23 +0000649 // pgoodFault is deglitched up to DEGLITCH_LIMIT
650 EXPECT_EQ(psu.hasPgoodFault(), false);
651 setPMBusExpectations(mockPMBus, expectations);
652 psu.analyze();
653 EXPECT_EQ(psu.hasPgoodFault(), false);
654 setPMBusExpectations(mockPMBus, expectations);
655 psu.analyze();
656 // DEGLITCH_LIMIT reached for pgoodFault
Brandon Wyman2916ea52021-11-06 03:31:18 +0000657 EXPECT_EQ(psu.hasPgoodFault(), true);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000658
Brandon Wyman3c208462020-05-13 16:25:58 -0500659 EXPECT_CALL(mockPMBus, read("in1_input", _))
660 .Times(1)
661 .WillOnce(Return(209000));
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600662 psu.clearFaults();
663 EXPECT_EQ(psu.isPresent(), true);
664 EXPECT_EQ(psu.isFaulted(), false);
665 EXPECT_EQ(psu.hasInputFault(), false);
666 EXPECT_EQ(psu.hasMFRFault(), false);
667 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000668 EXPECT_EQ(psu.hasCommFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000669 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000670 EXPECT_EQ(psu.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000671 EXPECT_EQ(psu.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000672 EXPECT_EQ(psu.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000673 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000674 EXPECT_EQ(psu.hasPgoodFault(), false);
B. J. Wyman681b2a32021-04-20 22:31:22 +0000675
676 // TODO: Faults clear on missing/present?
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600677}
678
679TEST_F(PowerSupplyTests, UpdateInventory)
680{
681 auto bus = sdbusplus::bus::new_default();
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500682
683 try
684 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000685 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500686 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
687 // If it is not present, I should not be trying to read a string
688 EXPECT_CALL(mockPMBus, readString(_, _)).Times(0);
689 psu.updateInventory();
690 }
691 catch (...)
692 {
693 ADD_FAILURE() << "Should not have caught exception.";
694 }
695
696 try
697 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000698 PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000699 MockedGPIOInterface* mockPresenceGPIO =
700 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000701 // GPIO read return 1 to indicate present.
702 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
703 psu.analyze();
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500704 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
705 EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return(""));
706 psu.updateInventory();
707
Brandon Wyman3c530fb2021-04-13 13:13:22 -0500708#if IBM_VPD
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500709 EXPECT_CALL(mockPMBus, readString(_, _))
710 .WillOnce(Return("CCIN"))
711 .WillOnce(Return("PN3456"))
712 .WillOnce(Return("FN3456"))
713 .WillOnce(Return("HEADER"))
714 .WillOnce(Return("SN3456"))
715 .WillOnce(Return("FW3456"));
Brandon Wyman3c530fb2021-04-13 13:13:22 -0500716#endif
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500717 psu.updateInventory();
718 // TODO: D-Bus mocking to verify values stored on D-Bus (???)
719 }
720 catch (...)
721 {
722 ADD_FAILURE() << "Should not have caught exception.";
723 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600724}
725
726TEST_F(PowerSupplyTests, IsPresent)
727{
728 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000729
730 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000731 MockedGPIOInterface* mockPresenceGPIO =
732 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600733 EXPECT_EQ(psu.isPresent(), false);
734
B. J. Wyman681b2a32021-04-20 22:31:22 +0000735 // Change GPIO read to return 1 to indicate present.
736 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
737 psu.analyze();
738 EXPECT_EQ(psu.isPresent(), true);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600739}
740
741TEST_F(PowerSupplyTests, IsFaulted)
742{
743 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000744
745 PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000746 MockedGPIOInterface* mockPresenceGPIO =
747 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000748 // Always return 1 to indicate present.
749 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
750 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600751 EXPECT_EQ(psu.isFaulted(), false);
752 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wymanb654c612021-11-05 23:24:51 +0000753 PMBusExpectations expectations;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000754 // STATUS_WORD with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000755 expectations.statusWordValue = 0xFFFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000756 // STATUS_INPUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000757 expectations.statusInputValue = 0xFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000758 // STATUS_MFR_SPECIFIC with faults bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000759 expectations.statusMFRValue = 0xFF;
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000760 // STATUS_CML with faults bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000761 expectations.statusCMLValue = 0xFF;
Brandon Wyman6710ba22021-10-27 17:39:31 +0000762 // STATUS_VOUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000763 expectations.statusVOUTValue = 0xFF;
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000764 // STATUS_IOUT with fault bits on.
765 expectations.statusIOUTValue = 0xFF;
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000766 // STATUS_FANS_1_2 with bits on.
767 expectations.statusFans12Value = 0xFF;
Brandon Wyman96893a42021-11-05 19:56:57 +0000768 // STATUS_TEMPERATURE with fault bits on.
769 expectations.statusTempValue = 0xFF;
Brandon Wymanb654c612021-11-05 23:24:51 +0000770 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600771 psu.analyze();
772 EXPECT_EQ(psu.isFaulted(), true);
773}
774
775TEST_F(PowerSupplyTests, HasInputFault)
776{
777 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000778
779 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000780 MockedGPIOInterface* mockPresenceGPIO =
781 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000782 // Always return 1 to indicate present.
783 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
784 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600785 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
786 EXPECT_EQ(psu.hasInputFault(), false);
Brandon Wyman8da35c52021-10-28 22:45:08 +0000787 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000788 PMBusExpectations expectations;
789 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600790 psu.analyze();
791 EXPECT_EQ(psu.hasInputFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000792 // STATUS_WORD with input fault/warn on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000793 expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000794 // STATUS_INPUT with an input fault bit on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000795 expectations.statusInputValue = 0x80;
796 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600797 psu.analyze();
798 EXPECT_EQ(psu.hasInputFault(), true);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000799 // STATUS_WORD with no bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000800 expectations.statusWordValue = 0;
801 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600802 psu.analyze();
803 EXPECT_EQ(psu.hasInputFault(), false);
804}
805
806TEST_F(PowerSupplyTests, HasMFRFault)
807{
808 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000809
810 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000811 MockedGPIOInterface* mockPresenceGPIO =
812 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000813 // Always return 1 to indicate present.
814 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
815 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600816 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
817 EXPECT_EQ(psu.hasMFRFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000818 // First return STATUS_WORD with no bits on.
Brandon Wyman8da35c52021-10-28 22:45:08 +0000819 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000820 PMBusExpectations expectations;
821 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600822 psu.analyze();
823 EXPECT_EQ(psu.hasMFRFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000824 // Next return STATUS_WORD with MFR fault bit on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000825 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000826 // STATUS_MFR_SPEFIC with bit(s) on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000827 expectations.statusMFRValue = 0xFF;
828 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600829 psu.analyze();
830 EXPECT_EQ(psu.hasMFRFault(), true);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000831 // Back to no bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +0000832 expectations.statusWordValue = 0;
833 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600834 psu.analyze();
835 EXPECT_EQ(psu.hasMFRFault(), false);
836}
837
838TEST_F(PowerSupplyTests, HasVINUVFault)
839{
840 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000841
842 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000843 MockedGPIOInterface* mockPresenceGPIO =
844 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000845 // Always return 1 to indicate present.
846 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
847 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600848 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
849 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wyman8da35c52021-10-28 22:45:08 +0000850 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000851 PMBusExpectations expectations;
852 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600853 psu.analyze();
854 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000855 // Turn fault on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000856 expectations.statusWordValue = (status_word::VIN_UV_FAULT);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000857 // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by
858 // Figure 16, and assume bits on in STATUS_INPUT.
Brandon Wymanb654c612021-11-05 23:24:51 +0000859 expectations.statusInputValue = 0x18;
860 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600861 psu.analyze();
862 EXPECT_EQ(psu.hasVINUVFault(), true);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000863 // Back to no fault bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +0000864 expectations.statusWordValue = 0;
865 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600866 psu.analyze();
867 EXPECT_EQ(psu.hasVINUVFault(), false);
868}
Brandon Wyman6710ba22021-10-27 17:39:31 +0000869
870TEST_F(PowerSupplyTests, HasVoutOVFault)
871{
872 auto bus = sdbusplus::bus::new_default();
873
874 PowerSupply psu{bus, PSUInventoryPath, 3, 0x69, PSUGPIOLineName};
875 MockedGPIOInterface* mockPresenceGPIO =
876 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
877 // Always return 1 to indicate present.
878 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
879 psu.analyze();
880 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
881 EXPECT_EQ(psu.hasVoutOVFault(), false);
882 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000883 PMBusExpectations expectations;
884 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000885 psu.analyze();
886 EXPECT_EQ(psu.hasVoutOVFault(), false);
887 // Turn fault on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000888 expectations.statusWordValue = (status_word::VOUT_OV_FAULT);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000889 // STATUS_VOUT fault bit(s)
Brandon Wymanb654c612021-11-05 23:24:51 +0000890 expectations.statusVOUTValue = 0x80;
Brandon Wyman96893a42021-11-05 19:56:57 +0000891 // STATUS_TEMPERATURE default.
Brandon Wymanb654c612021-11-05 23:24:51 +0000892 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000893 psu.analyze();
894 EXPECT_EQ(psu.hasVoutOVFault(), true);
895 // Back to no fault bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +0000896 expectations.statusWordValue = 0;
897 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000898 psu.analyze();
899 EXPECT_EQ(psu.hasVoutOVFault(), false);
900}
Brandon Wyman96893a42021-11-05 19:56:57 +0000901
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000902TEST_F(PowerSupplyTests, HasIoutOCFault)
903{
904 auto bus = sdbusplus::bus::new_default();
905
906 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName};
907 MockedGPIOInterface* mockPresenceGPIO =
908 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
909 // Always return 1 to indicate present.
910 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
911 psu.analyze();
912 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
913 EXPECT_EQ(psu.hasIoutOCFault(), false);
914 // STATUS_WORD 0x0000 is powered on, no faults.
915 PMBusExpectations expectations;
916 setPMBusExpectations(mockPMBus, expectations);
917 psu.analyze();
918 EXPECT_EQ(psu.hasIoutOCFault(), false);
919 // Turn fault on.
920 expectations.statusWordValue = status_word::IOUT_OC_FAULT;
921 // STATUS_IOUT fault bit(s)
922 expectations.statusIOUTValue = 0x88;
923 setPMBusExpectations(mockPMBus, expectations);
924 psu.analyze();
925 EXPECT_EQ(psu.hasIoutOCFault(), true);
926 // Back to no fault bits on in STATUS_WORD
927 expectations.statusWordValue = 0;
928 setPMBusExpectations(mockPMBus, expectations);
929 psu.analyze();
930 EXPECT_EQ(psu.hasIoutOCFault(), false);
931}
932
Brandon Wyman2cf46942021-10-28 19:09:16 +0000933TEST_F(PowerSupplyTests, HasVoutUVFault)
934{
935 auto bus = sdbusplus::bus::new_default();
936
937 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName};
938 MockedGPIOInterface* mockPresenceGPIO =
939 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
940 // Always return 1 to indicate present.
941 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
942 psu.analyze();
943 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
944 EXPECT_EQ(psu.hasVoutUVFault(), false);
945 PMBusExpectations expectations;
946 setPMBusExpectations(mockPMBus, expectations);
947 psu.analyze();
948 EXPECT_EQ(psu.hasVoutUVFault(), false);
949 // Turn fault on.
950 expectations.statusWordValue = (status_word::VOUT_FAULT);
951 // STATUS_VOUT fault bit(s)
952 expectations.statusVOUTValue = 0x30;
953 setPMBusExpectations(mockPMBus, expectations);
954 psu.analyze();
955 EXPECT_EQ(psu.hasVoutUVFault(), true);
956 // Back to no fault bits on in STATUS_WORD
957 expectations.statusWordValue = 0;
958 setPMBusExpectations(mockPMBus, expectations);
959 psu.analyze();
960 EXPECT_EQ(psu.hasVoutUVFault(), false);
961}
962
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000963TEST_F(PowerSupplyTests, HasFanFault)
964{
965 auto bus = sdbusplus::bus::new_default();
966
967 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName};
968 MockedGPIOInterface* mockPresenceGPIO =
969 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
970 // Always return 1 to indicate present.
971 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
972 psu.analyze();
973 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
974 EXPECT_EQ(psu.hasFanFault(), false);
975 // STATUS_WORD 0x0000 is powered on, no faults.
976 PMBusExpectations expectations;
977 setPMBusExpectations(mockPMBus, expectations);
978 psu.analyze();
979 EXPECT_EQ(psu.hasFanFault(), false);
980 // Turn fault on.
981 expectations.statusWordValue = (status_word::FAN_FAULT);
982 // STATUS_FANS_1_2 fault bit on (Fan 1 Fault)
983 expectations.statusFans12Value = 0x80;
984 setPMBusExpectations(mockPMBus, expectations);
985 psu.analyze();
986 EXPECT_EQ(psu.hasFanFault(), true);
987 // Back to no fault bits on in STATUS_WORD
988 expectations.statusWordValue = 0;
989 setPMBusExpectations(mockPMBus, expectations);
990 psu.analyze();
991 EXPECT_EQ(psu.hasFanFault(), false);
992}
993
Brandon Wyman96893a42021-11-05 19:56:57 +0000994TEST_F(PowerSupplyTests, HasTempFault)
995{
996 auto bus = sdbusplus::bus::new_default();
997
998 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName};
999 MockedGPIOInterface* mockPresenceGPIO =
1000 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1001 // Always return 1 to indicate present.
1002 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
1003 psu.analyze();
1004 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1005 EXPECT_EQ(psu.hasTempFault(), false);
1006 // STATUS_WORD 0x0000 is powered on, no faults.
1007 PMBusExpectations expectations;
1008 setPMBusExpectations(mockPMBus, expectations);
1009 psu.analyze();
1010 EXPECT_EQ(psu.hasTempFault(), false);
1011 // Turn fault on.
1012 expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
1013 // STATUS_TEMPERATURE fault bit on (OT Fault)
1014 expectations.statusTempValue = 0x80;
1015 setPMBusExpectations(mockPMBus, expectations);
1016 psu.analyze();
1017 EXPECT_EQ(psu.hasTempFault(), true);
1018 // Back to no fault bits on in STATUS_WORD
1019 expectations.statusWordValue = 0;
1020 setPMBusExpectations(mockPMBus, expectations);
1021 psu.analyze();
1022 EXPECT_EQ(psu.hasTempFault(), false);
1023}
Brandon Wyman2916ea52021-11-06 03:31:18 +00001024
1025TEST_F(PowerSupplyTests, HasPgoodFault)
1026{
1027 auto bus = sdbusplus::bus::new_default();
1028
1029 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6b, PSUGPIOLineName};
1030 MockedGPIOInterface* mockPresenceGPIO =
1031 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1032 // Always return 1 to indicate present.
1033 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001034 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman06ca4592021-12-06 22:52:23 +00001035 EXPECT_CALL(mockPMBus, findHwmonDir());
1036 // Presence change from missing to present will trigger write to
1037 // ON_OFF_CONFIG.
1038 EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, _, _));
1039 // Missing/present will trigger read of "in1_input" to try CLEAR_FAULTS.
1040 EXPECT_CALL(mockPMBus, read("in1_input", _))
1041 .Times(1)
1042 .WillOnce(Return(207000));
1043 // Missing/present call will update Presence in inventory.
1044 EXPECT_CALL(mockedUtil, setPresence(_, _, true, _));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001045 // STATUS_WORD 0x0000 is powered on, no faults.
1046 PMBusExpectations expectations;
1047 setPMBusExpectations(mockPMBus, expectations);
1048 psu.analyze();
1049 EXPECT_EQ(psu.hasPgoodFault(), false);
1050 // Turn PGOOD# off (fault on).
1051 expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED);
1052 setPMBusExpectations(mockPMBus, expectations);
1053 psu.analyze();
Brandon Wyman06ca4592021-12-06 22:52:23 +00001054 // Expect false until reaches DEGLITCH_LIMIT
1055 EXPECT_EQ(psu.hasPgoodFault(), false);
1056 setPMBusExpectations(mockPMBus, expectations);
1057 psu.analyze();
1058 // Expect false until reaches DEGLITCH_LIMIT
1059 EXPECT_EQ(psu.hasPgoodFault(), false);
1060 setPMBusExpectations(mockPMBus, expectations);
1061 psu.analyze();
1062 // DEGLITCH_LIMIT reached, expect true.
Brandon Wyman2916ea52021-11-06 03:31:18 +00001063 EXPECT_EQ(psu.hasPgoodFault(), true);
1064 // Back to no fault bits on in STATUS_WORD
1065 expectations.statusWordValue = 0;
1066 setPMBusExpectations(mockPMBus, expectations);
1067 psu.analyze();
1068 EXPECT_EQ(psu.hasPgoodFault(), false);
1069 // Turn OFF bit on
1070 expectations.statusWordValue = (status_word::UNIT_IS_OFF);
1071 setPMBusExpectations(mockPMBus, expectations);
1072 psu.analyze();
Brandon Wyman06ca4592021-12-06 22:52:23 +00001073 EXPECT_EQ(psu.hasPgoodFault(), false);
1074 setPMBusExpectations(mockPMBus, expectations);
1075 psu.analyze();
1076 EXPECT_EQ(psu.hasPgoodFault(), false);
1077 setPMBusExpectations(mockPMBus, expectations);
1078 psu.analyze();
Brandon Wyman2916ea52021-11-06 03:31:18 +00001079 EXPECT_EQ(psu.hasPgoodFault(), true);
1080 // Back to no fault bits on in STATUS_WORD
1081 expectations.statusWordValue = 0;
1082 setPMBusExpectations(mockPMBus, expectations);
1083 psu.analyze();
1084 EXPECT_EQ(psu.hasPgoodFault(), false);
1085}