blob: 1eec2a0d0f24ff3cf2df9a5968dcaaccfea7d7c9 [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
Brandon Wyman391a0692021-12-08 23:28:18 +000095// Helper function for when a power supply goes from missing to present.
96void setMissingToPresentExpects(MockedPMBus& pmbus, const MockedUtil& util)
97{
98 // Call to analyze() will update to present, that will trigger updating
99 // to the correct/latest HWMON directory, in case it changes.
100 EXPECT_CALL(pmbus, findHwmonDir());
101 // Presence change from missing to present will trigger write to
102 // ON_OFF_CONFIG.
103 EXPECT_CALL(pmbus, writeBinary(ON_OFF_CONFIG, _, _));
104 // Presence change from missing to present will trigger in1_input read
105 // in an attempt to get CLEAR_FAULTS called.
Brandon Wyman82affd92021-11-24 19:12:49 +0000106 // The voltage defaults to 0, the first call to analyze should update the
107 // voltage to the current reading, triggering another clearing of faults
108 // due to below minimum to within range voltage.
109 // This READ_VIN for CLEAR_FAULTS does not check the returned value.
110 EXPECT_CALL(pmbus, read(READ_VIN, _))
111 .Times(2)
112 .WillOnce(Return(1))
113 .WillOnce(Return(2));
Brandon Wyman391a0692021-12-08 23:28:18 +0000114 // Missing/present call will update Presence in inventory.
Brandon Wyman391a0692021-12-08 23:28:18 +0000115 EXPECT_CALL(util, setPresence(_, _, true, _));
116}
117
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600118TEST_F(PowerSupplyTests, Constructor)
119{
120 /**
121 * @param[in] invpath - String for inventory path to use
122 * @param[in] i2cbus - The bus number this power supply is on
123 * @param[in] i2caddr - The 16-bit I2C address of the power supply
B. J. Wyman681b2a32021-04-20 22:31:22 +0000124 * @param[in] gpioLineName - The string for the gpio-line-name to read for
125 * presence.
126 * @param[in] bindDelay - Time in milliseconds to delay binding the device
127 * driver after seeing the presence line go active.
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600128 */
129 auto bus = sdbusplus::bus::new_default();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600130
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500131 // Try where inventory path is empty, constructor should fail.
132 try
133 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000134 auto psu =
135 std::make_unique<PowerSupply>(bus, "", 3, 0x68, PSUGPIOLineName);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500136 ADD_FAILURE() << "Should not have reached this line.";
137 }
138 catch (const std::invalid_argument& e)
139 {
140 EXPECT_STREQ(e.what(), "Invalid empty inventoryPath");
141 }
142 catch (...)
143 {
144 ADD_FAILURE() << "Should not have caught exception.";
145 }
146
B. J. Wyman681b2a32021-04-20 22:31:22 +0000147 // TODO: Try invalid i2c address?
148
149 // Try where gpioLineName is empty.
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500150 try
151 {
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500152 auto psu =
B. J. Wyman681b2a32021-04-20 22:31:22 +0000153 std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68, "");
154 ADD_FAILURE()
155 << "Should not have reached this line. Invalid gpioLineName.";
156 }
157 catch (const std::invalid_argument& e)
158 {
159 EXPECT_STREQ(e.what(), "Invalid empty gpioLineName");
160 }
161 catch (...)
162 {
163 ADD_FAILURE() << "Should not have caught exception.";
164 }
165
166 // Test with valid arguments
167 // NOT using D-Bus inventory path for presence.
168 try
169 {
170 auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68,
171 PSUGPIOLineName);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500172
173 EXPECT_EQ(psu->isPresent(), false);
174 EXPECT_EQ(psu->isFaulted(), false);
Brandon Wyman8da35c52021-10-28 22:45:08 +0000175 EXPECT_EQ(psu->hasCommFault(), false);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500176 EXPECT_EQ(psu->hasInputFault(), false);
177 EXPECT_EQ(psu->hasMFRFault(), false);
178 EXPECT_EQ(psu->hasVINUVFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000179 EXPECT_EQ(psu->hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000180 EXPECT_EQ(psu->hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000181 EXPECT_EQ(psu->hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000182 EXPECT_EQ(psu->hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000183 EXPECT_EQ(psu->hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000184 EXPECT_EQ(psu->hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000185 EXPECT_EQ(psu->hasPSKillFault(), false);
186 EXPECT_EQ(psu->hasPS12VcsFault(), false);
187 EXPECT_EQ(psu->hasPSCS12VFault(), false);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500188 }
189 catch (...)
190 {
191 ADD_FAILURE() << "Should not have caught exception.";
192 }
B. J. Wyman681b2a32021-04-20 22:31:22 +0000193
194 // Test with valid arguments
195 // TODO: Using D-Bus inventory path for presence.
196 try
197 {
198 // FIXME: How do I get that presenceGPIO.read() in the startup to throw
199 // an exception?
200
201 // EXPECT_CALL(mockedUtil, getPresence(_,
202 // StrEq(PSUInventoryPath)))
203 // .Times(1);
204 }
205 catch (...)
206 {
207 ADD_FAILURE() << "Should not have caught exception.";
208 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600209}
210
211TEST_F(PowerSupplyTests, Analyze)
212{
213 auto bus = sdbusplus::bus::new_default();
214
Brandon Wymanb654c612021-11-05 23:24:51 +0000215 {
216 // If I default to reading the GPIO, I will NOT expect a call to
217 // getPresence().
B. J. Wyman681b2a32021-04-20 22:31:22 +0000218
Brandon Wymanb654c612021-11-05 23:24:51 +0000219 PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
220 MockedGPIOInterface* mockPresenceGPIO =
221 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
222 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000223
Brandon Wymanb654c612021-11-05 23:24:51 +0000224 psu.analyze();
225 // By default, nothing should change.
226 EXPECT_EQ(psu.isPresent(), false);
227 EXPECT_EQ(psu.isFaulted(), false);
228 EXPECT_EQ(psu.hasInputFault(), false);
229 EXPECT_EQ(psu.hasMFRFault(), false);
230 EXPECT_EQ(psu.hasVINUVFault(), false);
231 EXPECT_EQ(psu.hasCommFault(), false);
232 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000233 EXPECT_EQ(psu.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000234 EXPECT_EQ(psu.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000235 EXPECT_EQ(psu.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000236 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000237 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000238 EXPECT_EQ(psu.hasPSKillFault(), false);
239 EXPECT_EQ(psu.hasPS12VcsFault(), false);
240 EXPECT_EQ(psu.hasPSCS12VFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000241 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600242
B. J. Wyman681b2a32021-04-20 22:31:22 +0000243 PowerSupply psu2{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
244 // In order to get the various faults tested, the power supply needs to
245 // be present in order to read from the PMBus device(s).
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000246 MockedGPIOInterface* mockPresenceGPIO2 =
247 static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO());
Brandon Wyman06ca4592021-12-06 22:52:23 +0000248 // Always return 1 to indicate present.
249 // Each analyze() call will trigger a read of the presence GPIO.
250 EXPECT_CALL(*mockPresenceGPIO2, read()).WillRepeatedly(Return(1));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000251 EXPECT_EQ(psu2.isPresent(), false);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600252
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600253 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +0000254 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600255
Brandon Wymanb654c612021-11-05 23:24:51 +0000256 // STATUS_WORD INPUT fault.
257 {
258 // Start with STATUS_WORD 0x0000. Powered on, no faults.
259 // Set expectations for a no fault
260 PMBusExpectations expectations;
261 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000262 // After reading STATUS_WORD, etc., there will be a READ_VIN check.
263 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
264 .Times(1)
265 .WillOnce(Return("206000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000266 psu2.analyze();
267 EXPECT_EQ(psu2.isPresent(), true);
268 EXPECT_EQ(psu2.isFaulted(), false);
269 EXPECT_EQ(psu2.hasInputFault(), false);
270 EXPECT_EQ(psu2.hasMFRFault(), false);
271 EXPECT_EQ(psu2.hasVINUVFault(), false);
272 EXPECT_EQ(psu2.hasCommFault(), false);
273 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000274 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000275 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000276 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000277 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000278 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000279 EXPECT_EQ(psu2.hasPSKillFault(), false);
280 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
281 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000282
283 // Update expectations for STATUS_WORD input fault/warn
Brandon Wyman96893a42021-11-05 19:56:57 +0000284 // STATUS_INPUT fault bits ... on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000285 expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
286 expectations.statusInputValue = 0x38;
287 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000288 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
289 .Times(1)
290 .WillOnce(Return("207000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000291 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(), false);
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 Wyman39ea02b2021-11-23 23:22:23 +0000304 EXPECT_EQ(psu2.hasPSKillFault(), false);
305 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
306 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000307 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600308
309 // STATUS_WORD INPUT/UV fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000310 {
311 // First need it to return good status, then the fault
312 PMBusExpectations expectations;
313 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000314 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
315 .Times(1)
316 .WillOnce(Return("208000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000317 psu2.analyze();
318 // Now set fault bits in STATUS_WORD
319 expectations.statusWordValue =
320 (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT);
321 // STATUS_INPUT fault bits ... on.
322 expectations.statusInputValue = 0x38;
323 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000324 // Input/UV fault, so voltage should read back low.
325 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
326 .Times(1)
327 .WillOnce(Return("19123"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000328 psu2.analyze();
329 EXPECT_EQ(psu2.isPresent(), true);
330 EXPECT_EQ(psu2.isFaulted(), true);
331 EXPECT_EQ(psu2.hasInputFault(), true);
332 EXPECT_EQ(psu2.hasMFRFault(), false);
333 EXPECT_EQ(psu2.hasVINUVFault(), true);
334 EXPECT_EQ(psu2.hasCommFault(), false);
335 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000336 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000337 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000338 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000339 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000340 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000341 EXPECT_EQ(psu2.hasPSKillFault(), false);
342 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
343 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
Brandon Wyman82affd92021-11-24 19:12:49 +0000344
345 // Turning VIN_UV fault off causes clearing of faults, causing read of
346 // in1_input as an attempt to get CLEAR_FAULTS called.
347 expectations.statusWordValue = 0;
348 setPMBusExpectations(mockPMBus, expectations);
349 // The call to read the voltage
350 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
351 .Times(1)
352 .WillOnce(Return("209000"));
353 // The call for CLEAR_FAULTS command
354 EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(3));
355 psu2.analyze();
356 // Should remain present, no longer be faulted, no input fault, no
357 // VIN_UV fault. Nothing else should change.
358 EXPECT_EQ(psu2.isPresent(), true);
359 EXPECT_EQ(psu2.isFaulted(), false);
360 EXPECT_EQ(psu2.hasInputFault(), false);
361 EXPECT_EQ(psu2.hasVINUVFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000362 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600363
364 // STATUS_WORD MFR fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000365 {
366 // First need it to return good status, then the fault
367 PMBusExpectations expectations;
368 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000369 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
370 .Times(1)
371 .WillOnce(Return("210000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000372 psu2.analyze();
373 // Now STATUS_WORD with MFR fault bit on.
374 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
375 // STATUS_MFR bits on.
376 expectations.statusMFRValue = 0xFF;
377 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000378 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
379 .Times(1)
380 .WillOnce(Return("211000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000381 psu2.analyze();
382 EXPECT_EQ(psu2.isPresent(), true);
383 EXPECT_EQ(psu2.isFaulted(), true);
384 EXPECT_EQ(psu2.hasInputFault(), false);
385 EXPECT_EQ(psu2.hasMFRFault(), true);
386 EXPECT_EQ(psu2.hasVINUVFault(), false);
387 EXPECT_EQ(psu2.hasCommFault(), false);
388 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000389 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000390 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000391 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000392 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000393 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000394 EXPECT_EQ(psu2.hasPSKillFault(), true);
395 EXPECT_EQ(psu2.hasPS12VcsFault(), true);
396 EXPECT_EQ(psu2.hasPSCS12VFault(), true);
Brandon Wymanb654c612021-11-05 23:24:51 +0000397 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600398
Brandon Wyman96893a42021-11-05 19:56:57 +0000399 // Temperature fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000400 {
401 // First STATUS_WORD with no bits set, then with temperature fault.
402 PMBusExpectations expectations;
403 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000404 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
405 .Times(1)
406 .WillOnce(Return("212000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000407 psu2.analyze();
408 // STATUS_WORD with temperature fault bit on.
409 expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
Brandon Wyman96893a42021-11-05 19:56:57 +0000410 // STATUS_TEMPERATURE with fault bit(s) on.
411 expectations.statusTempValue = 0x10;
Brandon Wymanb654c612021-11-05 23:24:51 +0000412 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000413 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
414 .Times(1)
415 .WillOnce(Return("213000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000416 psu2.analyze();
417 EXPECT_EQ(psu2.isPresent(), true);
Brandon Wyman96893a42021-11-05 19:56:57 +0000418 EXPECT_EQ(psu2.isFaulted(), true);
Brandon Wymanb654c612021-11-05 23:24:51 +0000419 EXPECT_EQ(psu2.hasInputFault(), false);
420 EXPECT_EQ(psu2.hasMFRFault(), false);
421 EXPECT_EQ(psu2.hasVINUVFault(), false);
422 EXPECT_EQ(psu2.hasCommFault(), false);
423 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000424 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000425 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000426 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000427 EXPECT_EQ(psu2.hasTempFault(), true);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000428 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000429 EXPECT_EQ(psu2.hasPSKillFault(), false);
430 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
431 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000432 }
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000433
434 // CML fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000435 {
436 // First STATUS_WORD wit no bits set, then with CML fault.
437 PMBusExpectations expectations;
438 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000439 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
440 .Times(1)
441 .WillOnce(Return("214000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000442 psu2.analyze();
443 // STATUS_WORD with CML fault bit on.
444 expectations.statusWordValue = (status_word::CML_FAULT);
445 // Turn on STATUS_CML fault bit(s)
446 expectations.statusCMLValue = 0xFF;
447 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000448 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
449 .Times(1)
450 .WillOnce(Return("215000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000451 psu2.analyze();
452 EXPECT_EQ(psu2.isPresent(), true);
453 EXPECT_EQ(psu2.isFaulted(), true);
454 EXPECT_EQ(psu2.hasInputFault(), false);
455 EXPECT_EQ(psu2.hasMFRFault(), false);
456 EXPECT_EQ(psu2.hasVINUVFault(), false);
457 EXPECT_EQ(psu2.hasCommFault(), true);
458 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000459 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000460 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000461 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000462 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000463 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000464 EXPECT_EQ(psu2.hasPSKillFault(), false);
465 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
466 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000467 }
Brandon Wyman6710ba22021-10-27 17:39:31 +0000468
469 // VOUT_OV_FAULT fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000470 {
471 // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault.
472 PMBusExpectations expectations;
473 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000474 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
475 .Times(1)
476 .WillOnce(Return("216000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000477 psu2.analyze();
478 // STATUS_WORD with VOUT/VOUT_OV fault.
479 expectations.statusWordValue =
480 ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT));
481 // Turn on STATUS_VOUT fault bit(s)
482 expectations.statusVOUTValue = 0xA0;
Brandon Wyman96893a42021-11-05 19:56:57 +0000483 // STATUS_TEMPERATURE don't care (default)
Brandon Wymanb654c612021-11-05 23:24:51 +0000484 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000485 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
486 .Times(1)
487 .WillOnce(Return("217000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000488 psu2.analyze();
489 EXPECT_EQ(psu2.isPresent(), true);
490 EXPECT_EQ(psu2.isFaulted(), true);
491 EXPECT_EQ(psu2.hasInputFault(), false);
492 EXPECT_EQ(psu2.hasMFRFault(), false);
493 EXPECT_EQ(psu2.hasVINUVFault(), false);
494 EXPECT_EQ(psu2.hasCommFault(), false);
495 EXPECT_EQ(psu2.hasVoutOVFault(), true);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000496 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000497 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000498 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000499 EXPECT_EQ(psu2.hasTempFault(), false);
500 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000501 EXPECT_EQ(psu2.hasPSKillFault(), false);
502 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
503 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000504 }
505
506 // IOUT_OC_FAULT fault
507 {
508 // First STATUS_WORD with no bits set, then with IOUT_OC fault.
509 PMBusExpectations expectations;
510 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000511 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
512 .Times(1)
513 .WillOnce(Return("218000"));
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000514 psu2.analyze();
515 // STATUS_WORD with IOUT_OC fault.
516 expectations.statusWordValue = status_word::IOUT_OC_FAULT;
517 // Turn on STATUS_IOUT fault bit(s)
518 expectations.statusIOUTValue = 0x88;
519 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000520 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
521 .Times(1)
522 .WillOnce(Return("219000"));
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000523 psu2.analyze();
524 EXPECT_EQ(psu2.isPresent(), true);
525 EXPECT_EQ(psu2.isFaulted(), true);
526 EXPECT_EQ(psu2.hasInputFault(), false);
527 EXPECT_EQ(psu2.hasMFRFault(), false);
528 EXPECT_EQ(psu2.hasVINUVFault(), false);
529 EXPECT_EQ(psu2.hasCommFault(), false);
530 EXPECT_EQ(psu2.hasVoutOVFault(), false);
531 EXPECT_EQ(psu2.hasIoutOCFault(), true);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000532 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000533 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000534 EXPECT_EQ(psu2.hasTempFault(), false);
535 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000536 EXPECT_EQ(psu2.hasPSKillFault(), false);
537 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
538 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000539 }
540
541 // VOUT_UV_FAULT
542 {
543 // First STATUS_WORD with no bits set, then with VOUT fault.
544 PMBusExpectations expectations;
545 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000546 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
547 .Times(1)
548 .WillOnce(Return("220000"));
Brandon Wyman2cf46942021-10-28 19:09:16 +0000549 psu2.analyze();
550 // Change STATUS_WORD to indicate VOUT fault.
551 expectations.statusWordValue = (status_word::VOUT_FAULT);
552 // Turn on STATUS_VOUT fault bit(s)
553 expectations.statusVOUTValue = 0x30;
554 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000555 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
556 .Times(1)
557 .WillOnce(Return("221000"));
Brandon Wyman2cf46942021-10-28 19:09:16 +0000558 psu2.analyze();
559 EXPECT_EQ(psu2.isPresent(), true);
560 EXPECT_EQ(psu2.isFaulted(), true);
561 EXPECT_EQ(psu2.hasInputFault(), false);
562 EXPECT_EQ(psu2.hasMFRFault(), false);
563 EXPECT_EQ(psu2.hasVINUVFault(), false);
564 EXPECT_EQ(psu2.hasCommFault(), false);
565 EXPECT_EQ(psu2.hasVoutOVFault(), false);
566 EXPECT_EQ(psu2.hasIoutOCFault(), false);
567 EXPECT_EQ(psu2.hasVoutUVFault(), true);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000568 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000569 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000570 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000571 EXPECT_EQ(psu2.hasPSKillFault(), false);
572 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
573 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000574 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600575
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000576 // Fan fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000577 {
578 // First STATUS_WORD with no bits set, then with fan fault.
579 PMBusExpectations expectations;
580 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000581 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
582 .Times(1)
583 .WillOnce(Return("222000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000584 psu2.analyze();
585 expectations.statusWordValue = (status_word::FAN_FAULT);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000586 // STATUS_FANS_1_2 with fan 1 warning & fault bits on.
587 expectations.statusFans12Value = 0xA0;
Brandon Wymanb654c612021-11-05 23:24:51 +0000588 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000589 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
590 .Times(1)
591 .WillOnce(Return("223000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000592 psu2.analyze();
593 EXPECT_EQ(psu2.isPresent(), true);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000594 EXPECT_EQ(psu2.isFaulted(), true);
Brandon Wymanb654c612021-11-05 23:24:51 +0000595 EXPECT_EQ(psu2.hasInputFault(), false);
596 EXPECT_EQ(psu2.hasMFRFault(), false);
597 EXPECT_EQ(psu2.hasVINUVFault(), false);
598 EXPECT_EQ(psu2.hasCommFault(), false);
599 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000600 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000601 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000602 EXPECT_EQ(psu2.hasFanFault(), true);
Brandon Wyman96893a42021-11-05 19:56:57 +0000603 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000604 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000605 EXPECT_EQ(psu2.hasPSKillFault(), false);
606 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
607 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000608 }
Brandon Wyman2916ea52021-11-06 03:31:18 +0000609
Brandon Wyman06ca4592021-12-06 22:52:23 +0000610 // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT.
Brandon Wyman2916ea52021-11-06 03:31:18 +0000611 {
Brandon Wyman2916ea52021-11-06 03:31:18 +0000612 // First STATUS_WORD with no bits set.
613 PMBusExpectations expectations;
614 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000615 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
616 .Times(1)
617 .WillOnce(Return("123000"));
Brandon Wyman2916ea52021-11-06 03:31:18 +0000618 psu2.analyze();
619 EXPECT_EQ(psu2.isFaulted(), false);
620 // POWER_GOOD# inactive, and OFF bit on.
621 expectations.statusWordValue =
622 ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF));
Brandon Wyman06ca4592021-12-06 22:52:23 +0000623 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
624 {
625 // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and
626 // STATUS_TEMPERATURE: Don't care if bits set or not (defaults).
627 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000628 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
629 .Times(1)
630 .WillOnce(Return("124000"));
Brandon Wyman06ca4592021-12-06 22:52:23 +0000631 psu2.analyze();
632 EXPECT_EQ(psu2.isPresent(), true);
633 if (x < DEGLITCH_LIMIT)
634 {
635 EXPECT_EQ(psu2.isFaulted(), false);
636 }
637 else
638 {
639 EXPECT_EQ(psu2.isFaulted(), true);
640 }
641 EXPECT_EQ(psu2.hasInputFault(), false);
642 EXPECT_EQ(psu2.hasMFRFault(), false);
643 EXPECT_EQ(psu2.hasVINUVFault(), false);
644 EXPECT_EQ(psu2.hasCommFault(), false);
645 EXPECT_EQ(psu2.hasVoutOVFault(), false);
646 EXPECT_EQ(psu2.hasVoutUVFault(), false);
647 EXPECT_EQ(psu2.hasIoutOCFault(), false);
648 EXPECT_EQ(psu2.hasFanFault(), false);
649 EXPECT_EQ(psu2.hasTempFault(), false);
650 if (x < DEGLITCH_LIMIT)
651 {
652 EXPECT_EQ(psu2.hasPgoodFault(), false);
653 }
654 else
655 {
656 EXPECT_EQ(psu2.hasPgoodFault(), true);
657 }
658 }
Brandon Wyman2916ea52021-11-06 03:31:18 +0000659 }
660
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600661 // TODO: ReadFailure
662}
663
Brandon Wyman59a35792020-06-04 12:37:40 -0500664TEST_F(PowerSupplyTests, OnOffConfig)
665{
666 auto bus = sdbusplus::bus::new_default();
667 uint8_t data = 0x15;
668
669 // Test where PSU is NOT present
670 try
671 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000672 // Assume GPIO presence, not inventory presence?
673 PowerSupply psu{bus, PSUInventoryPath, 4, 0x69, PSUGPIOLineName};
674
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000675 MockedGPIOInterface* mockPresenceGPIO =
676 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000677 ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0));
Brandon Wyman59a35792020-06-04 12:37:40 -0500678 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000679 // Constructor should set initial presence, default read returns 0.
Brandon Wyman59a35792020-06-04 12:37:40 -0500680 // If it is not present, I should not be trying to write to it.
681 EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0);
682 psu.onOffConfig(data);
683 }
684 catch (...)
Adriana Kobylak0c9a33d2021-09-13 18:05:09 +0000685 {}
Brandon Wyman59a35792020-06-04 12:37:40 -0500686
687 // Test where PSU is present
688 try
689 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000690 // Assume GPIO presence, not inventory presence?
691 PowerSupply psu{bus, PSUInventoryPath, 5, 0x6a, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000692 MockedGPIOInterface* mockPresenceGPIO =
693 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wyman391a0692021-12-08 23:28:18 +0000694 // There will potentially be multiple calls, we want it to continue
695 // returning 1 for the GPIO read to keep the power supply present.
696 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman59a35792020-06-04 12:37:40 -0500697 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +0000698 setMissingToPresentExpects(mockPMBus, mockedUtil);
699 // If I am calling analyze(), I should probably give it good data.
700 // STATUS_WORD 0x0000 is powered on, no faults.
701 PMBusExpectations expectations;
702 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000703 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
704 .Times(1)
705 .WillOnce(Return("205000"));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000706 psu.analyze();
Brandon Wyman391a0692021-12-08 23:28:18 +0000707 // I definitely should be writting ON_OFF_CONFIG if I call the function
708 EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, ElementsAre(0x15),
709 Type::HwmonDeviceDebug))
Brandon Wyman59a35792020-06-04 12:37:40 -0500710 .Times(1);
711 psu.onOffConfig(data);
712 }
713 catch (...)
Adriana Kobylak0c9a33d2021-09-13 18:05:09 +0000714 {}
Brandon Wyman59a35792020-06-04 12:37:40 -0500715}
716
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600717TEST_F(PowerSupplyTests, ClearFaults)
718{
719 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000720 PowerSupply psu{bus, PSUInventoryPath, 13, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000721 MockedGPIOInterface* mockPresenceGPIO =
722 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wyman06ca4592021-12-06 22:52:23 +0000723 // Always return 1 to indicate present.
724 // Each analyze() call will trigger a read of the presence GPIO.
725 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000726 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +0000727 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wyman8da35c52021-10-28 22:45:08 +0000728 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000729 PMBusExpectations expectations;
730 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000731 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
732 .Times(1)
733 .WillOnce(Return("207000"));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000734 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600735 EXPECT_EQ(psu.isPresent(), true);
736 EXPECT_EQ(psu.isFaulted(), false);
737 EXPECT_EQ(psu.hasInputFault(), false);
738 EXPECT_EQ(psu.hasMFRFault(), false);
739 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000740 EXPECT_EQ(psu.hasCommFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000741 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000742 EXPECT_EQ(psu.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000743 EXPECT_EQ(psu.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000744 EXPECT_EQ(psu.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000745 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000746 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000747 EXPECT_EQ(psu.hasPSKillFault(), false);
748 EXPECT_EQ(psu.hasPS12VcsFault(), false);
749 EXPECT_EQ(psu.hasPSCS12VFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000750
Brandon Wymanf07bc792021-10-12 19:00:35 +0000751 // STATUS_WORD with fault bits galore!
Brandon Wymanb654c612021-11-05 23:24:51 +0000752 expectations.statusWordValue = 0xFFFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000753 // STATUS_INPUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000754 expectations.statusInputValue = 0xFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000755 // STATUS_MFR_SPEFIC with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000756 expectations.statusMFRValue = 0xFF;
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000757 // STATUS_CML with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000758 expectations.statusCMLValue = 0xFF;
Brandon Wyman6710ba22021-10-27 17:39:31 +0000759 // STATUS_VOUT with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000760 expectations.statusVOUTValue = 0xFF;
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000761 // STATUS_IOUT with bits on.
762 expectations.statusIOUTValue = 0xFF;
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000763 // STATUS_FANS_1_2 with bits on.
764 expectations.statusFans12Value = 0xFF;
Brandon Wyman96893a42021-11-05 19:56:57 +0000765 // STATUS_TEMPERATURE with bits on.
766 expectations.statusTempValue = 0xFF;
Brandon Wymanb654c612021-11-05 23:24:51 +0000767 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000768 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
769 .Times(1)
770 .WillOnce(Return("0"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600771 psu.analyze();
772 EXPECT_EQ(psu.isPresent(), true);
773 EXPECT_EQ(psu.isFaulted(), true);
774 EXPECT_EQ(psu.hasInputFault(), true);
775 EXPECT_EQ(psu.hasMFRFault(), true);
776 EXPECT_EQ(psu.hasVINUVFault(), true);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000777 EXPECT_EQ(psu.hasCommFault(), true);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000778 EXPECT_EQ(psu.hasVoutOVFault(), true);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000779 EXPECT_EQ(psu.hasIoutOCFault(), true);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000780 // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
781 // Rely on HasVoutUVFault() to verify this sets and clears.
782 EXPECT_EQ(psu.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000783 EXPECT_EQ(psu.hasFanFault(), true);
Brandon Wyman96893a42021-11-05 19:56:57 +0000784 EXPECT_EQ(psu.hasTempFault(), true);
Brandon Wyman06ca4592021-12-06 22:52:23 +0000785 // pgoodFault is deglitched up to DEGLITCH_LIMIT
786 EXPECT_EQ(psu.hasPgoodFault(), false);
787 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000788 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
789 .Times(1)
790 .WillOnce(Return("0"));
Brandon Wyman06ca4592021-12-06 22:52:23 +0000791 psu.analyze();
792 EXPECT_EQ(psu.hasPgoodFault(), false);
793 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000794 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
795 .Times(1)
796 .WillOnce(Return("0"));
Brandon Wyman06ca4592021-12-06 22:52:23 +0000797 psu.analyze();
798 // DEGLITCH_LIMIT reached for pgoodFault
Brandon Wyman2916ea52021-11-06 03:31:18 +0000799 EXPECT_EQ(psu.hasPgoodFault(), true);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000800 EXPECT_EQ(psu.hasPSKillFault(), true);
801 EXPECT_EQ(psu.hasPS12VcsFault(), true);
802 EXPECT_EQ(psu.hasPSCS12VFault(), true);
Brandon Wyman82affd92021-11-24 19:12:49 +0000803 // This is the CLEAR_FAULTS read that does not check the return value.
804 EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(3));
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600805 psu.clearFaults();
806 EXPECT_EQ(psu.isPresent(), true);
807 EXPECT_EQ(psu.isFaulted(), false);
808 EXPECT_EQ(psu.hasInputFault(), false);
809 EXPECT_EQ(psu.hasMFRFault(), false);
810 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000811 EXPECT_EQ(psu.hasCommFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000812 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000813 EXPECT_EQ(psu.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000814 EXPECT_EQ(psu.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000815 EXPECT_EQ(psu.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000816 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000817 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000818 EXPECT_EQ(psu.hasPSKillFault(), false);
819 EXPECT_EQ(psu.hasPS12VcsFault(), false);
820 EXPECT_EQ(psu.hasPSCS12VFault(), false);
B. J. Wyman681b2a32021-04-20 22:31:22 +0000821
Brandon Wyman82affd92021-11-24 19:12:49 +0000822 // Faults clear on READ_VIN 0 -> !0
823 // STATUS_WORD with fault bits galore!
824 expectations.statusWordValue = 0xFFFF;
825 // STATUS_INPUT with fault bits on.
826 expectations.statusInputValue = 0xFF;
827 // STATUS_MFR_SPEFIC with bits on.
828 expectations.statusMFRValue = 0xFF;
829 // STATUS_CML with bits on.
830 expectations.statusCMLValue = 0xFF;
831 // STATUS_VOUT with bits on.
832 expectations.statusVOUTValue = 0xFF;
833 // STATUS_IOUT with bits on.
834 expectations.statusIOUTValue = 0xFF;
835 // STATUS_FANS_1_2 with bits on.
836 expectations.statusFans12Value = 0xFF;
837 // STATUS_TEMPERATURE with bits on.
838 expectations.statusTempValue = 0xFF;
839 setPMBusExpectations(mockPMBus, expectations);
840 EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(0));
841 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
842 .Times(1)
843 .WillOnce(Return("0"));
844 psu.analyze();
845 EXPECT_EQ(psu.isPresent(), true);
846 EXPECT_EQ(psu.isFaulted(), true);
847 EXPECT_EQ(psu.hasInputFault(), true);
848 EXPECT_EQ(psu.hasMFRFault(), true);
849 EXPECT_EQ(psu.hasVINUVFault(), true);
850 // True due to CML fault bits on
851 EXPECT_EQ(psu.hasCommFault(), true);
852 EXPECT_EQ(psu.hasVoutOVFault(), true);
853 EXPECT_EQ(psu.hasIoutOCFault(), true);
854 // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
855 // Rely on HasVoutUVFault() to verify this sets and clears.
856 EXPECT_EQ(psu.hasVoutUVFault(), false);
857 EXPECT_EQ(psu.hasFanFault(), true);
858 EXPECT_EQ(psu.hasTempFault(), true);
859 // PGOOD fault is deglitched before hasPgoodFault() returns true.
860 EXPECT_EQ(psu.hasPgoodFault(), false);
861 EXPECT_EQ(psu.hasPSKillFault(), true);
862 EXPECT_EQ(psu.hasPS12VcsFault(), true);
863 EXPECT_EQ(psu.hasPSCS12VFault(), true);
864 // STATUS_WORD with INPUT/VIN_UV fault bits off.
865 expectations.statusWordValue = 0xDFF7;
866 // STATUS_INPUT with VIN_UV_WARNING, VIN_UV_FAULT, and Unit Off For
867 // Insufficient Input Voltage bits off.
868 expectations.statusInputValue = 0xC7;
869 setPMBusExpectations(mockPMBus, expectations);
870 // READ_VIN back in range.
871 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
872 .Times(1)
873 .WillOnce(Return("206000"));
874 psu.analyze();
875 EXPECT_EQ(psu.isPresent(), true);
876 EXPECT_EQ(psu.isFaulted(), false);
877 EXPECT_EQ(psu.hasInputFault(), false);
878 EXPECT_EQ(psu.hasMFRFault(), false);
879 EXPECT_EQ(psu.hasVINUVFault(), false);
880 EXPECT_EQ(psu.hasCommFault(), false);
881 EXPECT_EQ(psu.hasVoutOVFault(), false);
882 EXPECT_EQ(psu.hasIoutOCFault(), false);
883 EXPECT_EQ(psu.hasVoutUVFault(), false);
884 EXPECT_EQ(psu.hasFanFault(), false);
885 EXPECT_EQ(psu.hasTempFault(), false);
886 EXPECT_EQ(psu.hasPgoodFault(), false);
887 EXPECT_EQ(psu.hasPSKillFault(), false);
888 EXPECT_EQ(psu.hasPS12VcsFault(), false);
889 EXPECT_EQ(psu.hasPSCS12VFault(), false);
890
B. J. Wyman681b2a32021-04-20 22:31:22 +0000891 // TODO: Faults clear on missing/present?
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600892}
893
894TEST_F(PowerSupplyTests, UpdateInventory)
895{
896 auto bus = sdbusplus::bus::new_default();
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500897
898 try
899 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000900 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500901 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
902 // If it is not present, I should not be trying to read a string
903 EXPECT_CALL(mockPMBus, readString(_, _)).Times(0);
904 psu.updateInventory();
905 }
906 catch (...)
907 {
908 ADD_FAILURE() << "Should not have caught exception.";
909 }
910
911 try
912 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000913 PowerSupply psu{bus, PSUInventoryPath, 13, 0x69, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000914 MockedGPIOInterface* mockPresenceGPIO =
915 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000916 // GPIO read return 1 to indicate present.
917 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500918 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +0000919 setMissingToPresentExpects(mockPMBus, mockedUtil);
920 // STATUS_WORD 0x0000 is powered on, no faults.
921 PMBusExpectations expectations;
922 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000923 // Call to analyze will read voltage, trigger clear faults for 0 to
924 // within range.
925 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
926 .Times(1)
927 .WillOnce(Return("123456"));
Brandon Wyman391a0692021-12-08 23:28:18 +0000928 psu.analyze();
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500929 EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return(""));
930 psu.updateInventory();
931
Brandon Wyman3c530fb2021-04-13 13:13:22 -0500932#if IBM_VPD
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500933 EXPECT_CALL(mockPMBus, readString(_, _))
934 .WillOnce(Return("CCIN"))
935 .WillOnce(Return("PN3456"))
936 .WillOnce(Return("FN3456"))
937 .WillOnce(Return("HEADER"))
938 .WillOnce(Return("SN3456"))
939 .WillOnce(Return("FW3456"));
Brandon Wyman3c530fb2021-04-13 13:13:22 -0500940#endif
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500941 psu.updateInventory();
942 // TODO: D-Bus mocking to verify values stored on D-Bus (???)
943 }
944 catch (...)
945 {
946 ADD_FAILURE() << "Should not have caught exception.";
947 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600948}
949
950TEST_F(PowerSupplyTests, IsPresent)
951{
952 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000953
954 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000955 MockedGPIOInterface* mockPresenceGPIO =
956 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600957 EXPECT_EQ(psu.isPresent(), false);
958
B. J. Wyman681b2a32021-04-20 22:31:22 +0000959 // Change GPIO read to return 1 to indicate present.
960 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
Brandon Wyman391a0692021-12-08 23:28:18 +0000961 // Call to analyze() will update to present, that will trigger updating
962 // to the correct/latest HWMON directory, in case it changes.
963 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
964 setMissingToPresentExpects(mockPMBus, mockedUtil);
965 // Call to analyze things will trigger read of STATUS_WORD and READ_VIN.
966 // Default expectations will be on, no faults.
967 PMBusExpectations expectations;
968 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000969 // Give it an input voltage in the 100-volt range.
970 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
971 .Times(1)
972 .WillOnce(Return("123456"));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000973 psu.analyze();
974 EXPECT_EQ(psu.isPresent(), true);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600975}
976
977TEST_F(PowerSupplyTests, IsFaulted)
978{
979 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +0000980
981 PowerSupply psu{bus, PSUInventoryPath, 11, 0x6f, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000982 MockedGPIOInterface* mockPresenceGPIO =
983 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000984 // Always return 1 to indicate present.
985 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman391a0692021-12-08 23:28:18 +0000986 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
987 setMissingToPresentExpects(mockPMBus, mockedUtil);
988 // Call to analyze things will trigger read of STATUS_WORD and READ_VIN.
989 // Default expectations will be on, no faults.
990 PMBusExpectations expectations;
991 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000992 // Give it an input voltage in the 100-volt range.
993 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
994 .Times(1)
995 .WillOnce(Return("124680"));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000996 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600997 EXPECT_EQ(psu.isFaulted(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +0000998 // STATUS_WORD with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000999 expectations.statusWordValue = 0xFFFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +00001000 // STATUS_INPUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001001 expectations.statusInputValue = 0xFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +00001002 // STATUS_MFR_SPECIFIC with faults bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001003 expectations.statusMFRValue = 0xFF;
Brandon Wyman85c7bf42021-10-19 22:28:48 +00001004 // STATUS_CML with faults bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001005 expectations.statusCMLValue = 0xFF;
Brandon Wyman6710ba22021-10-27 17:39:31 +00001006 // STATUS_VOUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001007 expectations.statusVOUTValue = 0xFF;
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001008 // STATUS_IOUT with fault bits on.
1009 expectations.statusIOUTValue = 0xFF;
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001010 // STATUS_FANS_1_2 with bits on.
1011 expectations.statusFans12Value = 0xFF;
Brandon Wyman96893a42021-11-05 19:56:57 +00001012 // STATUS_TEMPERATURE with fault bits on.
1013 expectations.statusTempValue = 0xFF;
Brandon Wymanb654c612021-11-05 23:24:51 +00001014 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001015 // Also get another read of READ_VIN.
1016 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1017 .Times(1)
1018 .WillOnce(Return("125790"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001019 psu.analyze();
1020 EXPECT_EQ(psu.isFaulted(), true);
1021}
1022
1023TEST_F(PowerSupplyTests, HasInputFault)
1024{
1025 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +00001026
1027 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +00001028 MockedGPIOInterface* mockPresenceGPIO =
1029 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +00001030 // Always return 1 to indicate present.
1031 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001032 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001033 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wyman8da35c52021-10-28 22:45:08 +00001034 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +00001035 PMBusExpectations expectations;
1036 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001037 // Analyze call will also need good READ_VIN value to check.
1038 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1039 .Times(1)
1040 .WillOnce(Return("201100"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001041 psu.analyze();
1042 EXPECT_EQ(psu.hasInputFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001043 // STATUS_WORD with input fault/warn on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001044 expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001045 // STATUS_INPUT with an input fault bit on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001046 expectations.statusInputValue = 0x80;
1047 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001048 // Analyze call will also need good READ_VIN value to check.
1049 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1050 .Times(1)
1051 .WillOnce(Return("201200"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001052 psu.analyze();
1053 EXPECT_EQ(psu.hasInputFault(), true);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001054 // STATUS_WORD with no bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001055 expectations.statusWordValue = 0;
1056 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001057 // Analyze call will also need good READ_VIN value to check.
1058 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1059 .Times(1)
1060 .WillOnce(Return("201300"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001061 psu.analyze();
1062 EXPECT_EQ(psu.hasInputFault(), false);
1063}
1064
1065TEST_F(PowerSupplyTests, HasMFRFault)
1066{
1067 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +00001068
1069 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +00001070 MockedGPIOInterface* mockPresenceGPIO =
1071 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +00001072 // Always return 1 to indicate present.
1073 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001074 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001075 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001076 // First return STATUS_WORD with no bits on.
Brandon Wyman8da35c52021-10-28 22:45:08 +00001077 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +00001078 PMBusExpectations expectations;
1079 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001080 // Analyze call will also need good READ_VIN value to check.
1081 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1082 .Times(1)
1083 .WillOnce(Return("202100"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001084 psu.analyze();
1085 EXPECT_EQ(psu.hasMFRFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001086 // Next return STATUS_WORD with MFR fault bit on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001087 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001088 // STATUS_MFR_SPEFIC with bit(s) on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001089 expectations.statusMFRValue = 0xFF;
1090 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001091 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1092 .Times(1)
1093 .WillOnce(Return("202200"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001094 psu.analyze();
1095 EXPECT_EQ(psu.hasMFRFault(), true);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001096 // Back to no bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +00001097 expectations.statusWordValue = 0;
1098 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001099 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1100 .Times(1)
1101 .WillOnce(Return("202300"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001102 psu.analyze();
1103 EXPECT_EQ(psu.hasMFRFault(), false);
1104}
1105
1106TEST_F(PowerSupplyTests, HasVINUVFault)
1107{
1108 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +00001109
1110 PowerSupply psu{bus, PSUInventoryPath, 3, 0x68, PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +00001111 MockedGPIOInterface* mockPresenceGPIO =
1112 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +00001113 // Always return 1 to indicate present.
1114 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001115 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001116 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wyman82affd92021-11-24 19:12:49 +00001117
1118 // Presence change from missing to present will trigger in1_input read in
1119 // an attempt to get CLEAR_FAULTS called. Return value ignored.
1120 // Zero to non-zero voltage, for missing/present change, triggers clear
1121 // faults call again. Return value ignored.
1122 // Fault (low voltage) to not faulted (voltage in range) triggers clear
1123 // faults call a third time.
1124
Brandon Wyman8da35c52021-10-28 22:45:08 +00001125 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +00001126 PMBusExpectations expectations;
1127 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001128 // Analyze call will also need good READ_VIN value to check.
1129 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1130 .Times(1)
1131 .WillOnce(Return("201100"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001132 psu.analyze();
1133 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001134 // Turn fault on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001135 expectations.statusWordValue = (status_word::VIN_UV_FAULT);
Brandon Wyman85c7bf42021-10-19 22:28:48 +00001136 // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by
1137 // Figure 16, and assume bits on in STATUS_INPUT.
Brandon Wymanb654c612021-11-05 23:24:51 +00001138 expectations.statusInputValue = 0x18;
1139 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001140 // If there is a VIN_UV fault, fake reading voltage of less than 20V
1141 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1142 .Times(1)
1143 .WillOnce(Return("19876"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001144 psu.analyze();
1145 EXPECT_EQ(psu.hasVINUVFault(), true);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001146 // Back to no fault bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +00001147 expectations.statusWordValue = 0;
1148 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001149 // Updates now result in clearing faults if read voltage goes from below the
1150 // minimum, to within a valid range.
1151 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1152 .Times(1)
1153 .WillOnce(Return("201300"));
1154 // Went from below minimum to within range, expect CLEAR_FAULTS.
1155 EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(3));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001156 psu.analyze();
1157 EXPECT_EQ(psu.hasVINUVFault(), false);
1158}
Brandon Wyman6710ba22021-10-27 17:39:31 +00001159
1160TEST_F(PowerSupplyTests, HasVoutOVFault)
1161{
1162 auto bus = sdbusplus::bus::new_default();
1163
1164 PowerSupply psu{bus, PSUInventoryPath, 3, 0x69, PSUGPIOLineName};
1165 MockedGPIOInterface* mockPresenceGPIO =
1166 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1167 // Always return 1 to indicate present.
1168 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman6710ba22021-10-27 17:39:31 +00001169 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001170 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wyman6710ba22021-10-27 17:39:31 +00001171 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +00001172 PMBusExpectations expectations;
1173 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001174 // Call to analyze will trigger read of "in1_input" to check voltage.
1175 // Initial value would be 0, so this read updates it to non-zero.
1176 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1177 .Times(1)
1178 .WillOnce(Return("202100"));
Brandon Wyman6710ba22021-10-27 17:39:31 +00001179 psu.analyze();
1180 EXPECT_EQ(psu.hasVoutOVFault(), false);
1181 // Turn fault on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001182 expectations.statusWordValue = (status_word::VOUT_OV_FAULT);
Brandon Wyman6710ba22021-10-27 17:39:31 +00001183 // STATUS_VOUT fault bit(s)
Brandon Wymanb654c612021-11-05 23:24:51 +00001184 expectations.statusVOUTValue = 0x80;
Brandon Wyman96893a42021-11-05 19:56:57 +00001185 // STATUS_TEMPERATURE default.
Brandon Wymanb654c612021-11-05 23:24:51 +00001186 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001187 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1188 .Times(1)
1189 .WillOnce(Return("202200"));
Brandon Wyman6710ba22021-10-27 17:39:31 +00001190 psu.analyze();
1191 EXPECT_EQ(psu.hasVoutOVFault(), true);
1192 // Back to no fault bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +00001193 expectations.statusWordValue = 0;
1194 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001195 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1196 .Times(1)
1197 .WillOnce(Return("202300"));
Brandon Wyman6710ba22021-10-27 17:39:31 +00001198 psu.analyze();
1199 EXPECT_EQ(psu.hasVoutOVFault(), false);
1200}
Brandon Wyman96893a42021-11-05 19:56:57 +00001201
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001202TEST_F(PowerSupplyTests, HasIoutOCFault)
1203{
1204 auto bus = sdbusplus::bus::new_default();
1205
1206 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName};
1207 MockedGPIOInterface* mockPresenceGPIO =
1208 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1209 // Always return 1 to indicate present.
1210 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001211 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001212 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001213 // STATUS_WORD 0x0000 is powered on, no faults.
1214 PMBusExpectations expectations;
1215 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001216 // Call to analyze will trigger read of "in1_input" to check voltage.
1217 // Initial value would be 0, so this read updates it to non-zero.
1218 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1219 .Times(1)
1220 .WillOnce(Return("203100"));
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001221 psu.analyze();
1222 EXPECT_EQ(psu.hasIoutOCFault(), false);
1223 // Turn fault on.
1224 expectations.statusWordValue = status_word::IOUT_OC_FAULT;
1225 // STATUS_IOUT fault bit(s)
1226 expectations.statusIOUTValue = 0x88;
1227 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001228 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1229 .Times(1)
1230 .WillOnce(Return("203200"));
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001231 psu.analyze();
1232 EXPECT_EQ(psu.hasIoutOCFault(), true);
1233 // Back to no fault bits on in STATUS_WORD
1234 expectations.statusWordValue = 0;
1235 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001236 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1237 .Times(1)
1238 .WillOnce(Return("203300"));
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001239 psu.analyze();
1240 EXPECT_EQ(psu.hasIoutOCFault(), false);
1241}
1242
Brandon Wyman2cf46942021-10-28 19:09:16 +00001243TEST_F(PowerSupplyTests, HasVoutUVFault)
1244{
1245 auto bus = sdbusplus::bus::new_default();
1246
1247 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName};
1248 MockedGPIOInterface* mockPresenceGPIO =
1249 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1250 // Always return 1 to indicate present.
1251 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman2cf46942021-10-28 19:09:16 +00001252 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001253 setMissingToPresentExpects(mockPMBus, mockedUtil);
1254 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wyman2cf46942021-10-28 19:09:16 +00001255 PMBusExpectations expectations;
1256 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001257 // Call to analyze will trigger read of "in1_input" to check voltage.
1258 // Initial value would be 0, so this read updates it to non-zero.
1259 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1260 .Times(1)
1261 .WillOnce(Return("204100"));
Brandon Wyman2cf46942021-10-28 19:09:16 +00001262 psu.analyze();
1263 EXPECT_EQ(psu.hasVoutUVFault(), false);
1264 // Turn fault on.
1265 expectations.statusWordValue = (status_word::VOUT_FAULT);
1266 // STATUS_VOUT fault bit(s)
1267 expectations.statusVOUTValue = 0x30;
1268 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001269 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1270 .Times(1)
1271 .WillOnce(Return("204200"));
Brandon Wyman2cf46942021-10-28 19:09:16 +00001272 psu.analyze();
1273 EXPECT_EQ(psu.hasVoutUVFault(), true);
1274 // Back to no fault bits on in STATUS_WORD
1275 expectations.statusWordValue = 0;
1276 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001277 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1278 .Times(1)
1279 .WillOnce(Return("204300"));
Brandon Wyman2cf46942021-10-28 19:09:16 +00001280 psu.analyze();
1281 EXPECT_EQ(psu.hasVoutUVFault(), false);
1282}
1283
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001284TEST_F(PowerSupplyTests, HasFanFault)
1285{
1286 auto bus = sdbusplus::bus::new_default();
1287
1288 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6d, PSUGPIOLineName};
1289 MockedGPIOInterface* mockPresenceGPIO =
1290 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1291 // Always return 1 to indicate present.
1292 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001293 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001294 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001295 // STATUS_WORD 0x0000 is powered on, no faults.
1296 PMBusExpectations expectations;
1297 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001298 // Call to analyze will trigger read of "in1_input" to check voltage.
1299 // Initial value would be 0, so this read updates it to non-zero.
1300 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1301 .Times(1)
1302 .WillOnce(Return("205100"));
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001303 psu.analyze();
1304 EXPECT_EQ(psu.hasFanFault(), false);
1305 // Turn fault on.
1306 expectations.statusWordValue = (status_word::FAN_FAULT);
1307 // STATUS_FANS_1_2 fault bit on (Fan 1 Fault)
1308 expectations.statusFans12Value = 0x80;
1309 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001310 // Call to analyze will trigger read of "in1_input" to check voltage.
1311 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1312 .Times(1)
1313 .WillOnce(Return("205200"));
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001314 psu.analyze();
1315 EXPECT_EQ(psu.hasFanFault(), true);
1316 // Back to no fault bits on in STATUS_WORD
1317 expectations.statusWordValue = 0;
1318 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001319 // Call to analyze will trigger read of "in1_input" to check voltage.
1320 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1321 .Times(1)
1322 .WillOnce(Return("205300"));
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001323 psu.analyze();
1324 EXPECT_EQ(psu.hasFanFault(), false);
1325}
1326
Brandon Wyman96893a42021-11-05 19:56:57 +00001327TEST_F(PowerSupplyTests, HasTempFault)
1328{
1329 auto bus = sdbusplus::bus::new_default();
1330
1331 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6a, PSUGPIOLineName};
1332 MockedGPIOInterface* mockPresenceGPIO =
1333 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1334 // Always return 1 to indicate present.
1335 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman96893a42021-11-05 19:56:57 +00001336 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001337 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wyman96893a42021-11-05 19:56:57 +00001338 // STATUS_WORD 0x0000 is powered on, no faults.
1339 PMBusExpectations expectations;
1340 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001341 // Call to analyze will trigger read of "in1_input" to check voltage.
1342 // Initial value would be 0, so this read updates it to non-zero.
1343 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1344 .Times(1)
1345 .WillOnce(Return("206100"));
Brandon Wyman96893a42021-11-05 19:56:57 +00001346 psu.analyze();
1347 EXPECT_EQ(psu.hasTempFault(), false);
1348 // Turn fault on.
1349 expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
1350 // STATUS_TEMPERATURE fault bit on (OT Fault)
1351 expectations.statusTempValue = 0x80;
1352 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001353 // Call to analyze will trigger read of "in1_input" to check voltage.
1354 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1355 .Times(1)
1356 .WillOnce(Return("206200"));
Brandon Wyman96893a42021-11-05 19:56:57 +00001357 psu.analyze();
1358 EXPECT_EQ(psu.hasTempFault(), true);
1359 // Back to no fault bits on in STATUS_WORD
1360 expectations.statusWordValue = 0;
1361 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001362 // Call to analyze will trigger read of "in1_input" to check voltage.
1363 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1364 .Times(1)
1365 .WillOnce(Return("206300"));
Brandon Wyman96893a42021-11-05 19:56:57 +00001366 psu.analyze();
1367 EXPECT_EQ(psu.hasTempFault(), false);
1368}
Brandon Wyman2916ea52021-11-06 03:31:18 +00001369
1370TEST_F(PowerSupplyTests, HasPgoodFault)
1371{
1372 auto bus = sdbusplus::bus::new_default();
1373
1374 PowerSupply psu{bus, PSUInventoryPath, 3, 0x6b, PSUGPIOLineName};
1375 MockedGPIOInterface* mockPresenceGPIO =
1376 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1377 // Always return 1 to indicate present.
1378 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001379 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001380 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wyman2916ea52021-11-06 03:31:18 +00001381 // STATUS_WORD 0x0000 is powered on, no faults.
1382 PMBusExpectations expectations;
1383 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001384 // Call to analyze will trigger read of "in1_input" to check voltage.
1385 // Initial value would be 0, so this read updates it to non-zero.
1386 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1387 .Times(1)
1388 .WillOnce(Return("207100"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001389 psu.analyze();
1390 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman391a0692021-12-08 23:28:18 +00001391 // Setup another expectation of no faults.
1392 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001393 // Call to analyze will trigger read of "in1_input" to check voltage.
1394 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1395 .Times(1)
1396 .WillOnce(Return("207200"));
1397 psu.analyze();
1398 EXPECT_EQ(psu.hasPgoodFault(), false);
1399 // Setup another expectation of no faults.
1400 setPMBusExpectations(mockPMBus, expectations);
1401 // Call to analyze will trigger read of "in1_input" to check voltage.
1402 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1403 .Times(1)
1404 .WillOnce(Return("207300"));
Brandon Wyman391a0692021-12-08 23:28:18 +00001405 psu.analyze();
1406 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +00001407 // Turn PGOOD# off (fault on).
1408 expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED);
1409 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001410 // Call to analyze will trigger read of "in1_input" to check voltage.
1411 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1412 .Times(1)
1413 .WillOnce(Return("207400"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001414 psu.analyze();
Brandon Wyman06ca4592021-12-06 22:52:23 +00001415 // Expect false until reaches DEGLITCH_LIMIT
1416 EXPECT_EQ(psu.hasPgoodFault(), false);
1417 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001418 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1419 .Times(1)
1420 .WillOnce(Return("207500"));
Brandon Wyman06ca4592021-12-06 22:52:23 +00001421 psu.analyze();
1422 // Expect false until reaches DEGLITCH_LIMIT
1423 EXPECT_EQ(psu.hasPgoodFault(), false);
1424 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001425 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1426 .Times(1)
1427 .WillOnce(Return("207600"));
Brandon Wyman06ca4592021-12-06 22:52:23 +00001428 psu.analyze();
1429 // DEGLITCH_LIMIT reached, expect true.
Brandon Wyman2916ea52021-11-06 03:31:18 +00001430 EXPECT_EQ(psu.hasPgoodFault(), true);
1431 // Back to no fault bits on in STATUS_WORD
1432 expectations.statusWordValue = 0;
1433 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001434 // Call to analyze will trigger read of "in1_input" to check voltage.
1435 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1436 .Times(1)
1437 .WillOnce(Return("207700"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001438 psu.analyze();
1439 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman82affd92021-11-24 19:12:49 +00001440
Brandon Wyman2916ea52021-11-06 03:31:18 +00001441 // Turn OFF bit on
1442 expectations.statusWordValue = (status_word::UNIT_IS_OFF);
1443 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001444 // Call to analyze will trigger read of "in1_input" to check voltage.
1445 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1446 .Times(1)
1447 .WillOnce(Return("208100"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001448 psu.analyze();
Brandon Wyman06ca4592021-12-06 22:52:23 +00001449 EXPECT_EQ(psu.hasPgoodFault(), false);
1450 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001451 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1452 .Times(1)
1453 .WillOnce(Return("208200"));
Brandon Wyman06ca4592021-12-06 22:52:23 +00001454 psu.analyze();
1455 EXPECT_EQ(psu.hasPgoodFault(), false);
1456 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001457 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1458 .Times(1)
1459 .WillOnce(Return("208300"));
Brandon Wyman06ca4592021-12-06 22:52:23 +00001460 psu.analyze();
Brandon Wyman2916ea52021-11-06 03:31:18 +00001461 EXPECT_EQ(psu.hasPgoodFault(), true);
1462 // Back to no fault bits on in STATUS_WORD
1463 expectations.statusWordValue = 0;
1464 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001465 // Call to analyze will trigger read of "in1_input" to check voltage.
1466 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1467 .Times(1)
1468 .WillOnce(Return("208400"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001469 psu.analyze();
1470 EXPECT_EQ(psu.hasPgoodFault(), false);
1471}
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001472
1473TEST_F(PowerSupplyTests, HasPSKillFault)
1474{
1475 auto bus = sdbusplus::bus::new_default();
1476 PowerSupply psu{bus, PSUInventoryPath, 4, 0x6d, PSUGPIOLineName};
1477 MockedGPIOInterface* mockPresenceGPIO =
1478 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1479 // Always return 1 to indicate present.
1480 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001481 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman82affd92021-11-24 19:12:49 +00001482 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001483 // STATUS_WORD 0x0000 is powered on, no faults.
1484 PMBusExpectations expectations;
1485 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001486 // Call to analyze will trigger read of "in1_input" to check voltage.
1487 // Initial value would be 0, so this read updates it to non-zero.
1488 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1489 .Times(1)
1490 .WillOnce(Return("208100"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001491 psu.analyze();
1492 EXPECT_EQ(psu.hasPSKillFault(), false);
1493 // Next return STATUS_WORD with MFR fault bit on.
1494 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1495 // STATUS_MFR_SPEFIC with bit(s) on.
1496 expectations.statusMFRValue = 0xFF;
1497 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001498 // Call to analyze will trigger read of "in1_input" to check voltage.
1499 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1500 .Times(1)
1501 .WillOnce(Return("208200"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001502 psu.analyze();
1503 EXPECT_EQ(psu.hasPSKillFault(), true);
1504 // Back to no bits on in STATUS_WORD
1505 expectations.statusWordValue = 0;
1506 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001507 // Call to analyze will trigger read of "in1_input" to check voltage.
1508 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1509 .Times(1)
1510 .WillOnce(Return("208300"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001511 psu.analyze();
1512 EXPECT_EQ(psu.hasPSKillFault(), false);
1513 // Next return STATUS_WORD with MFR fault bit on.
1514 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1515 // STATUS_MFR_SPEFIC with bit 4 on.
1516 expectations.statusMFRValue = 0x10;
1517 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001518 // Call to analyze will trigger read of "in1_input" to check voltage.
1519 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1520 .Times(1)
1521 .WillOnce(Return("208400"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001522 psu.analyze();
1523 EXPECT_EQ(psu.hasPSKillFault(), true);
1524 // Back to no bits on in STATUS_WORD
1525 expectations.statusWordValue = 0;
1526 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001527 // Call to analyze will trigger read of "in1_input" to check voltage.
1528 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1529 .Times(1)
1530 .WillOnce(Return("208500"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001531 psu.analyze();
1532 EXPECT_EQ(psu.hasPSKillFault(), false);
1533}
1534
1535TEST_F(PowerSupplyTests, HasPS12VcsFault)
1536{
1537 auto bus = sdbusplus::bus::new_default();
1538 PowerSupply psu{bus, PSUInventoryPath, 5, 0x6e, PSUGPIOLineName};
1539 MockedGPIOInterface* mockPresenceGPIO =
1540 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1541 // Always return 1 to indicate present.
1542 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001543 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman82affd92021-11-24 19:12:49 +00001544 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001545 // STATUS_WORD 0x0000 is powered on, no faults.
1546 PMBusExpectations expectations;
1547 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001548 // Call to analyze will trigger read of "in1_input" to check voltage.
1549 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1550 .Times(1)
1551 .WillOnce(Return("209100"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001552 psu.analyze();
1553 EXPECT_EQ(psu.hasPS12VcsFault(), false);
1554 // Next return STATUS_WORD with MFR fault bit on.
1555 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1556 // STATUS_MFR_SPEFIC with bit(s) on.
1557 expectations.statusMFRValue = 0xFF;
1558 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001559 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1560 .Times(1)
1561 .WillOnce(Return("209200"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001562 psu.analyze();
1563 EXPECT_EQ(psu.hasPS12VcsFault(), true);
1564 // Back to no bits on in STATUS_WORD
1565 expectations.statusWordValue = 0;
1566 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001567 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1568 .Times(1)
1569 .WillOnce(Return("209300"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001570 psu.analyze();
1571 EXPECT_EQ(psu.hasPS12VcsFault(), false);
1572 // Next return STATUS_WORD with MFR fault bit on.
1573 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1574 // STATUS_MFR_SPEFIC with bit 6 on.
1575 expectations.statusMFRValue = 0x40;
1576 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001577 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1578 .Times(1)
1579 .WillOnce(Return("209400"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001580 psu.analyze();
1581 EXPECT_EQ(psu.hasPS12VcsFault(), true);
1582 // Back to no bits on in STATUS_WORD
1583 expectations.statusWordValue = 0;
1584 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001585 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1586 .Times(1)
1587 .WillOnce(Return("209500"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001588 psu.analyze();
1589 EXPECT_EQ(psu.hasPS12VcsFault(), false);
1590}
1591
1592TEST_F(PowerSupplyTests, HasPSCS12VFault)
1593{
1594 auto bus = sdbusplus::bus::new_default();
1595 PowerSupply psu{bus, PSUInventoryPath, 6, 0x6f, PSUGPIOLineName};
1596 MockedGPIOInterface* mockPresenceGPIO =
1597 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1598 // Always return 1 to indicate present.
1599 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001600 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman82affd92021-11-24 19:12:49 +00001601 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001602 // STATUS_WORD 0x0000 is powered on, no faults.
1603 PMBusExpectations expectations;
1604 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001605 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1606 .Times(1)
1607 .WillOnce(Return("209100"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001608 psu.analyze();
1609 EXPECT_EQ(psu.hasPSCS12VFault(), false);
1610 // Next return STATUS_WORD with MFR fault bit on.
1611 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1612 // STATUS_MFR_SPEFIC with bit(s) on.
1613 expectations.statusMFRValue = 0xFF;
1614 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001615 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1616 .Times(1)
1617 .WillOnce(Return("209200"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001618 psu.analyze();
1619 EXPECT_EQ(psu.hasPSCS12VFault(), true);
1620 // Back to no bits on in STATUS_WORD
1621 expectations.statusWordValue = 0;
1622 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001623 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1624 .Times(1)
1625 .WillOnce(Return("209300"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001626 psu.analyze();
1627 EXPECT_EQ(psu.hasPSCS12VFault(), false);
1628 // Next return STATUS_WORD with MFR fault bit on.
1629 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1630 // STATUS_MFR_SPEFIC with bit 7 on.
1631 expectations.statusMFRValue = 0x80;
1632 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001633 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1634 .Times(1)
1635 .WillOnce(Return("209400"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001636 psu.analyze();
1637 EXPECT_EQ(psu.hasPSCS12VFault(), true);
1638 // Back to no bits on in STATUS_WORD
1639 expectations.statusWordValue = 0;
1640 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001641 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1642 .Times(1)
1643 .WillOnce(Return("209500"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001644 psu.analyze();
1645 EXPECT_EQ(psu.hasPSCS12VFault(), false);
1646}