blob: 1e47b9c227f876943c2830a52cd4651b3ed06102 [file] [log] [blame]
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001#include "../power_supply.hpp"
Brandon Wymanc3324422022-03-24 20:30:57 +00002#include "../record_manager.hpp"
Brandon Wyman3f1242f2020-01-28 13:11:25 -06003#include "mock.hpp"
4
5#include <xyz/openbmc_project/Common/Device/error.hpp>
6#include <xyz/openbmc_project/Common/error.hpp>
7
8#include <gmock/gmock.h>
9#include <gtest/gtest.h>
10
11using namespace phosphor::power::psu;
12using namespace phosphor::pmbus;
13
14using ::testing::_;
Brandon Wyman59a35792020-06-04 12:37:40 -050015using ::testing::Args;
Brandon Wyman3f1242f2020-01-28 13:11:25 -060016using ::testing::Assign;
17using ::testing::DoAll;
Brandon Wyman59a35792020-06-04 12:37:40 -050018using ::testing::ElementsAre;
19using ::testing::NotNull;
Brandon Wyman3f1242f2020-01-28 13:11:25 -060020using ::testing::Return;
21using ::testing::StrEq;
22
23static auto PSUInventoryPath = "/xyz/bmc/inv/sys/chassis/board/powersupply0";
B. J. Wyman681b2a32021-04-20 22:31:22 +000024static auto PSUGPIOLineName = "presence-ps0";
Brandon Wyman3f1242f2020-01-28 13:11:25 -060025
Brandon Wymanb654c612021-11-05 23:24:51 +000026struct PMBusExpectations
27{
28 uint16_t statusWordValue{0x0000};
29 uint8_t statusInputValue{0x00};
30 uint8_t statusMFRValue{0x00};
31 uint8_t statusCMLValue{0x00};
32 uint8_t statusVOUTValue{0x00};
Brandon Wymanb10b3be2021-11-09 22:12:15 +000033 uint8_t statusIOUTValue{0x00};
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +000034 uint8_t statusFans12Value{0x00};
Brandon Wyman96893a42021-11-05 19:56:57 +000035 uint8_t statusTempValue{0x00};
Brandon Wymanb654c612021-11-05 23:24:51 +000036};
37
Brandon Wyman8da35c52021-10-28 22:45:08 +000038// Helper function to setup expectations for various STATUS_* commands
Brandon Wymanb654c612021-11-05 23:24:51 +000039void setPMBusExpectations(MockedPMBus& mockPMBus,
40 const PMBusExpectations& expectations)
Brandon Wyman8da35c52021-10-28 22:45:08 +000041{
Brandon Wyman32453e92021-12-15 19:00:14 +000042 EXPECT_CALL(mockPMBus, read(STATUS_WORD, _, _))
Brandon Wyman8da35c52021-10-28 22:45:08 +000043 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000044 .WillOnce(Return(expectations.statusWordValue));
Brandon Wyman8da35c52021-10-28 22:45:08 +000045
Brandon Wymanb654c612021-11-05 23:24:51 +000046 if (expectations.statusWordValue != 0)
Brandon Wyman8da35c52021-10-28 22:45:08 +000047 {
48 // If fault bits are on in STATUS_WORD, there will also be a read of
Brandon Wyman96893a42021-11-05 19:56:57 +000049 // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT (page 0), and
50 // STATUS_TEMPERATURE.
Brandon Wyman32453e92021-12-15 19:00:14 +000051 EXPECT_CALL(mockPMBus, read(STATUS_INPUT, _, _))
Brandon Wyman8da35c52021-10-28 22:45:08 +000052 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000053 .WillOnce(Return(expectations.statusInputValue));
Brandon Wyman32453e92021-12-15 19:00:14 +000054 EXPECT_CALL(mockPMBus, read(STATUS_MFR, _, _))
Brandon Wyman8da35c52021-10-28 22:45:08 +000055 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000056 .WillOnce(Return(expectations.statusMFRValue));
Brandon Wyman32453e92021-12-15 19:00:14 +000057 EXPECT_CALL(mockPMBus, read(STATUS_CML, _, _))
Brandon Wyman8da35c52021-10-28 22:45:08 +000058 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000059 .WillOnce(Return(expectations.statusCMLValue));
Brandon Wyman6710ba22021-10-27 17:39:31 +000060 // Page will need to be set to 0 to read STATUS_VOUT.
61 EXPECT_CALL(mockPMBus, insertPageNum(STATUS_VOUT, 0))
62 .Times(1)
63 .WillOnce(Return("status0_vout"));
Brandon Wyman32453e92021-12-15 19:00:14 +000064 EXPECT_CALL(mockPMBus, read("status0_vout", _, _))
Brandon Wyman6710ba22021-10-27 17:39:31 +000065 .Times(1)
Brandon Wymanb654c612021-11-05 23:24:51 +000066 .WillOnce(Return(expectations.statusVOUTValue));
Brandon Wyman32453e92021-12-15 19:00:14 +000067 EXPECT_CALL(mockPMBus, read(STATUS_IOUT, _, _))
Brandon Wymanb10b3be2021-11-09 22:12:15 +000068 .Times(1)
69 .WillOnce(Return(expectations.statusIOUTValue));
Brandon Wyman32453e92021-12-15 19:00:14 +000070 EXPECT_CALL(mockPMBus, read(STATUS_FANS_1_2, _, _))
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +000071 .Times(1)
72 .WillOnce(Return(expectations.statusFans12Value));
Brandon Wyman32453e92021-12-15 19:00:14 +000073 EXPECT_CALL(mockPMBus, read(STATUS_TEMPERATURE, _, _))
Brandon Wyman96893a42021-11-05 19:56:57 +000074 .Times(1)
75 .WillOnce(Return(expectations.statusTempValue));
Brandon Wyman8da35c52021-10-28 22:45:08 +000076 }
77}
78
Brandon Wyman3f1242f2020-01-28 13:11:25 -060079class PowerSupplyTests : public ::testing::Test
80{
81 public:
82 PowerSupplyTests() :
83 mockedUtil(reinterpret_cast<const MockedUtil&>(getUtils()))
84 {
85 ON_CALL(mockedUtil, getPresence(_, _)).WillByDefault(Return(false));
86 }
87
88 ~PowerSupplyTests() override
89 {
90 freeUtils();
91 }
92
93 const MockedUtil& mockedUtil;
94};
95
Brandon Wyman391a0692021-12-08 23:28:18 +000096// Helper function for when a power supply goes from missing to present.
97void setMissingToPresentExpects(MockedPMBus& pmbus, const MockedUtil& util)
98{
99 // Call to analyze() will update to present, that will trigger updating
100 // to the correct/latest HWMON directory, in case it changes.
101 EXPECT_CALL(pmbus, findHwmonDir());
102 // Presence change from missing to present will trigger write to
103 // ON_OFF_CONFIG.
104 EXPECT_CALL(pmbus, writeBinary(ON_OFF_CONFIG, _, _));
105 // Presence change from missing to present will trigger in1_input read
106 // in an attempt to get CLEAR_FAULTS called.
Brandon Wyman82affd92021-11-24 19:12:49 +0000107 // This READ_VIN for CLEAR_FAULTS does not check the returned value.
Brandon Wyman3225a452022-03-18 18:51:49 +0000108 EXPECT_CALL(pmbus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
109 // The call for clearing faults includes clearing VIN_UV fault.
110 // The voltage defaults to 0, the first call to analyze should update the
111 // voltage to the current reading, triggering clearing VIN_UV fault(s)
112 // due to below minimum to within range voltage.
113 EXPECT_CALL(pmbus, read("in1_lcrit_alarm", _, _))
Brandon Wyman82affd92021-11-24 19:12:49 +0000114 .Times(2)
Brandon Wyman3225a452022-03-18 18:51:49 +0000115 .WillRepeatedly(Return(1));
Brandon Wyman391a0692021-12-08 23:28:18 +0000116 // Missing/present call will update Presence in inventory.
Brandon Wyman391a0692021-12-08 23:28:18 +0000117 EXPECT_CALL(util, setPresence(_, _, true, _));
118}
119
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600120TEST_F(PowerSupplyTests, Constructor)
121{
122 /**
123 * @param[in] invpath - String for inventory path to use
124 * @param[in] i2cbus - The bus number this power supply is on
125 * @param[in] i2caddr - The 16-bit I2C address of the power supply
B. J. Wyman681b2a32021-04-20 22:31:22 +0000126 * @param[in] gpioLineName - The string for the gpio-line-name to read for
127 * presence.
128 * @param[in] bindDelay - Time in milliseconds to delay binding the device
129 * driver after seeing the presence line go active.
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600130 */
131 auto bus = sdbusplus::bus::new_default();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600132
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500133 // Try where inventory path is empty, constructor should fail.
134 try
135 {
Brandon Wymanc3324422022-03-24 20:30:57 +0000136 auto psu = std::make_unique<PowerSupply>(bus, "", 3, 0x68, "ibm-cffps",
137 PSUGPIOLineName);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500138 ADD_FAILURE() << "Should not have reached this line.";
139 }
140 catch (const std::invalid_argument& e)
141 {
142 EXPECT_STREQ(e.what(), "Invalid empty inventoryPath");
143 }
144 catch (...)
145 {
146 ADD_FAILURE() << "Should not have caught exception.";
147 }
148
B. J. Wyman681b2a32021-04-20 22:31:22 +0000149 // TODO: Try invalid i2c address?
150
151 // Try where gpioLineName is empty.
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500152 try
153 {
Brandon Wymanc3324422022-03-24 20:30:57 +0000154 auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68,
155 "ibm-cffps", "");
B. J. Wyman681b2a32021-04-20 22:31:22 +0000156 ADD_FAILURE()
157 << "Should not have reached this line. Invalid gpioLineName.";
158 }
159 catch (const std::invalid_argument& e)
160 {
161 EXPECT_STREQ(e.what(), "Invalid empty gpioLineName");
162 }
163 catch (...)
164 {
165 ADD_FAILURE() << "Should not have caught exception.";
166 }
167
168 // Test with valid arguments
169 // NOT using D-Bus inventory path for presence.
170 try
171 {
172 auto psu = std::make_unique<PowerSupply>(bus, PSUInventoryPath, 3, 0x68,
Brandon Wymanc3324422022-03-24 20:30:57 +0000173 "ibm-cffps", PSUGPIOLineName);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500174
175 EXPECT_EQ(psu->isPresent(), false);
176 EXPECT_EQ(psu->isFaulted(), false);
Brandon Wyman8da35c52021-10-28 22:45:08 +0000177 EXPECT_EQ(psu->hasCommFault(), false);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500178 EXPECT_EQ(psu->hasInputFault(), false);
179 EXPECT_EQ(psu->hasMFRFault(), false);
180 EXPECT_EQ(psu->hasVINUVFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000181 EXPECT_EQ(psu->hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000182 EXPECT_EQ(psu->hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000183 EXPECT_EQ(psu->hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000184 EXPECT_EQ(psu->hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000185 EXPECT_EQ(psu->hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000186 EXPECT_EQ(psu->hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000187 EXPECT_EQ(psu->hasPSKillFault(), false);
188 EXPECT_EQ(psu->hasPS12VcsFault(), false);
189 EXPECT_EQ(psu->hasPSCS12VFault(), false);
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500190 }
191 catch (...)
192 {
193 ADD_FAILURE() << "Should not have caught exception.";
194 }
B. J. Wyman681b2a32021-04-20 22:31:22 +0000195
196 // Test with valid arguments
197 // TODO: Using D-Bus inventory path for presence.
198 try
199 {
200 // FIXME: How do I get that presenceGPIO.read() in the startup to throw
201 // an exception?
202
203 // EXPECT_CALL(mockedUtil, getPresence(_,
204 // StrEq(PSUInventoryPath)))
205 // .Times(1);
206 }
207 catch (...)
208 {
209 ADD_FAILURE() << "Should not have caught exception.";
210 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600211}
212
213TEST_F(PowerSupplyTests, Analyze)
214{
215 auto bus = sdbusplus::bus::new_default();
216
Brandon Wymanb654c612021-11-05 23:24:51 +0000217 {
218 // If I default to reading the GPIO, I will NOT expect a call to
219 // getPresence().
B. J. Wyman681b2a32021-04-20 22:31:22 +0000220
Brandon Wymanc3324422022-03-24 20:30:57 +0000221 PowerSupply psu{bus, PSUInventoryPath, 4,
222 0x69, "ibm-cffps", PSUGPIOLineName};
Brandon Wymanb654c612021-11-05 23:24:51 +0000223 MockedGPIOInterface* mockPresenceGPIO =
224 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
225 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(0));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000226
Brandon Wymanb654c612021-11-05 23:24:51 +0000227 psu.analyze();
228 // By default, nothing should change.
229 EXPECT_EQ(psu.isPresent(), false);
230 EXPECT_EQ(psu.isFaulted(), false);
231 EXPECT_EQ(psu.hasInputFault(), false);
232 EXPECT_EQ(psu.hasMFRFault(), false);
233 EXPECT_EQ(psu.hasVINUVFault(), false);
234 EXPECT_EQ(psu.hasCommFault(), false);
235 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000236 EXPECT_EQ(psu.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000237 EXPECT_EQ(psu.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000238 EXPECT_EQ(psu.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000239 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000240 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000241 EXPECT_EQ(psu.hasPSKillFault(), false);
242 EXPECT_EQ(psu.hasPS12VcsFault(), false);
243 EXPECT_EQ(psu.hasPSCS12VFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000244 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600245
Brandon Wymanc3324422022-03-24 20:30:57 +0000246 PowerSupply psu2{bus, PSUInventoryPath, 5,
247 0x6a, "ibm-cffps", PSUGPIOLineName};
B. J. Wyman681b2a32021-04-20 22:31:22 +0000248 // In order to get the various faults tested, the power supply needs to
249 // be present in order to read from the PMBus device(s).
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000250 MockedGPIOInterface* mockPresenceGPIO2 =
251 static_cast<MockedGPIOInterface*>(psu2.getPresenceGPIO());
Brandon Wyman06ca4592021-12-06 22:52:23 +0000252 // Always return 1 to indicate present.
253 // Each analyze() call will trigger a read of the presence GPIO.
254 EXPECT_CALL(*mockPresenceGPIO2, read()).WillRepeatedly(Return(1));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000255 EXPECT_EQ(psu2.isPresent(), false);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600256
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600257 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu2.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +0000258 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +0000259 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
260 // for INPUT_HISTORY will check max_power_out to see if it is
261 // old/unsupported power supply. Indicate good value, supported.
262 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
263 .Times(1)
264 .WillOnce(Return("2000"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600265
Brandon Wymanb654c612021-11-05 23:24:51 +0000266 // STATUS_WORD INPUT fault.
267 {
268 // Start with STATUS_WORD 0x0000. Powered on, no faults.
269 // Set expectations for a no fault
270 PMBusExpectations expectations;
271 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000272 // After reading STATUS_WORD, etc., there will be a READ_VIN check.
273 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
274 .Times(1)
275 .WillOnce(Return("206000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000276 psu2.analyze();
277 EXPECT_EQ(psu2.isPresent(), true);
278 EXPECT_EQ(psu2.isFaulted(), false);
279 EXPECT_EQ(psu2.hasInputFault(), false);
280 EXPECT_EQ(psu2.hasMFRFault(), false);
281 EXPECT_EQ(psu2.hasVINUVFault(), false);
282 EXPECT_EQ(psu2.hasCommFault(), false);
283 EXPECT_EQ(psu2.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000284 EXPECT_EQ(psu2.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000285 EXPECT_EQ(psu2.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000286 EXPECT_EQ(psu2.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000287 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000288 EXPECT_EQ(psu2.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000289 EXPECT_EQ(psu2.hasPSKillFault(), false);
290 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
291 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000292
293 // Update expectations for STATUS_WORD input fault/warn
Brandon Wyman96893a42021-11-05 19:56:57 +0000294 // STATUS_INPUT fault bits ... on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000295 expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
Brandon Wyman3225a452022-03-18 18:51:49 +0000296 // IIN_OC fault.
297 expectations.statusInputValue = 0x04;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000298
299 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
300 {
301 setPMBusExpectations(mockPMBus, expectations);
302 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
303 .Times(1)
304 .WillOnce(Return("207000"));
305 psu2.analyze();
306 EXPECT_EQ(psu2.isPresent(), true);
307 // Should not be faulted until it reaches the deglitch limit.
308 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
309 EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT);
310 EXPECT_EQ(psu2.hasMFRFault(), false);
311 EXPECT_EQ(psu2.hasVINUVFault(), false);
312 EXPECT_EQ(psu2.hasCommFault(), false);
313 EXPECT_EQ(psu2.hasVoutOVFault(), false);
314 EXPECT_EQ(psu2.hasIoutOCFault(), false);
315 EXPECT_EQ(psu2.hasVoutUVFault(), false);
316 EXPECT_EQ(psu2.hasFanFault(), false);
317 EXPECT_EQ(psu2.hasTempFault(), false);
318 EXPECT_EQ(psu2.hasPgoodFault(), false);
319 EXPECT_EQ(psu2.hasPSKillFault(), false);
320 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
321 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
322 }
Brandon Wymanb654c612021-11-05 23:24:51 +0000323 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600324
Brandon Wyman32453e92021-12-15 19:00:14 +0000325 EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
Brandon Wyman3225a452022-03-18 18:51:49 +0000326 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
327 .Times(1)
328 .WillOnce(Return(1));
Brandon Wymanc2906f42021-12-21 20:14:56 +0000329 psu2.clearFaults();
330
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600331 // STATUS_WORD INPUT/UV fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000332 {
333 // First need it to return good status, then the fault
334 PMBusExpectations expectations;
335 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000336 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
337 .Times(1)
338 .WillOnce(Return("208000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000339 psu2.analyze();
Brandon Wymanc2906f42021-12-21 20:14:56 +0000340 EXPECT_EQ(psu2.isFaulted(), false);
341 EXPECT_EQ(psu2.hasInputFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000342 // Now set fault bits in STATUS_WORD
343 expectations.statusWordValue =
344 (status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT);
345 // STATUS_INPUT fault bits ... on.
Brandon Wyman3225a452022-03-18 18:51:49 +0000346 expectations.statusInputValue = 0x18;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000347 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
348 {
349 setPMBusExpectations(mockPMBus, expectations);
350 // Input/UV fault, so voltage should read back low.
351 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
352 .Times(1)
353 .WillOnce(Return("19123"));
354 psu2.analyze();
355 EXPECT_EQ(psu2.isPresent(), true);
356 // Only faulted if hit deglitch limit
357 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
358 EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT);
359 EXPECT_EQ(psu2.hasVINUVFault(), x >= DEGLITCH_LIMIT);
360 EXPECT_EQ(psu2.hasMFRFault(), false);
361 EXPECT_EQ(psu2.hasCommFault(), false);
362 EXPECT_EQ(psu2.hasVoutOVFault(), false);
363 EXPECT_EQ(psu2.hasIoutOCFault(), false);
364 EXPECT_EQ(psu2.hasVoutUVFault(), false);
365 EXPECT_EQ(psu2.hasFanFault(), false);
366 EXPECT_EQ(psu2.hasTempFault(), false);
367 EXPECT_EQ(psu2.hasPgoodFault(), false);
368 EXPECT_EQ(psu2.hasPSKillFault(), false);
369 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
370 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
371 }
Brandon Wyman82affd92021-11-24 19:12:49 +0000372 // Turning VIN_UV fault off causes clearing of faults, causing read of
373 // in1_input as an attempt to get CLEAR_FAULTS called.
374 expectations.statusWordValue = 0;
375 setPMBusExpectations(mockPMBus, expectations);
376 // The call to read the voltage
377 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
378 .Times(1)
379 .WillOnce(Return("209000"));
Brandon Wyman3225a452022-03-18 18:51:49 +0000380 // The call to clear VIN_UV/Off fault(s)
381 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
Brandon Wyman32453e92021-12-15 19:00:14 +0000382 .Times(1)
Brandon Wyman3225a452022-03-18 18:51:49 +0000383 .WillOnce(Return(1));
Brandon Wyman82affd92021-11-24 19:12:49 +0000384 psu2.analyze();
385 // Should remain present, no longer be faulted, no input fault, no
386 // VIN_UV fault. Nothing else should change.
387 EXPECT_EQ(psu2.isPresent(), true);
388 EXPECT_EQ(psu2.isFaulted(), false);
389 EXPECT_EQ(psu2.hasInputFault(), false);
390 EXPECT_EQ(psu2.hasVINUVFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000391 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600392
Brandon Wyman32453e92021-12-15 19:00:14 +0000393 EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
Brandon Wyman3225a452022-03-18 18:51:49 +0000394 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
395 .Times(1)
396 .WillOnce(Return(1));
Brandon Wymanc2906f42021-12-21 20:14:56 +0000397 psu2.clearFaults();
398
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600399 // STATUS_WORD MFR fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000400 {
401 // First need it to return good status, then the 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("210000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000407 psu2.analyze();
408 // Now STATUS_WORD with MFR fault bit on.
409 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
410 // STATUS_MFR bits on.
411 expectations.statusMFRValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000412
413 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
414 {
415 setPMBusExpectations(mockPMBus, expectations);
416 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
417 .Times(1)
418 .WillOnce(Return("211000"));
419 psu2.analyze();
420 EXPECT_EQ(psu2.isPresent(), true);
421 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
422 EXPECT_EQ(psu2.hasInputFault(), false);
423 EXPECT_EQ(psu2.hasMFRFault(), x >= DEGLITCH_LIMIT);
424 EXPECT_EQ(psu2.hasPSKillFault(), x >= DEGLITCH_LIMIT);
425 EXPECT_EQ(psu2.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
426 EXPECT_EQ(psu2.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
427 EXPECT_EQ(psu2.hasVINUVFault(), false);
428 EXPECT_EQ(psu2.hasCommFault(), false);
429 EXPECT_EQ(psu2.hasVoutOVFault(), false);
430 EXPECT_EQ(psu2.hasIoutOCFault(), false);
431 EXPECT_EQ(psu2.hasVoutUVFault(), false);
432 EXPECT_EQ(psu2.hasFanFault(), false);
433 EXPECT_EQ(psu2.hasTempFault(), false);
434 EXPECT_EQ(psu2.hasPgoodFault(), false);
435 }
Brandon Wymanb654c612021-11-05 23:24:51 +0000436 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600437
Brandon Wyman32453e92021-12-15 19:00:14 +0000438 EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
Brandon Wyman3225a452022-03-18 18:51:49 +0000439 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
440 .Times(1)
441 .WillOnce(Return(1));
Brandon Wymanc2906f42021-12-21 20:14:56 +0000442 psu2.clearFaults();
Brandon Wyman3225a452022-03-18 18:51:49 +0000443
Brandon Wyman96893a42021-11-05 19:56:57 +0000444 // Temperature fault.
Brandon Wymanb654c612021-11-05 23:24:51 +0000445 {
446 // First STATUS_WORD with no bits set, then with temperature fault.
447 PMBusExpectations expectations;
448 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000449 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
450 .Times(1)
451 .WillOnce(Return("212000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000452 psu2.analyze();
453 // STATUS_WORD with temperature fault bit on.
454 expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
Brandon Wyman96893a42021-11-05 19:56:57 +0000455 // STATUS_TEMPERATURE with fault bit(s) on.
456 expectations.statusTempValue = 0x10;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000457 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
458 {
459 setPMBusExpectations(mockPMBus, expectations);
460 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
461 .Times(1)
462 .WillOnce(Return("213000"));
463 psu2.analyze();
464 EXPECT_EQ(psu2.isPresent(), true);
465 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
466 EXPECT_EQ(psu2.hasInputFault(), false);
467 EXPECT_EQ(psu2.hasMFRFault(), false);
468 EXPECT_EQ(psu2.hasVINUVFault(), false);
469 EXPECT_EQ(psu2.hasCommFault(), false);
470 EXPECT_EQ(psu2.hasVoutOVFault(), false);
471 EXPECT_EQ(psu2.hasIoutOCFault(), false);
472 EXPECT_EQ(psu2.hasVoutUVFault(), false);
473 EXPECT_EQ(psu2.hasFanFault(), false);
474 EXPECT_EQ(psu2.hasTempFault(), x >= DEGLITCH_LIMIT);
475 EXPECT_EQ(psu2.hasPgoodFault(), false);
476 EXPECT_EQ(psu2.hasPSKillFault(), false);
477 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
478 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
479 }
Brandon Wymanb654c612021-11-05 23:24:51 +0000480 }
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000481
Brandon Wyman32453e92021-12-15 19:00:14 +0000482 EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
Brandon Wyman3225a452022-03-18 18:51:49 +0000483 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
484 .Times(1)
485 .WillOnce(Return(1));
Brandon Wymanc2906f42021-12-21 20:14:56 +0000486 psu2.clearFaults();
Brandon Wyman3225a452022-03-18 18:51:49 +0000487
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000488 // CML fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000489 {
490 // First STATUS_WORD wit no bits set, then with CML fault.
491 PMBusExpectations expectations;
492 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000493 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
494 .Times(1)
495 .WillOnce(Return("214000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000496 psu2.analyze();
497 // STATUS_WORD with CML fault bit on.
498 expectations.statusWordValue = (status_word::CML_FAULT);
499 // Turn on STATUS_CML fault bit(s)
500 expectations.statusCMLValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000501 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
502 {
503 setPMBusExpectations(mockPMBus, expectations);
504 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
505 .Times(1)
506 .WillOnce(Return("215000"));
507 psu2.analyze();
508 EXPECT_EQ(psu2.isPresent(), true);
509 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
510 EXPECT_EQ(psu2.hasCommFault(), x >= DEGLITCH_LIMIT);
511 EXPECT_EQ(psu2.hasInputFault(), false);
512 EXPECT_EQ(psu2.hasMFRFault(), false);
513 EXPECT_EQ(psu2.hasVINUVFault(), false);
514 EXPECT_EQ(psu2.hasVoutOVFault(), false);
515 EXPECT_EQ(psu2.hasIoutOCFault(), false);
516 EXPECT_EQ(psu2.hasVoutUVFault(), false);
517 EXPECT_EQ(psu2.hasFanFault(), false);
518 EXPECT_EQ(psu2.hasTempFault(), false);
519 EXPECT_EQ(psu2.hasPgoodFault(), false);
520 EXPECT_EQ(psu2.hasPSKillFault(), false);
521 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
522 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
523 }
Brandon Wymanb654c612021-11-05 23:24:51 +0000524 }
Brandon Wyman6710ba22021-10-27 17:39:31 +0000525
Brandon Wyman32453e92021-12-15 19:00:14 +0000526 EXPECT_CALL(mockPMBus, read(READ_VIN, _, _)).Times(1).WillOnce(Return(1));
Brandon Wyman3225a452022-03-18 18:51:49 +0000527 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
528 .Times(1)
529 .WillOnce(Return(1));
Brandon Wymanc2906f42021-12-21 20:14:56 +0000530 psu2.clearFaults();
Brandon Wyman3225a452022-03-18 18:51:49 +0000531
Brandon Wyman6710ba22021-10-27 17:39:31 +0000532 // VOUT_OV_FAULT fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000533 {
534 // First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault.
535 PMBusExpectations expectations;
536 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000537 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
538 .Times(1)
539 .WillOnce(Return("216000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000540 psu2.analyze();
541 // STATUS_WORD with VOUT/VOUT_OV fault.
542 expectations.statusWordValue =
543 ((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT));
544 // Turn on STATUS_VOUT fault bit(s)
545 expectations.statusVOUTValue = 0xA0;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000546 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
547 {
548 // STATUS_TEMPERATURE don't care (default)
549 setPMBusExpectations(mockPMBus, expectations);
550 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
551 .Times(1)
552 .WillOnce(Return("217000"));
553 psu2.analyze();
554 EXPECT_EQ(psu2.isPresent(), true);
555 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
556 EXPECT_EQ(psu2.hasInputFault(), false);
557 EXPECT_EQ(psu2.hasMFRFault(), false);
558 EXPECT_EQ(psu2.hasVINUVFault(), false);
559 EXPECT_EQ(psu2.hasCommFault(), false);
560 EXPECT_EQ(psu2.hasVoutOVFault(), x >= DEGLITCH_LIMIT);
561 EXPECT_EQ(psu2.hasVoutUVFault(), false);
562 EXPECT_EQ(psu2.hasIoutOCFault(), false);
563 EXPECT_EQ(psu2.hasFanFault(), false);
564 EXPECT_EQ(psu2.hasTempFault(), false);
565 EXPECT_EQ(psu2.hasPgoodFault(), false);
566 EXPECT_EQ(psu2.hasPSKillFault(), false);
567 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
568 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
569 }
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000570 }
571
572 // IOUT_OC_FAULT fault
573 {
574 // First STATUS_WORD with no bits set, then with IOUT_OC fault.
575 PMBusExpectations expectations;
576 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000577 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
578 .Times(1)
579 .WillOnce(Return("218000"));
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000580 psu2.analyze();
581 // STATUS_WORD with IOUT_OC fault.
582 expectations.statusWordValue = status_word::IOUT_OC_FAULT;
583 // Turn on STATUS_IOUT fault bit(s)
584 expectations.statusIOUTValue = 0x88;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000585 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
586 {
587 setPMBusExpectations(mockPMBus, expectations);
588 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
589 .Times(1)
590 .WillOnce(Return("219000"));
591 psu2.analyze();
592 EXPECT_EQ(psu2.isPresent(), true);
593 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
594 EXPECT_EQ(psu2.hasInputFault(), false);
595 EXPECT_EQ(psu2.hasMFRFault(), false);
596 EXPECT_EQ(psu2.hasVINUVFault(), false);
597 EXPECT_EQ(psu2.hasCommFault(), false);
598 EXPECT_EQ(psu2.hasVoutOVFault(), false);
599 EXPECT_EQ(psu2.hasIoutOCFault(), x >= DEGLITCH_LIMIT);
600 EXPECT_EQ(psu2.hasVoutUVFault(), false);
601 EXPECT_EQ(psu2.hasFanFault(), false);
602 EXPECT_EQ(psu2.hasTempFault(), false);
603 EXPECT_EQ(psu2.hasPgoodFault(), false);
604 EXPECT_EQ(psu2.hasPSKillFault(), false);
605 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
606 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
607 }
Brandon Wyman2cf46942021-10-28 19:09:16 +0000608 }
609
610 // VOUT_UV_FAULT
611 {
612 // First STATUS_WORD with no bits set, then with VOUT fault.
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("220000"));
Brandon Wyman2cf46942021-10-28 19:09:16 +0000618 psu2.analyze();
619 // Change STATUS_WORD to indicate VOUT fault.
620 expectations.statusWordValue = (status_word::VOUT_FAULT);
621 // Turn on STATUS_VOUT fault bit(s)
622 expectations.statusVOUTValue = 0x30;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000623 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
624 {
625 setPMBusExpectations(mockPMBus, expectations);
626 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
627 .Times(1)
628 .WillOnce(Return("221000"));
629 psu2.analyze();
630 EXPECT_EQ(psu2.isPresent(), true);
631 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
632 EXPECT_EQ(psu2.hasInputFault(), false);
633 EXPECT_EQ(psu2.hasMFRFault(), false);
634 EXPECT_EQ(psu2.hasVINUVFault(), false);
635 EXPECT_EQ(psu2.hasCommFault(), false);
636 EXPECT_EQ(psu2.hasVoutOVFault(), false);
637 EXPECT_EQ(psu2.hasIoutOCFault(), false);
638 EXPECT_EQ(psu2.hasVoutUVFault(), x >= DEGLITCH_LIMIT);
639 EXPECT_EQ(psu2.hasFanFault(), false);
640 EXPECT_EQ(psu2.hasTempFault(), false);
641 EXPECT_EQ(psu2.hasPgoodFault(), false);
642 EXPECT_EQ(psu2.hasPSKillFault(), false);
643 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
644 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
645 }
Brandon Wymanb654c612021-11-05 23:24:51 +0000646 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600647
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000648 // Fan fault
Brandon Wymanb654c612021-11-05 23:24:51 +0000649 {
650 // First STATUS_WORD with no bits set, then with fan fault.
651 PMBusExpectations expectations;
652 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000653 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
654 .Times(1)
655 .WillOnce(Return("222000"));
Brandon Wymanb654c612021-11-05 23:24:51 +0000656 psu2.analyze();
657 expectations.statusWordValue = (status_word::FAN_FAULT);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000658 // STATUS_FANS_1_2 with fan 1 warning & fault bits on.
659 expectations.statusFans12Value = 0xA0;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000660
661 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
662 {
663 setPMBusExpectations(mockPMBus, expectations);
664 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
665 .Times(1)
666 .WillOnce(Return("223000"));
667 psu2.analyze();
668 EXPECT_EQ(psu2.isPresent(), true);
669 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
670 EXPECT_EQ(psu2.hasFanFault(), x >= DEGLITCH_LIMIT);
671 EXPECT_EQ(psu2.hasInputFault(), false);
672 EXPECT_EQ(psu2.hasMFRFault(), false);
673 EXPECT_EQ(psu2.hasVINUVFault(), false);
674 EXPECT_EQ(psu2.hasCommFault(), false);
675 EXPECT_EQ(psu2.hasVoutOVFault(), false);
676 EXPECT_EQ(psu2.hasIoutOCFault(), false);
677 EXPECT_EQ(psu2.hasVoutUVFault(), false);
678 EXPECT_EQ(psu2.hasTempFault(), false);
679 EXPECT_EQ(psu2.hasPgoodFault(), false);
680 EXPECT_EQ(psu2.hasPSKillFault(), false);
681 EXPECT_EQ(psu2.hasPS12VcsFault(), false);
682 EXPECT_EQ(psu2.hasPSCS12VFault(), false);
683 }
Brandon Wymanb654c612021-11-05 23:24:51 +0000684 }
Brandon Wyman2916ea52021-11-06 03:31:18 +0000685
Brandon Wyman06ca4592021-12-06 22:52:23 +0000686 // PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT.
Brandon Wyman2916ea52021-11-06 03:31:18 +0000687 {
Brandon Wyman2916ea52021-11-06 03:31:18 +0000688 // First STATUS_WORD with no bits set.
689 PMBusExpectations expectations;
690 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000691 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
692 .Times(1)
693 .WillOnce(Return("123000"));
Brandon Wyman2916ea52021-11-06 03:31:18 +0000694 psu2.analyze();
695 EXPECT_EQ(psu2.isFaulted(), false);
696 // POWER_GOOD# inactive, and OFF bit on.
697 expectations.statusWordValue =
698 ((status_word::POWER_GOOD_NEGATED) | (status_word::UNIT_IS_OFF));
Brandon Wyman06ca4592021-12-06 22:52:23 +0000699 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
700 {
701 // STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and
702 // STATUS_TEMPERATURE: Don't care if bits set or not (defaults).
703 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000704 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
705 .Times(1)
706 .WillOnce(Return("124000"));
Brandon Wyman06ca4592021-12-06 22:52:23 +0000707 psu2.analyze();
708 EXPECT_EQ(psu2.isPresent(), true);
Brandon Wymanc2906f42021-12-21 20:14:56 +0000709 EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
Brandon Wyman06ca4592021-12-06 22:52:23 +0000710 EXPECT_EQ(psu2.hasInputFault(), false);
711 EXPECT_EQ(psu2.hasMFRFault(), false);
712 EXPECT_EQ(psu2.hasVINUVFault(), false);
713 EXPECT_EQ(psu2.hasCommFault(), false);
714 EXPECT_EQ(psu2.hasVoutOVFault(), false);
715 EXPECT_EQ(psu2.hasVoutUVFault(), false);
716 EXPECT_EQ(psu2.hasIoutOCFault(), false);
717 EXPECT_EQ(psu2.hasFanFault(), false);
718 EXPECT_EQ(psu2.hasTempFault(), false);
Brandon Wyman32453e92021-12-15 19:00:14 +0000719 EXPECT_EQ(psu2.hasPgoodFault(), x >= DEGLITCH_LIMIT);
Brandon Wyman06ca4592021-12-06 22:52:23 +0000720 }
Brandon Wyman2916ea52021-11-06 03:31:18 +0000721 }
722
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600723 // TODO: ReadFailure
724}
725
Brandon Wyman59a35792020-06-04 12:37:40 -0500726TEST_F(PowerSupplyTests, OnOffConfig)
727{
728 auto bus = sdbusplus::bus::new_default();
729 uint8_t data = 0x15;
730
731 // Test where PSU is NOT present
732 try
733 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000734 // Assume GPIO presence, not inventory presence?
Matt Spinler0975eaf2022-02-14 15:38:30 -0600735 EXPECT_CALL(mockedUtil, setAvailable(_, _, _)).Times(0);
Brandon Wymanc3324422022-03-24 20:30:57 +0000736 PowerSupply psu{bus, PSUInventoryPath, 4,
737 0x69, "ibm-cffps", PSUGPIOLineName};
B. J. Wyman681b2a32021-04-20 22:31:22 +0000738
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000739 MockedGPIOInterface* mockPresenceGPIO =
740 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000741 ON_CALL(*mockPresenceGPIO, read()).WillByDefault(Return(0));
Brandon Wyman59a35792020-06-04 12:37:40 -0500742 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
B. J. Wyman681b2a32021-04-20 22:31:22 +0000743 // Constructor should set initial presence, default read returns 0.
Brandon Wyman59a35792020-06-04 12:37:40 -0500744 // If it is not present, I should not be trying to write to it.
745 EXPECT_CALL(mockPMBus, writeBinary(_, _, _)).Times(0);
746 psu.onOffConfig(data);
747 }
748 catch (...)
Adriana Kobylak0c9a33d2021-09-13 18:05:09 +0000749 {}
Brandon Wyman59a35792020-06-04 12:37:40 -0500750
751 // Test where PSU is present
752 try
753 {
B. J. Wyman681b2a32021-04-20 22:31:22 +0000754 // Assume GPIO presence, not inventory presence?
Matt Spinler0975eaf2022-02-14 15:38:30 -0600755 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
Brandon Wymanc3324422022-03-24 20:30:57 +0000756 PowerSupply psu{bus, PSUInventoryPath, 5,
757 0x6a, "ibm-cffps", PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000758 MockedGPIOInterface* mockPresenceGPIO =
759 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wyman391a0692021-12-08 23:28:18 +0000760 // There will potentially be multiple calls, we want it to continue
761 // returning 1 for the GPIO read to keep the power supply present.
762 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman59a35792020-06-04 12:37:40 -0500763 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +0000764 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +0000765 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
766 // for INPUT_HISTORY will check max_power_out to see if it is
767 // old/unsupported power supply. Indicate good value, supported.
768 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
769 .Times(1)
770 .WillOnce(Return("2000"));
Brandon Wyman391a0692021-12-08 23:28:18 +0000771 // If I am calling analyze(), I should probably give it good data.
772 // STATUS_WORD 0x0000 is powered on, no faults.
773 PMBusExpectations expectations;
774 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000775 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
776 .Times(1)
777 .WillOnce(Return("205000"));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000778 psu.analyze();
Brandon Wyman391a0692021-12-08 23:28:18 +0000779 // I definitely should be writting ON_OFF_CONFIG if I call the function
780 EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, ElementsAre(0x15),
781 Type::HwmonDeviceDebug))
Brandon Wyman59a35792020-06-04 12:37:40 -0500782 .Times(1);
783 psu.onOffConfig(data);
784 }
785 catch (...)
Adriana Kobylak0c9a33d2021-09-13 18:05:09 +0000786 {}
Brandon Wyman59a35792020-06-04 12:37:40 -0500787}
788
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600789TEST_F(PowerSupplyTests, ClearFaults)
790{
791 auto bus = sdbusplus::bus::new_default();
Brandon Wymanc3324422022-03-24 20:30:57 +0000792 PowerSupply psu{bus, PSUInventoryPath, 13,
793 0x68, "ibm-cffps", PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000794 MockedGPIOInterface* mockPresenceGPIO =
795 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wyman06ca4592021-12-06 22:52:23 +0000796 // Always return 1 to indicate present.
797 // Each analyze() call will trigger a read of the presence GPIO.
798 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000799 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +0000800 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +0000801 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
802 // for INPUT_HISTORY will check max_power_out to see if it is
803 // old/unsupported power supply. Indicate good value, supported.
804 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
805 .Times(1)
806 .WillOnce(Return("2000"));
Brandon Wyman8da35c52021-10-28 22:45:08 +0000807 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +0000808 PMBusExpectations expectations;
809 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +0000810 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
811 .Times(1)
812 .WillOnce(Return("207000"));
B. J. Wyman681b2a32021-04-20 22:31:22 +0000813 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600814 EXPECT_EQ(psu.isPresent(), true);
815 EXPECT_EQ(psu.isFaulted(), false);
816 EXPECT_EQ(psu.hasInputFault(), false);
817 EXPECT_EQ(psu.hasMFRFault(), false);
818 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000819 EXPECT_EQ(psu.hasCommFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000820 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000821 EXPECT_EQ(psu.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000822 EXPECT_EQ(psu.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000823 EXPECT_EQ(psu.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000824 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000825 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000826 EXPECT_EQ(psu.hasPSKillFault(), false);
827 EXPECT_EQ(psu.hasPS12VcsFault(), false);
828 EXPECT_EQ(psu.hasPSCS12VFault(), false);
Brandon Wymanb654c612021-11-05 23:24:51 +0000829
Brandon Wymanf07bc792021-10-12 19:00:35 +0000830 // STATUS_WORD with fault bits galore!
Brandon Wymanb654c612021-11-05 23:24:51 +0000831 expectations.statusWordValue = 0xFFFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000832 // STATUS_INPUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000833 expectations.statusInputValue = 0xFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +0000834 // STATUS_MFR_SPEFIC with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000835 expectations.statusMFRValue = 0xFF;
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000836 // STATUS_CML with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000837 expectations.statusCMLValue = 0xFF;
Brandon Wyman6710ba22021-10-27 17:39:31 +0000838 // STATUS_VOUT with bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +0000839 expectations.statusVOUTValue = 0xFF;
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000840 // STATUS_IOUT with bits on.
841 expectations.statusIOUTValue = 0xFF;
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000842 // STATUS_FANS_1_2 with bits on.
843 expectations.statusFans12Value = 0xFF;
Brandon Wyman96893a42021-11-05 19:56:57 +0000844 // STATUS_TEMPERATURE with bits on.
845 expectations.statusTempValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000846
847 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
848 {
849 setPMBusExpectations(mockPMBus, expectations);
850 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
851 .Times(1)
852 .WillOnce(Return("0"));
Matt Spinler0975eaf2022-02-14 15:38:30 -0600853 if (x == DEGLITCH_LIMIT)
854 {
855 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
856 }
Brandon Wymanc2906f42021-12-21 20:14:56 +0000857 psu.analyze();
858 EXPECT_EQ(psu.isPresent(), true);
859 // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
860 // Rely on HasVoutUVFault() to verify this sets and clears.
861 EXPECT_EQ(psu.hasVoutUVFault(), false);
862 // All faults are deglitched up to DEGLITCH_LIMIT
863 EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT);
864 EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT);
865 EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT);
866 EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT);
867 EXPECT_EQ(psu.hasCommFault(), x >= DEGLITCH_LIMIT);
868 EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT);
869 EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT);
870 EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT);
871 EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT);
872 EXPECT_EQ(psu.hasPgoodFault(), x >= DEGLITCH_LIMIT);
873 EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT);
874 EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
875 EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
876 }
877
Brandon Wyman32453e92021-12-15 19:00:14 +0000878 EXPECT_CALL(mockPMBus, read(READ_VIN, _, _))
879 .Times(1)
880 .WillOnce(Return(207000));
Brandon Wyman3225a452022-03-18 18:51:49 +0000881 // Clearing VIN_UV fault via in1_lcrit_alarm
882 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
883 .Times(1)
884 .WillOnce(Return(1));
Matt Spinler0975eaf2022-02-14 15:38:30 -0600885 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600886 psu.clearFaults();
887 EXPECT_EQ(psu.isPresent(), true);
888 EXPECT_EQ(psu.isFaulted(), false);
889 EXPECT_EQ(psu.hasInputFault(), false);
890 EXPECT_EQ(psu.hasMFRFault(), false);
891 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000892 EXPECT_EQ(psu.hasCommFault(), false);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000893 EXPECT_EQ(psu.hasVoutOVFault(), false);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000894 EXPECT_EQ(psu.hasIoutOCFault(), false);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000895 EXPECT_EQ(psu.hasVoutUVFault(), false);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000896 EXPECT_EQ(psu.hasFanFault(), false);
Brandon Wyman96893a42021-11-05 19:56:57 +0000897 EXPECT_EQ(psu.hasTempFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000898 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000899 EXPECT_EQ(psu.hasPSKillFault(), false);
900 EXPECT_EQ(psu.hasPS12VcsFault(), false);
901 EXPECT_EQ(psu.hasPSCS12VFault(), false);
B. J. Wyman681b2a32021-04-20 22:31:22 +0000902
Brandon Wyman82affd92021-11-24 19:12:49 +0000903 // Faults clear on READ_VIN 0 -> !0
904 // STATUS_WORD with fault bits galore!
905 expectations.statusWordValue = 0xFFFF;
906 // STATUS_INPUT with fault bits on.
907 expectations.statusInputValue = 0xFF;
908 // STATUS_MFR_SPEFIC with bits on.
909 expectations.statusMFRValue = 0xFF;
910 // STATUS_CML with bits on.
911 expectations.statusCMLValue = 0xFF;
912 // STATUS_VOUT with bits on.
913 expectations.statusVOUTValue = 0xFF;
914 // STATUS_IOUT with bits on.
915 expectations.statusIOUTValue = 0xFF;
916 // STATUS_FANS_1_2 with bits on.
917 expectations.statusFans12Value = 0xFF;
918 // STATUS_TEMPERATURE with bits on.
919 expectations.statusTempValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000920
921 // All faults degltiched now. Check for false before limit above.
922 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
923 {
924 setPMBusExpectations(mockPMBus, expectations);
925 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
926 .Times(1)
927 .WillOnce(Return("0"));
Matt Spinler0975eaf2022-02-14 15:38:30 -0600928 if (x == DEGLITCH_LIMIT)
929 {
930 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
931 }
Brandon Wymanc2906f42021-12-21 20:14:56 +0000932 psu.analyze();
933 }
934
Brandon Wyman82affd92021-11-24 19:12:49 +0000935 EXPECT_EQ(psu.isPresent(), true);
936 EXPECT_EQ(psu.isFaulted(), true);
937 EXPECT_EQ(psu.hasInputFault(), true);
938 EXPECT_EQ(psu.hasMFRFault(), true);
939 EXPECT_EQ(psu.hasVINUVFault(), true);
940 // True due to CML fault bits on
941 EXPECT_EQ(psu.hasCommFault(), true);
942 EXPECT_EQ(psu.hasVoutOVFault(), true);
943 EXPECT_EQ(psu.hasIoutOCFault(), true);
944 // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
945 // Rely on HasVoutUVFault() to verify this sets and clears.
946 EXPECT_EQ(psu.hasVoutUVFault(), false);
947 EXPECT_EQ(psu.hasFanFault(), true);
948 EXPECT_EQ(psu.hasTempFault(), true);
Brandon Wymanc2906f42021-12-21 20:14:56 +0000949 EXPECT_EQ(psu.hasPgoodFault(), true);
Brandon Wyman82affd92021-11-24 19:12:49 +0000950 EXPECT_EQ(psu.hasPSKillFault(), true);
951 EXPECT_EQ(psu.hasPS12VcsFault(), true);
952 EXPECT_EQ(psu.hasPSCS12VFault(), true);
953 // STATUS_WORD with INPUT/VIN_UV fault bits off.
954 expectations.statusWordValue = 0xDFF7;
955 // STATUS_INPUT with VIN_UV_WARNING, VIN_UV_FAULT, and Unit Off For
956 // Insufficient Input Voltage bits off.
957 expectations.statusInputValue = 0xC7;
958 setPMBusExpectations(mockPMBus, expectations);
959 // READ_VIN back in range.
960 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
961 .Times(1)
962 .WillOnce(Return("206000"));
Brandon Wyman3225a452022-03-18 18:51:49 +0000963 // VIN_UV cleared via in1_lcrit_alarm when voltage back in range.
964 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
965 .Times(1)
966 .WillOnce(Return(1));
967 psu.analyze();
968 // We only cleared the VIN_UV and OFF faults.
969 EXPECT_EQ(psu.isPresent(), true);
970 EXPECT_EQ(psu.isFaulted(), true);
971 EXPECT_EQ(psu.hasInputFault(), false);
972 EXPECT_EQ(psu.hasMFRFault(), true);
973 EXPECT_EQ(psu.hasVINUVFault(), false);
974 EXPECT_EQ(psu.hasCommFault(), true);
975 EXPECT_EQ(psu.hasVoutOVFault(), true);
976 EXPECT_EQ(psu.hasIoutOCFault(), true);
977 EXPECT_EQ(psu.hasVoutUVFault(), false);
978 EXPECT_EQ(psu.hasFanFault(), true);
979 EXPECT_EQ(psu.hasTempFault(), true);
980 EXPECT_EQ(psu.hasPgoodFault(), true);
981 EXPECT_EQ(psu.hasPSKillFault(), true);
982 EXPECT_EQ(psu.hasPS12VcsFault(), true);
983 EXPECT_EQ(psu.hasPSCS12VFault(), true);
984
985 // All faults cleared
986 expectations = {0};
987 setPMBusExpectations(mockPMBus, expectations);
988 // READ_VIN back in range.
989 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
990 .Times(1)
991 .WillOnce(Return("206000"));
Matt Spinler0975eaf2022-02-14 15:38:30 -0600992 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
Brandon Wyman82affd92021-11-24 19:12:49 +0000993 psu.analyze();
994 EXPECT_EQ(psu.isPresent(), true);
995 EXPECT_EQ(psu.isFaulted(), false);
996 EXPECT_EQ(psu.hasInputFault(), false);
997 EXPECT_EQ(psu.hasMFRFault(), false);
998 EXPECT_EQ(psu.hasVINUVFault(), false);
999 EXPECT_EQ(psu.hasCommFault(), false);
1000 EXPECT_EQ(psu.hasVoutOVFault(), false);
1001 EXPECT_EQ(psu.hasIoutOCFault(), false);
1002 EXPECT_EQ(psu.hasVoutUVFault(), false);
1003 EXPECT_EQ(psu.hasFanFault(), false);
1004 EXPECT_EQ(psu.hasTempFault(), false);
1005 EXPECT_EQ(psu.hasPgoodFault(), false);
1006 EXPECT_EQ(psu.hasPSKillFault(), false);
1007 EXPECT_EQ(psu.hasPS12VcsFault(), false);
1008 EXPECT_EQ(psu.hasPSCS12VFault(), false);
1009
B. J. Wyman681b2a32021-04-20 22:31:22 +00001010 // TODO: Faults clear on missing/present?
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001011}
1012
1013TEST_F(PowerSupplyTests, UpdateInventory)
1014{
1015 auto bus = sdbusplus::bus::new_default();
Brandon Wyman1d7a7df2020-03-26 10:14:05 -05001016
1017 try
1018 {
Brandon Wymanc3324422022-03-24 20:30:57 +00001019 PowerSupply psu{bus, PSUInventoryPath, 3,
1020 0x68, "ibm-cffps", PSUGPIOLineName};
Brandon Wyman1d7a7df2020-03-26 10:14:05 -05001021 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1022 // If it is not present, I should not be trying to read a string
1023 EXPECT_CALL(mockPMBus, readString(_, _)).Times(0);
1024 psu.updateInventory();
1025 }
1026 catch (...)
1027 {
1028 ADD_FAILURE() << "Should not have caught exception.";
1029 }
1030
1031 try
1032 {
Brandon Wymanc3324422022-03-24 20:30:57 +00001033 PowerSupply psu{bus, PSUInventoryPath, 13,
1034 0x69, "ibm-cffps", PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +00001035 MockedGPIOInterface* mockPresenceGPIO =
1036 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +00001037 // GPIO read return 1 to indicate present.
1038 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
Brandon Wyman1d7a7df2020-03-26 10:14:05 -05001039 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001040 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001041 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1042 // for INPUT_HISTORY will check max_power_out to see if it is
1043 // old/unsupported power supply. Indicate good value, supported.
1044 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1045 .Times(1)
1046 .WillOnce(Return("2000"));
Brandon Wyman391a0692021-12-08 23:28:18 +00001047 // STATUS_WORD 0x0000 is powered on, no faults.
1048 PMBusExpectations expectations;
1049 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001050 // Call to analyze will read voltage, trigger clear faults for 0 to
1051 // within range.
1052 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1053 .Times(1)
1054 .WillOnce(Return("123456"));
Brandon Wyman391a0692021-12-08 23:28:18 +00001055 psu.analyze();
Brandon Wyman1d7a7df2020-03-26 10:14:05 -05001056 EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return(""));
1057 psu.updateInventory();
1058
Brandon Wyman3c530fb2021-04-13 13:13:22 -05001059#if IBM_VPD
Brandon Wyman1d7a7df2020-03-26 10:14:05 -05001060 EXPECT_CALL(mockPMBus, readString(_, _))
1061 .WillOnce(Return("CCIN"))
1062 .WillOnce(Return("PN3456"))
1063 .WillOnce(Return("FN3456"))
1064 .WillOnce(Return("HEADER"))
1065 .WillOnce(Return("SN3456"))
1066 .WillOnce(Return("FW3456"));
Brandon Wyman3c530fb2021-04-13 13:13:22 -05001067#endif
Brandon Wyman1d7a7df2020-03-26 10:14:05 -05001068 psu.updateInventory();
1069 // TODO: D-Bus mocking to verify values stored on D-Bus (???)
1070 }
1071 catch (...)
1072 {
1073 ADD_FAILURE() << "Should not have caught exception.";
1074 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001075}
1076
1077TEST_F(PowerSupplyTests, IsPresent)
1078{
1079 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +00001080
Brandon Wymanc3324422022-03-24 20:30:57 +00001081 PowerSupply psu{bus, PSUInventoryPath, 3,
1082 0x68, "ibm-cffps", PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +00001083 MockedGPIOInterface* mockPresenceGPIO =
1084 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001085 EXPECT_EQ(psu.isPresent(), false);
1086
B. J. Wyman681b2a32021-04-20 22:31:22 +00001087 // Change GPIO read to return 1 to indicate present.
1088 EXPECT_CALL(*mockPresenceGPIO, read()).Times(1).WillOnce(Return(1));
Brandon Wyman391a0692021-12-08 23:28:18 +00001089 // Call to analyze() will update to present, that will trigger updating
1090 // to the correct/latest HWMON directory, in case it changes.
1091 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1092 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001093 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1094 // for INPUT_HISTORY will check max_power_out to see if it is
1095 // old/unsupported power supply. Indicate good value, supported.
1096 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1097 .Times(1)
1098 .WillOnce(Return("2000"));
Brandon Wyman391a0692021-12-08 23:28:18 +00001099 // Call to analyze things will trigger read of STATUS_WORD and READ_VIN.
1100 // Default expectations will be on, no faults.
1101 PMBusExpectations expectations;
1102 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001103 // Give it an input voltage in the 100-volt range.
1104 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1105 .Times(1)
1106 .WillOnce(Return("123456"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001107 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
B. J. Wyman681b2a32021-04-20 22:31:22 +00001108 psu.analyze();
1109 EXPECT_EQ(psu.isPresent(), true);
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001110}
1111
1112TEST_F(PowerSupplyTests, IsFaulted)
1113{
1114 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +00001115
Brandon Wymanc3324422022-03-24 20:30:57 +00001116 PowerSupply psu{bus, PSUInventoryPath, 11,
1117 0x6f, "ibm-cffps", PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +00001118 MockedGPIOInterface* mockPresenceGPIO =
1119 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +00001120 // Always return 1 to indicate present.
1121 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman391a0692021-12-08 23:28:18 +00001122 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
1123 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001124 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1125 // for INPUT_HISTORY will check max_power_out to see if it is
1126 // old/unsupported power supply. Indicate good value, supported.
1127 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1128 .Times(1)
1129 .WillOnce(Return("2000"));
Brandon Wyman391a0692021-12-08 23:28:18 +00001130 // Call to analyze things will trigger read of STATUS_WORD and READ_VIN.
1131 // Default expectations will be on, no faults.
1132 PMBusExpectations expectations;
1133 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001134 // Give it an input voltage in the 100-volt range.
1135 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1136 .Times(1)
1137 .WillOnce(Return("124680"));
B. J. Wyman681b2a32021-04-20 22:31:22 +00001138 psu.analyze();
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001139 EXPECT_EQ(psu.isFaulted(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001140 // STATUS_WORD with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001141 expectations.statusWordValue = 0xFFFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +00001142 // STATUS_INPUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001143 expectations.statusInputValue = 0xFF;
Brandon Wymanf07bc792021-10-12 19:00:35 +00001144 // STATUS_MFR_SPECIFIC with faults bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001145 expectations.statusMFRValue = 0xFF;
Brandon Wyman85c7bf42021-10-19 22:28:48 +00001146 // STATUS_CML with faults bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001147 expectations.statusCMLValue = 0xFF;
Brandon Wyman6710ba22021-10-27 17:39:31 +00001148 // STATUS_VOUT with fault bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001149 expectations.statusVOUTValue = 0xFF;
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001150 // STATUS_IOUT with fault bits on.
1151 expectations.statusIOUTValue = 0xFF;
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001152 // STATUS_FANS_1_2 with bits on.
1153 expectations.statusFans12Value = 0xFF;
Brandon Wyman96893a42021-11-05 19:56:57 +00001154 // STATUS_TEMPERATURE with fault bits on.
1155 expectations.statusTempValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001156 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1157 {
1158 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman4fc191f2022-03-10 23:07:13 +00001159 // Also get another read of READ_VIN, faulted, so not in 100-volt range
Brandon Wymanc2906f42021-12-21 20:14:56 +00001160 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1161 .Times(1)
Brandon Wyman4fc191f2022-03-10 23:07:13 +00001162 .WillOnce(Return("19000"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001163 if (x == DEGLITCH_LIMIT)
1164 {
1165 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1166 }
Brandon Wymanc2906f42021-12-21 20:14:56 +00001167 psu.analyze();
1168 EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT);
1169 }
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001170}
1171
1172TEST_F(PowerSupplyTests, HasInputFault)
1173{
1174 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +00001175
Brandon Wymanc3324422022-03-24 20:30:57 +00001176 PowerSupply psu{bus, PSUInventoryPath, 3,
1177 0x68, "ibm-cffps", PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +00001178 MockedGPIOInterface* mockPresenceGPIO =
1179 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +00001180 // Always return 1 to indicate present.
1181 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001182 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001183 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001184 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1185 // for INPUT_HISTORY will check max_power_out to see if it is
1186 // old/unsupported power supply. Indicate good value, supported.
1187 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1188 .Times(1)
1189 .WillOnce(Return("2000"));
Brandon Wyman8da35c52021-10-28 22:45:08 +00001190 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +00001191 PMBusExpectations expectations;
1192 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001193 // Analyze call will also need good READ_VIN value to check.
1194 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1195 .Times(1)
1196 .WillOnce(Return("201100"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001197 psu.analyze();
1198 EXPECT_EQ(psu.hasInputFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001199 // STATUS_WORD with input fault/warn on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001200 expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001201 // STATUS_INPUT with an input fault bit on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001202 expectations.statusInputValue = 0x80;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001203 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1204 {
1205 setPMBusExpectations(mockPMBus, expectations);
1206 // Analyze call will also need good READ_VIN value to check.
1207 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1208 .Times(1)
1209 .WillOnce(Return("201200"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001210 if (x == DEGLITCH_LIMIT)
1211 {
1212 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1213 }
Brandon Wymanc2906f42021-12-21 20:14:56 +00001214 psu.analyze();
1215 EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT);
1216 }
Brandon Wymanf07bc792021-10-12 19:00:35 +00001217 // STATUS_WORD with no bits on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001218 expectations.statusWordValue = 0;
1219 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001220 // Analyze call will also need good READ_VIN value to check.
1221 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1222 .Times(1)
1223 .WillOnce(Return("201300"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001224 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001225 psu.analyze();
1226 EXPECT_EQ(psu.hasInputFault(), false);
1227}
1228
1229TEST_F(PowerSupplyTests, HasMFRFault)
1230{
1231 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +00001232
Brandon Wymanc3324422022-03-24 20:30:57 +00001233 PowerSupply psu{bus, PSUInventoryPath, 3,
1234 0x68, "ibm-cffps", PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +00001235 MockedGPIOInterface* mockPresenceGPIO =
1236 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +00001237 // Always return 1 to indicate present.
1238 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001239 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001240 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001241 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1242 // for INPUT_HISTORY will check max_power_out to see if it is
1243 // old/unsupported power supply. Indicate good value, supported.
1244 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1245 .Times(1)
1246 .WillOnce(Return("2000"));
Brandon Wymanf07bc792021-10-12 19:00:35 +00001247 // First return STATUS_WORD with no bits on.
Brandon Wyman8da35c52021-10-28 22:45:08 +00001248 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +00001249 PMBusExpectations expectations;
1250 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001251 // Analyze call will also need good READ_VIN value to check.
1252 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1253 .Times(1)
1254 .WillOnce(Return("202100"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001255 psu.analyze();
1256 EXPECT_EQ(psu.hasMFRFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001257 // Next return STATUS_WORD with MFR fault bit on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001258 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001259 // STATUS_MFR_SPEFIC with bit(s) on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001260 expectations.statusMFRValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001261 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1262 {
1263 setPMBusExpectations(mockPMBus, expectations);
1264 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1265 .Times(1)
1266 .WillOnce(Return("202200"));
1267 psu.analyze();
1268 EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT);
1269 }
Brandon Wymanf07bc792021-10-12 19:00:35 +00001270 // Back to no bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +00001271 expectations.statusWordValue = 0;
1272 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001273 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1274 .Times(1)
1275 .WillOnce(Return("202300"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001276 psu.analyze();
1277 EXPECT_EQ(psu.hasMFRFault(), false);
1278}
1279
1280TEST_F(PowerSupplyTests, HasVINUVFault)
1281{
1282 auto bus = sdbusplus::bus::new_default();
B. J. Wyman681b2a32021-04-20 22:31:22 +00001283
Brandon Wymanc3324422022-03-24 20:30:57 +00001284 PowerSupply psu{bus, PSUInventoryPath, 3,
1285 0x68, "ibm-cffps", PSUGPIOLineName};
Adriana Kobylak3ca062a2021-10-20 15:27:23 +00001286 MockedGPIOInterface* mockPresenceGPIO =
1287 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
B. J. Wyman681b2a32021-04-20 22:31:22 +00001288 // Always return 1 to indicate present.
1289 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001290 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001291 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001292 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1293 // for INPUT_HISTORY will check max_power_out to see if it is
1294 // old/unsupported power supply. Indicate good value, supported.
1295 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1296 .Times(1)
1297 .WillOnce(Return("2000"));
Brandon Wyman82affd92021-11-24 19:12:49 +00001298
1299 // Presence change from missing to present will trigger in1_input read in
1300 // an attempt to get CLEAR_FAULTS called. Return value ignored.
1301 // Zero to non-zero voltage, for missing/present change, triggers clear
1302 // faults call again. Return value ignored.
1303 // Fault (low voltage) to not faulted (voltage in range) triggers clear
1304 // faults call a third time.
1305
Brandon Wyman8da35c52021-10-28 22:45:08 +00001306 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +00001307 PMBusExpectations expectations;
1308 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001309 // Analyze call will also need good READ_VIN value to check.
1310 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1311 .Times(1)
1312 .WillOnce(Return("201100"));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001313 psu.analyze();
1314 EXPECT_EQ(psu.hasVINUVFault(), false);
Brandon Wymanf07bc792021-10-12 19:00:35 +00001315 // Turn fault on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001316 expectations.statusWordValue = (status_word::VIN_UV_FAULT);
Brandon Wyman85c7bf42021-10-19 22:28:48 +00001317 // Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by
1318 // Figure 16, and assume bits on in STATUS_INPUT.
Brandon Wymanb654c612021-11-05 23:24:51 +00001319 expectations.statusInputValue = 0x18;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001320 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1321 {
1322 setPMBusExpectations(mockPMBus, expectations);
1323 // If there is a VIN_UV fault, fake reading voltage of less than 20V
1324 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1325 .Times(1)
1326 .WillOnce(Return("19876"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001327 if (x == DEGLITCH_LIMIT)
1328 {
1329 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1330 }
Brandon Wymanc2906f42021-12-21 20:14:56 +00001331 psu.analyze();
1332 EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT);
1333 }
Brandon Wymanf07bc792021-10-12 19:00:35 +00001334 // Back to no fault bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +00001335 expectations.statusWordValue = 0;
1336 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001337 // Updates now result in clearing faults if read voltage goes from below the
1338 // minimum, to within a valid range.
1339 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1340 .Times(1)
1341 .WillOnce(Return("201300"));
Brandon Wyman3225a452022-03-18 18:51:49 +00001342 // Went from below minimum to within range, expect clearVinUVFault().
1343 EXPECT_CALL(mockPMBus, read("in1_lcrit_alarm", _, _))
1344 .Times(1)
1345 .WillOnce(Return(1));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001346 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001347 psu.analyze();
1348 EXPECT_EQ(psu.hasVINUVFault(), false);
1349}
Brandon Wyman6710ba22021-10-27 17:39:31 +00001350
1351TEST_F(PowerSupplyTests, HasVoutOVFault)
1352{
1353 auto bus = sdbusplus::bus::new_default();
1354
Brandon Wymanc3324422022-03-24 20:30:57 +00001355 PowerSupply psu{bus, PSUInventoryPath, 3,
1356 0x69, "ibm-cffps", PSUGPIOLineName};
Brandon Wyman6710ba22021-10-27 17:39:31 +00001357 MockedGPIOInterface* mockPresenceGPIO =
1358 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1359 // Always return 1 to indicate present.
1360 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman6710ba22021-10-27 17:39:31 +00001361 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001362 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001363 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1364 // for INPUT_HISTORY will check max_power_out to see if it is
1365 // old/unsupported power supply. Indicate good value, supported.
1366 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1367 .Times(1)
1368 .WillOnce(Return("2000"));
Brandon Wyman6710ba22021-10-27 17:39:31 +00001369 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wymanb654c612021-11-05 23:24:51 +00001370 PMBusExpectations expectations;
1371 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001372 // Call to analyze will trigger read of "in1_input" to check voltage.
1373 // Initial value would be 0, so this read updates it to non-zero.
1374 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1375 .Times(1)
1376 .WillOnce(Return("202100"));
Brandon Wyman6710ba22021-10-27 17:39:31 +00001377 psu.analyze();
1378 EXPECT_EQ(psu.hasVoutOVFault(), false);
1379 // Turn fault on.
Brandon Wymanb654c612021-11-05 23:24:51 +00001380 expectations.statusWordValue = (status_word::VOUT_OV_FAULT);
Brandon Wyman6710ba22021-10-27 17:39:31 +00001381 // STATUS_VOUT fault bit(s)
Brandon Wymanb654c612021-11-05 23:24:51 +00001382 expectations.statusVOUTValue = 0x80;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001383 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1384 {
1385 setPMBusExpectations(mockPMBus, expectations);
1386 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1387 .Times(1)
1388 .WillOnce(Return("202200"));
1389 psu.analyze();
1390 EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT);
1391 }
Brandon Wyman6710ba22021-10-27 17:39:31 +00001392 // Back to no fault bits on in STATUS_WORD
Brandon Wymanb654c612021-11-05 23:24:51 +00001393 expectations.statusWordValue = 0;
1394 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001395 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1396 .Times(1)
1397 .WillOnce(Return("202300"));
Brandon Wyman6710ba22021-10-27 17:39:31 +00001398 psu.analyze();
1399 EXPECT_EQ(psu.hasVoutOVFault(), false);
1400}
Brandon Wyman96893a42021-11-05 19:56:57 +00001401
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001402TEST_F(PowerSupplyTests, HasIoutOCFault)
1403{
1404 auto bus = sdbusplus::bus::new_default();
1405
Brandon Wymanc3324422022-03-24 20:30:57 +00001406 PowerSupply psu{bus, PSUInventoryPath, 3,
1407 0x6d, "ibm-cffps", PSUGPIOLineName};
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001408 MockedGPIOInterface* mockPresenceGPIO =
1409 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1410 // Always return 1 to indicate present.
1411 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001412 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001413 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001414 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1415 // for INPUT_HISTORY will check max_power_out to see if it is
1416 // old/unsupported power supply. Indicate good value, supported.
1417 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1418 .Times(1)
1419 .WillOnce(Return("2000"));
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001420 // STATUS_WORD 0x0000 is powered on, no faults.
1421 PMBusExpectations expectations;
1422 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001423 // Call to analyze will trigger read of "in1_input" to check voltage.
1424 // Initial value would be 0, so this read updates it to non-zero.
1425 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1426 .Times(1)
1427 .WillOnce(Return("203100"));
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001428 psu.analyze();
1429 EXPECT_EQ(psu.hasIoutOCFault(), false);
1430 // Turn fault on.
1431 expectations.statusWordValue = status_word::IOUT_OC_FAULT;
1432 // STATUS_IOUT fault bit(s)
1433 expectations.statusIOUTValue = 0x88;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001434 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1435 {
1436 setPMBusExpectations(mockPMBus, expectations);
1437 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1438 .Times(1)
1439 .WillOnce(Return("203200"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001440 if (x == DEGLITCH_LIMIT)
1441 {
1442 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1443 }
Brandon Wymanc2906f42021-12-21 20:14:56 +00001444 psu.analyze();
1445 EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT);
1446 }
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001447 // Back to no fault bits on in STATUS_WORD
1448 expectations.statusWordValue = 0;
1449 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001450 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1451 .Times(1)
1452 .WillOnce(Return("203300"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001453 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
Brandon Wymanb10b3be2021-11-09 22:12:15 +00001454 psu.analyze();
1455 EXPECT_EQ(psu.hasIoutOCFault(), false);
1456}
1457
Brandon Wyman2cf46942021-10-28 19:09:16 +00001458TEST_F(PowerSupplyTests, HasVoutUVFault)
1459{
1460 auto bus = sdbusplus::bus::new_default();
1461
Brandon Wymanc3324422022-03-24 20:30:57 +00001462 PowerSupply psu{bus, PSUInventoryPath, 3,
1463 0x6a, "ibm-cffps", PSUGPIOLineName};
Brandon Wyman2cf46942021-10-28 19:09:16 +00001464 MockedGPIOInterface* mockPresenceGPIO =
1465 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1466 // Always return 1 to indicate present.
1467 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman2cf46942021-10-28 19:09:16 +00001468 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001469 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001470 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1471 // for INPUT_HISTORY will check max_power_out to see if it is
1472 // old/unsupported power supply. Indicate good value, supported.
1473 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1474 .Times(1)
1475 .WillOnce(Return("2000"));
Brandon Wyman391a0692021-12-08 23:28:18 +00001476 // STATUS_WORD 0x0000 is powered on, no faults.
Brandon Wyman2cf46942021-10-28 19:09:16 +00001477 PMBusExpectations expectations;
1478 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001479 // Call to analyze will trigger read of "in1_input" to check voltage.
1480 // Initial value would be 0, so this read updates it to non-zero.
1481 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1482 .Times(1)
1483 .WillOnce(Return("204100"));
Brandon Wyman2cf46942021-10-28 19:09:16 +00001484 psu.analyze();
1485 EXPECT_EQ(psu.hasVoutUVFault(), false);
1486 // Turn fault on.
1487 expectations.statusWordValue = (status_word::VOUT_FAULT);
1488 // STATUS_VOUT fault bit(s)
1489 expectations.statusVOUTValue = 0x30;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001490 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1491 {
1492 setPMBusExpectations(mockPMBus, expectations);
1493 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1494 .Times(1)
1495 .WillOnce(Return("204200"));
1496 psu.analyze();
1497 EXPECT_EQ(psu.hasVoutUVFault(), x >= DEGLITCH_LIMIT);
1498 }
Brandon Wyman2cf46942021-10-28 19:09:16 +00001499 // Back to no fault bits on in STATUS_WORD
1500 expectations.statusWordValue = 0;
1501 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001502 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1503 .Times(1)
1504 .WillOnce(Return("204300"));
Brandon Wyman2cf46942021-10-28 19:09:16 +00001505 psu.analyze();
1506 EXPECT_EQ(psu.hasVoutUVFault(), false);
1507}
1508
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001509TEST_F(PowerSupplyTests, HasFanFault)
1510{
1511 auto bus = sdbusplus::bus::new_default();
1512
Matt Spinler0975eaf2022-02-14 15:38:30 -06001513 EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1);
1514 EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0);
1515
Brandon Wymanc3324422022-03-24 20:30:57 +00001516 PowerSupply psu{bus, PSUInventoryPath, 3,
1517 0x6d, "ibm-cffps", PSUGPIOLineName};
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001518 MockedGPIOInterface* mockPresenceGPIO =
1519 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1520 // Always return 1 to indicate present.
1521 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001522 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001523 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001524 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1525 // for INPUT_HISTORY will check max_power_out to see if it is
1526 // old/unsupported power supply. Indicate good value, supported.
1527 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1528 .Times(1)
1529 .WillOnce(Return("2000"));
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001530 // STATUS_WORD 0x0000 is powered on, no faults.
1531 PMBusExpectations expectations;
1532 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001533 // Call to analyze will trigger read of "in1_input" to check voltage.
1534 // Initial value would be 0, so this read updates it to non-zero.
1535 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1536 .Times(1)
1537 .WillOnce(Return("205100"));
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001538 psu.analyze();
1539 EXPECT_EQ(psu.hasFanFault(), false);
1540 // Turn fault on.
1541 expectations.statusWordValue = (status_word::FAN_FAULT);
1542 // STATUS_FANS_1_2 fault bit on (Fan 1 Fault)
1543 expectations.statusFans12Value = 0x80;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001544 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1545 {
1546 setPMBusExpectations(mockPMBus, expectations);
1547 // Call to analyze will trigger read of "in1_input" to check voltage.
1548 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1549 .Times(1)
1550 .WillOnce(Return("205200"));
1551 psu.analyze();
1552 EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT);
1553 }
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001554 // Back to no fault bits on in STATUS_WORD
1555 expectations.statusWordValue = 0;
1556 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001557 // Call to analyze will trigger read of "in1_input" to check voltage.
1558 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1559 .Times(1)
1560 .WillOnce(Return("205300"));
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +00001561 psu.analyze();
1562 EXPECT_EQ(psu.hasFanFault(), false);
1563}
1564
Brandon Wyman96893a42021-11-05 19:56:57 +00001565TEST_F(PowerSupplyTests, HasTempFault)
1566{
1567 auto bus = sdbusplus::bus::new_default();
1568
Matt Spinler0975eaf2022-02-14 15:38:30 -06001569 EXPECT_CALL(mockedUtil, setAvailable(_, _, true)).Times(1);
1570 EXPECT_CALL(mockedUtil, setAvailable(_, _, false)).Times(0);
1571
Brandon Wymanc3324422022-03-24 20:30:57 +00001572 PowerSupply psu{bus, PSUInventoryPath, 3,
1573 0x6a, "ibm-cffps", PSUGPIOLineName};
Brandon Wyman96893a42021-11-05 19:56:57 +00001574 MockedGPIOInterface* mockPresenceGPIO =
1575 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1576 // Always return 1 to indicate present.
1577 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman96893a42021-11-05 19:56:57 +00001578 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001579 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001580 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1581 // for INPUT_HISTORY will check max_power_out to see if it is
1582 // old/unsupported power supply. Indicate good value, supported.
1583 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1584 .Times(1)
1585 .WillOnce(Return("2000"));
Brandon Wyman96893a42021-11-05 19:56:57 +00001586 // STATUS_WORD 0x0000 is powered on, no faults.
1587 PMBusExpectations expectations;
1588 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001589 // Call to analyze will trigger read of "in1_input" to check voltage.
1590 // Initial value would be 0, so this read updates it to non-zero.
1591 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1592 .Times(1)
1593 .WillOnce(Return("206100"));
Brandon Wyman96893a42021-11-05 19:56:57 +00001594 psu.analyze();
1595 EXPECT_EQ(psu.hasTempFault(), false);
1596 // Turn fault on.
1597 expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
1598 // STATUS_TEMPERATURE fault bit on (OT Fault)
1599 expectations.statusTempValue = 0x80;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001600 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1601 {
1602 setPMBusExpectations(mockPMBus, expectations);
1603 // Call to analyze will trigger read of "in1_input" to check voltage.
1604 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1605 .Times(1)
1606 .WillOnce(Return("206200"));
1607 psu.analyze();
1608 EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT);
1609 }
Brandon Wyman96893a42021-11-05 19:56:57 +00001610 // Back to no fault bits on in STATUS_WORD
1611 expectations.statusWordValue = 0;
1612 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001613 // Call to analyze will trigger read of "in1_input" to check voltage.
1614 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1615 .Times(1)
1616 .WillOnce(Return("206300"));
Brandon Wyman96893a42021-11-05 19:56:57 +00001617 psu.analyze();
1618 EXPECT_EQ(psu.hasTempFault(), false);
1619}
Brandon Wyman2916ea52021-11-06 03:31:18 +00001620
1621TEST_F(PowerSupplyTests, HasPgoodFault)
1622{
1623 auto bus = sdbusplus::bus::new_default();
1624
Brandon Wymanc3324422022-03-24 20:30:57 +00001625 PowerSupply psu{bus, PSUInventoryPath, 3,
1626 0x6b, "ibm-cffps", PSUGPIOLineName};
Brandon Wyman2916ea52021-11-06 03:31:18 +00001627 MockedGPIOInterface* mockPresenceGPIO =
1628 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1629 // Always return 1 to indicate present.
1630 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001631 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman391a0692021-12-08 23:28:18 +00001632 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001633 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1634 // for INPUT_HISTORY will check max_power_out to see if it is
1635 // old/unsupported power supply. Indicate good value, supported.
1636 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1637 .Times(1)
1638 .WillOnce(Return("2000"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001639 // STATUS_WORD 0x0000 is powered on, no faults.
1640 PMBusExpectations expectations;
1641 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001642 // Call to analyze will trigger read of "in1_input" to check voltage.
1643 // Initial value would be 0, so this read updates it to non-zero.
1644 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1645 .Times(1)
1646 .WillOnce(Return("207100"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001647 psu.analyze();
1648 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman391a0692021-12-08 23:28:18 +00001649 // Setup another expectation of no faults.
1650 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001651 // Call to analyze will trigger read of "in1_input" to check voltage.
1652 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1653 .Times(1)
1654 .WillOnce(Return("207200"));
1655 psu.analyze();
1656 EXPECT_EQ(psu.hasPgoodFault(), false);
1657 // Setup another expectation of no faults.
1658 setPMBusExpectations(mockPMBus, expectations);
1659 // Call to analyze will trigger read of "in1_input" to check voltage.
1660 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1661 .Times(1)
1662 .WillOnce(Return("207300"));
Brandon Wyman391a0692021-12-08 23:28:18 +00001663 psu.analyze();
1664 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman2916ea52021-11-06 03:31:18 +00001665 // Turn PGOOD# off (fault on).
1666 expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED);
1667 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001668 // Call to analyze will trigger read of "in1_input" to check voltage.
1669 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1670 .Times(1)
1671 .WillOnce(Return("207400"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001672 psu.analyze();
Brandon Wyman06ca4592021-12-06 22:52:23 +00001673 // Expect false until reaches DEGLITCH_LIMIT
1674 EXPECT_EQ(psu.hasPgoodFault(), false);
1675 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001676 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1677 .Times(1)
1678 .WillOnce(Return("207500"));
Brandon Wyman06ca4592021-12-06 22:52:23 +00001679 psu.analyze();
1680 // Expect false until reaches DEGLITCH_LIMIT
1681 EXPECT_EQ(psu.hasPgoodFault(), false);
1682 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001683 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1684 .Times(1)
1685 .WillOnce(Return("207600"));
Brandon Wyman06ca4592021-12-06 22:52:23 +00001686 psu.analyze();
1687 // DEGLITCH_LIMIT reached, expect true.
Brandon Wyman2916ea52021-11-06 03:31:18 +00001688 EXPECT_EQ(psu.hasPgoodFault(), true);
1689 // Back to no fault bits on in STATUS_WORD
1690 expectations.statusWordValue = 0;
1691 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001692 // Call to analyze will trigger read of "in1_input" to check voltage.
1693 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1694 .Times(1)
1695 .WillOnce(Return("207700"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001696 psu.analyze();
1697 EXPECT_EQ(psu.hasPgoodFault(), false);
Brandon Wyman82affd92021-11-24 19:12:49 +00001698
Brandon Wyman2916ea52021-11-06 03:31:18 +00001699 // Turn OFF bit on
1700 expectations.statusWordValue = (status_word::UNIT_IS_OFF);
1701 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001702 // Call to analyze will trigger read of "in1_input" to check voltage.
1703 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1704 .Times(1)
1705 .WillOnce(Return("208100"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001706 psu.analyze();
Brandon Wyman06ca4592021-12-06 22:52:23 +00001707 EXPECT_EQ(psu.hasPgoodFault(), false);
1708 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001709 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1710 .Times(1)
1711 .WillOnce(Return("208200"));
Brandon Wyman06ca4592021-12-06 22:52:23 +00001712 psu.analyze();
1713 EXPECT_EQ(psu.hasPgoodFault(), false);
1714 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001715 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1716 .Times(1)
1717 .WillOnce(Return("208300"));
Brandon Wyman06ca4592021-12-06 22:52:23 +00001718 psu.analyze();
Brandon Wyman2916ea52021-11-06 03:31:18 +00001719 EXPECT_EQ(psu.hasPgoodFault(), true);
1720 // Back to no fault bits on in STATUS_WORD
1721 expectations.statusWordValue = 0;
1722 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001723 // Call to analyze will trigger read of "in1_input" to check voltage.
1724 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1725 .Times(1)
1726 .WillOnce(Return("208400"));
Brandon Wyman2916ea52021-11-06 03:31:18 +00001727 psu.analyze();
1728 EXPECT_EQ(psu.hasPgoodFault(), false);
1729}
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001730
1731TEST_F(PowerSupplyTests, HasPSKillFault)
1732{
1733 auto bus = sdbusplus::bus::new_default();
Brandon Wymanc3324422022-03-24 20:30:57 +00001734 PowerSupply psu{bus, PSUInventoryPath, 4,
1735 0x6d, "ibm-cffps", PSUGPIOLineName};
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001736 MockedGPIOInterface* mockPresenceGPIO =
1737 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1738 // Always return 1 to indicate present.
1739 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001740 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman82affd92021-11-24 19:12:49 +00001741 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001742 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1743 // for INPUT_HISTORY will check max_power_out to see if it is
1744 // old/unsupported power supply. Indicate good value, supported.
1745 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1746 .Times(1)
1747 .WillOnce(Return("2000"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001748 // STATUS_WORD 0x0000 is powered on, no faults.
1749 PMBusExpectations expectations;
1750 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001751 // Call to analyze will trigger read of "in1_input" to check voltage.
1752 // Initial value would be 0, so this read updates it to non-zero.
1753 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1754 .Times(1)
1755 .WillOnce(Return("208100"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001756 psu.analyze();
1757 EXPECT_EQ(psu.hasPSKillFault(), false);
1758 // Next return STATUS_WORD with MFR fault bit on.
1759 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1760 // STATUS_MFR_SPEFIC with bit(s) on.
1761 expectations.statusMFRValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001762
1763 // Deglitching faults, false until read the fault bits on up to the limit.
1764 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1765 {
1766 setPMBusExpectations(mockPMBus, expectations);
1767 // Call to analyze will trigger read of "in1_input" to check voltage.
1768 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1769 .Times(1)
1770 .WillOnce(Return("208200"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001771 if (x == DEGLITCH_LIMIT)
1772 {
1773 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1774 }
Brandon Wymanc2906f42021-12-21 20:14:56 +00001775 psu.analyze();
1776 EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT);
1777 }
1778
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001779 // Back to no bits on in STATUS_WORD
1780 expectations.statusWordValue = 0;
1781 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001782 // Call to analyze will trigger read of "in1_input" to check voltage.
1783 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1784 .Times(1)
1785 .WillOnce(Return("208300"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001786 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001787 psu.analyze();
1788 EXPECT_EQ(psu.hasPSKillFault(), false);
1789 // Next return STATUS_WORD with MFR fault bit on.
1790 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1791 // STATUS_MFR_SPEFIC with bit 4 on.
1792 expectations.statusMFRValue = 0x10;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001793
1794 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1795 {
1796 setPMBusExpectations(mockPMBus, expectations);
1797 // Call to analyze will trigger read of "in1_input" to check voltage.
1798 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1799 .Times(1)
1800 .WillOnce(Return("208400"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001801 if (x == DEGLITCH_LIMIT)
1802 {
1803 EXPECT_CALL(mockedUtil, setAvailable(_, _, false));
1804 }
Brandon Wymanc2906f42021-12-21 20:14:56 +00001805 psu.analyze();
1806 EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT);
1807 }
1808
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001809 // Back to no bits on in STATUS_WORD
1810 expectations.statusWordValue = 0;
1811 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001812 // Call to analyze will trigger read of "in1_input" to check voltage.
1813 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1814 .Times(1)
1815 .WillOnce(Return("208500"));
Matt Spinler0975eaf2022-02-14 15:38:30 -06001816 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001817 psu.analyze();
1818 EXPECT_EQ(psu.hasPSKillFault(), false);
1819}
1820
1821TEST_F(PowerSupplyTests, HasPS12VcsFault)
1822{
1823 auto bus = sdbusplus::bus::new_default();
Brandon Wymanc3324422022-03-24 20:30:57 +00001824 PowerSupply psu{bus, PSUInventoryPath, 5,
1825 0x6e, "ibm-cffps", PSUGPIOLineName};
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001826 MockedGPIOInterface* mockPresenceGPIO =
1827 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1828 // Always return 1 to indicate present.
1829 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001830 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman82affd92021-11-24 19:12:49 +00001831 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001832 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1833 // for INPUT_HISTORY will check max_power_out to see if it is
1834 // old/unsupported power supply. Indicate good value, supported.
1835 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1836 .Times(1)
1837 .WillOnce(Return("2000"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001838 // STATUS_WORD 0x0000 is powered on, no faults.
1839 PMBusExpectations expectations;
1840 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001841 // Call to analyze will trigger read of "in1_input" to check voltage.
1842 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1843 .Times(1)
1844 .WillOnce(Return("209100"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001845 psu.analyze();
1846 EXPECT_EQ(psu.hasPS12VcsFault(), false);
1847 // Next return STATUS_WORD with MFR fault bit on.
1848 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1849 // STATUS_MFR_SPEFIC with bit(s) on.
1850 expectations.statusMFRValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001851
1852 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1853 {
1854 setPMBusExpectations(mockPMBus, expectations);
1855 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1856 .Times(1)
1857 .WillOnce(Return("209200"));
1858 psu.analyze();
1859 EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
1860 }
1861
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001862 // Back to no bits on in STATUS_WORD
1863 expectations.statusWordValue = 0;
1864 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001865 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1866 .Times(1)
1867 .WillOnce(Return("209300"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001868 psu.analyze();
1869 EXPECT_EQ(psu.hasPS12VcsFault(), false);
1870 // Next return STATUS_WORD with MFR fault bit on.
1871 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1872 // STATUS_MFR_SPEFIC with bit 6 on.
1873 expectations.statusMFRValue = 0x40;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001874
1875 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1876 {
1877 setPMBusExpectations(mockPMBus, expectations);
1878 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1879 .Times(1)
1880 .WillOnce(Return("209400"));
1881 psu.analyze();
1882 EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
1883 }
1884
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001885 // Back to no bits on in STATUS_WORD
1886 expectations.statusWordValue = 0;
1887 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001888 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1889 .Times(1)
1890 .WillOnce(Return("209500"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001891 psu.analyze();
1892 EXPECT_EQ(psu.hasPS12VcsFault(), false);
1893}
1894
1895TEST_F(PowerSupplyTests, HasPSCS12VFault)
1896{
1897 auto bus = sdbusplus::bus::new_default();
Brandon Wymanc3324422022-03-24 20:30:57 +00001898 PowerSupply psu{bus, PSUInventoryPath, 6,
1899 0x6f, "ibm-cffps", PSUGPIOLineName};
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001900 MockedGPIOInterface* mockPresenceGPIO =
1901 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
1902 // Always return 1 to indicate present.
1903 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001904 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wyman82affd92021-11-24 19:12:49 +00001905 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00001906 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1907 // for INPUT_HISTORY will check max_power_out to see if it is
1908 // old/unsupported power supply. Indicate good value, supported.
1909 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1910 .Times(1)
1911 .WillOnce(Return("2000"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001912 // STATUS_WORD 0x0000 is powered on, no faults.
1913 PMBusExpectations expectations;
1914 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001915 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1916 .Times(1)
1917 .WillOnce(Return("209100"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001918 psu.analyze();
1919 EXPECT_EQ(psu.hasPSCS12VFault(), false);
1920 // Next return STATUS_WORD with MFR fault bit on.
1921 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1922 // STATUS_MFR_SPEFIC with bit(s) on.
1923 expectations.statusMFRValue = 0xFF;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001924
1925 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1926 {
1927 setPMBusExpectations(mockPMBus, expectations);
1928 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1929 .Times(1)
1930 .WillOnce(Return("209200"));
1931 psu.analyze();
1932 EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
1933 }
1934
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001935 // Back to no bits on in STATUS_WORD
1936 expectations.statusWordValue = 0;
1937 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001938 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1939 .Times(1)
1940 .WillOnce(Return("209300"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001941 psu.analyze();
1942 EXPECT_EQ(psu.hasPSCS12VFault(), false);
1943 // Next return STATUS_WORD with MFR fault bit on.
1944 expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
1945 // STATUS_MFR_SPEFIC with bit 7 on.
1946 expectations.statusMFRValue = 0x80;
Brandon Wymanc2906f42021-12-21 20:14:56 +00001947
1948 for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
1949 {
1950 setPMBusExpectations(mockPMBus, expectations);
1951 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1952 .Times(1)
1953 .WillOnce(Return("209400"));
1954 psu.analyze();
1955 EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
1956 }
1957
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001958 // Back to no bits on in STATUS_WORD
1959 expectations.statusWordValue = 0;
1960 setPMBusExpectations(mockPMBus, expectations);
Brandon Wyman82affd92021-11-24 19:12:49 +00001961 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1962 .Times(1)
1963 .WillOnce(Return("209500"));
Brandon Wyman39ea02b2021-11-23 23:22:23 +00001964 psu.analyze();
1965 EXPECT_EQ(psu.hasPSCS12VFault(), false);
1966}
Brandon Wymanc3324422022-03-24 20:30:57 +00001967
1968TEST_F(PowerSupplyTests, SetupInputHistory)
1969{
1970 auto bus = sdbusplus::bus::new_default();
1971 {
1972 PowerSupply psu{bus, PSUInventoryPath, 6,
1973 0x6f, "ibm-cffps", PSUGPIOLineName};
1974 // Defaults to not present due to constructor and mock ordering.
1975 psu.setupInputHistory();
1976 EXPECT_EQ(psu.hasInputHistory(), false);
1977 MockedGPIOInterface* mockPresenceGPIO =
1978 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wymanae35ac52022-05-23 22:33:40 +00001979 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wymanc3324422022-03-24 20:30:57 +00001980 // Always return 1 to indicate present.
1981 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wymanae35ac52022-05-23 22:33:40 +00001982 setMissingToPresentExpects(mockPMBus, mockedUtil);
1983 PMBusExpectations expectations;
1984 setPMBusExpectations(mockPMBus, expectations);
1985 // After reading STATUS_WORD, etc., there will be a READ_VIN check.
1986 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
1987 .Times(1)
1988 .WillOnce(Return("206000"));
1989 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
1990 // for INPUT_HISTORY will check max_power_out to see if it is
1991 // old/unsupported power supply. Indicate good value, supported.
1992 /// Also called when I redo setupInputHistory().
1993 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
1994 .Times(2)
1995 .WillRepeatedly(Return("2000"));
1996 // Call to analyze() and above expectations to get missing/present and
1997 // good status.
Brandon Wymanc3324422022-03-24 20:30:57 +00001998 psu.analyze();
1999 psu.setupInputHistory();
2000 EXPECT_EQ(psu.hasInputHistory(), true);
2001 }
2002 {
Brandon Wymanae35ac52022-05-23 22:33:40 +00002003 // Workaround - Disable INPUT_HISTORY collection if 1400W
2004 PowerSupply psu{bus, PSUInventoryPath, 3,
2005 0x68, "ibm-cffps", PSUGPIOLineName};
2006 // Defaults to not present due to constructor and mock ordering.
2007 psu.setupInputHistory();
2008 EXPECT_EQ(psu.hasInputHistory(), false);
2009 MockedGPIOInterface* mockPresenceGPIO =
2010 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
2011 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
2012 // Always return 1 to indicate present.
2013 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
2014 setMissingToPresentExpects(mockPMBus, mockedUtil);
2015 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
2016 // for INPUT_HISTORY will check max_power_out to see if it is
2017 // old/unsupported power supply. Indicate 1400W IBM value, unsupported.
2018 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
2019 .Times(2)
2020 .WillRepeatedly(Return("30725"));
2021 PMBusExpectations expectations;
2022 setPMBusExpectations(mockPMBus, expectations);
2023 // After reading STATUS_WORD, etc., there will be a READ_VIN check.
2024 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
2025 .Times(1)
2026 .WillOnce(Return("206000"));
2027 // Call to analyze() and above expectations to get missing/present and
2028 // good status.
2029 psu.analyze();
2030 psu.setupInputHistory();
2031 // After updating to present, and retrying setup, expect ibm-cffps with
2032 // 1400W to still not support INPUT_HISTORY.
2033 EXPECT_EQ(psu.hasInputHistory(), false);
2034 }
2035 {
Brandon Wymanc3324422022-03-24 20:30:57 +00002036 PowerSupply psu{bus, PSUInventoryPath, 11,
2037 0x58, "inspur-ipsps", PSUGPIOLineName};
2038 // Defaults to not present due to constructor and mock ordering.
2039 psu.setupInputHistory();
2040 EXPECT_EQ(psu.hasInputHistory(), false);
2041 MockedGPIOInterface* mockPresenceGPIO =
2042 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
Brandon Wymanae35ac52022-05-23 22:33:40 +00002043 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
Brandon Wymanc3324422022-03-24 20:30:57 +00002044 // Always return 1 to indicate present.
2045 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
Brandon Wymanae35ac52022-05-23 22:33:40 +00002046 setMissingToPresentExpects(mockPMBus, mockedUtil);
2047 PMBusExpectations expectations;
2048 setPMBusExpectations(mockPMBus, expectations);
2049 // After reading STATUS_WORD, etc., there will be a READ_VIN check.
2050 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
2051 .Times(1)
2052 .WillOnce(Return("206000"));
2053 // Call to analyze() and above expectations to get missing/present and
2054 // good status.
Brandon Wymanc3324422022-03-24 20:30:57 +00002055 psu.analyze();
2056 psu.setupInputHistory();
2057 // After updating to present, and retrying setup, expect inspur-ipsps to
2058 // still not support INPUT_HISTORY.
2059 EXPECT_EQ(psu.hasInputHistory(), false);
2060 }
2061}
2062
2063TEST_F(PowerSupplyTests, UpdateHistory)
2064{
2065 auto bus = sdbusplus::bus::new_default();
2066 PowerSupply psu{bus, PSUInventoryPath, 7,
2067 0x6e, "ibm-cffps", PSUGPIOLineName};
2068 EXPECT_EQ(psu.hasInputHistory(), false);
2069 EXPECT_EQ(psu.getNumInputHistoryRecords(), 0);
2070 MockedGPIOInterface* mockPresenceGPIO =
2071 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
2072 // Always return 1 to indicate present.
2073 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
2074 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
2075 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00002076 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
2077 // for INPUT_HISTORY will check max_power_out to see if it is
2078 // old/unsupported power supply. Indicate good value, supported.
2079 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
2080 .Times(1)
2081 .WillOnce(Return("2000"));
Brandon Wymanc3324422022-03-24 20:30:57 +00002082 PMBusExpectations expectations;
2083 setPMBusExpectations(mockPMBus, expectations);
2084 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
2085 .Times(6)
2086 .WillRepeatedly(Return("205000"));
2087 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
2088 // First read after missing/present will have no data.
2089 std::vector<uint8_t> emptyHistory{};
2090 // Second read, after about 30 seconds, should have a record. 5-bytes.
2091 // Sequence Number: 0x00, Average: 0x50 0xf3 (212), Maximum: 0x54 0xf3 (213)
2092 std::vector<uint8_t> firstHistory{0x00, 0x50, 0xf3, 0x54, 0xf3};
2093 // Third read, after about 60 seconds, should have two records, 10-bytes,
2094 // but only reading 5 bytes, so make sure new/next sequence number
2095 std::vector<uint8_t> secondHistory{0x01, 0x54, 0xf3, 0x58, 0xf3};
2096 // Fourth read, 3rd sequence number (0x02).
2097 std::vector<uint8_t> thirdHistory{0x02, 0x54, 0xf3, 0x58, 0xf3};
2098 // Fifth read, out of sequence, clear and insert this one?
2099 std::vector<uint8_t> outseqHistory{0xff, 0x5c, 0xf3, 0x60, 0xf3};
2100 EXPECT_CALL(
2101 mockPMBus,
2102 readBinary(INPUT_HISTORY, Type::HwmonDeviceDebug,
2103 phosphor::power::history::RecordManager::RAW_RECORD_SIZE))
2104 .Times(6)
2105 .WillOnce(Return(emptyHistory))
2106 .WillOnce(Return(firstHistory))
2107 .WillOnce(Return(secondHistory))
2108 .WillOnce(Return(thirdHistory))
2109 .WillOnce(Return(outseqHistory))
2110 .WillOnce(Return(emptyHistory));
2111 // Calling analyze will update the presence, which will setup the input
2112 // history if the power supply went from missing to present.
2113 psu.analyze();
2114 // The ibm-cffps power supply should support input history
2115 EXPECT_EQ(psu.hasInputHistory(), true);
2116 // Usually should have empty buffer right after missing to present.
2117 // Faked that out above with mocked readBinary with emptyHistory data.
2118 EXPECT_EQ(psu.getNumInputHistoryRecords(), 0);
2119 // Second run through...
2120 setPMBusExpectations(mockPMBus, expectations);
2121 psu.analyze();
2122 EXPECT_EQ(psu.hasInputHistory(), true);
2123 EXPECT_EQ(psu.getNumInputHistoryRecords(), 1);
2124 // Third run through
2125 setPMBusExpectations(mockPMBus, expectations);
2126 psu.analyze();
2127 EXPECT_EQ(psu.hasInputHistory(), true);
2128 EXPECT_EQ(psu.getNumInputHistoryRecords(), 2);
2129 // Fourth run through. Up to 3 records now?
2130 setPMBusExpectations(mockPMBus, expectations);
2131 psu.analyze();
2132 EXPECT_EQ(psu.hasInputHistory(), true);
2133 EXPECT_EQ(psu.getNumInputHistoryRecords(), 3);
2134 // Out of sequencer, reset, insert new one.
2135 setPMBusExpectations(mockPMBus, expectations);
2136 psu.analyze();
2137 EXPECT_EQ(psu.hasInputHistory(), true);
2138 EXPECT_EQ(psu.getNumInputHistoryRecords(), 1);
2139 // Empty one after last one good. Reset/clear.
2140 setPMBusExpectations(mockPMBus, expectations);
2141 psu.analyze();
2142 EXPECT_EQ(psu.hasInputHistory(), true);
2143 EXPECT_EQ(psu.getNumInputHistoryRecords(), 0);
2144}
Brandon Wyman18a24d92022-04-19 22:48:34 +00002145
2146TEST_F(PowerSupplyTests, IsSyncHistoryRequired)
2147{
2148 auto bus = sdbusplus::bus::new_default();
2149 PowerSupply psu{bus, PSUInventoryPath, 8,
2150 0x6f, "ibm-cffps", PSUGPIOLineName};
2151 EXPECT_EQ(psu.hasInputHistory(), false);
2152 EXPECT_EQ(psu.isSyncHistoryRequired(), false);
2153 MockedGPIOInterface* mockPresenceGPIO =
2154 static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
2155 // Always return 1 to indicate present.
2156 EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
2157 MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
2158 setMissingToPresentExpects(mockPMBus, mockedUtil);
Brandon Wymanae35ac52022-05-23 22:33:40 +00002159 // Missing/present will trigger attempt to setup INPUT_HISTORY. Setup
2160 // for INPUT_HISTORY will check max_power_out to see if it is
2161 // old/unsupported power supply. Indicate good value, supported.
2162 EXPECT_CALL(mockPMBus, readString(MFR_POUT_MAX, _))
2163 .Times(1)
2164 .WillOnce(Return("2000"));
Brandon Wyman18a24d92022-04-19 22:48:34 +00002165 PMBusExpectations expectations;
2166 setPMBusExpectations(mockPMBus, expectations);
2167 EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
2168 .Times(1)
2169 .WillRepeatedly(Return("205000"));
2170 EXPECT_CALL(mockedUtil, setAvailable(_, _, true));
2171 psu.analyze();
2172 // The ibm-cffps power supply should support input history
2173 EXPECT_EQ(psu.hasInputHistory(), true);
2174 // Missing -> Present requires history sync
2175 EXPECT_EQ(psu.isSyncHistoryRequired(), true);
2176 psu.clearSyncHistoryRequired();
2177 EXPECT_EQ(psu.isSyncHistoryRequired(), false);
2178}