1*73944676SShawn McCarney /**
2*73944676SShawn McCarney * Copyright © 2025 IBM Corporation
3*73944676SShawn McCarney *
4*73944676SShawn McCarney * Licensed under the Apache License, Version 2.0 (the "License");
5*73944676SShawn McCarney * you may not use this file except in compliance with the License.
6*73944676SShawn McCarney * You may obtain a copy of the License at
7*73944676SShawn McCarney *
8*73944676SShawn McCarney * http://www.apache.org/licenses/LICENSE-2.0
9*73944676SShawn McCarney *
10*73944676SShawn McCarney * Unless required by applicable law or agreed to in writing, software
11*73944676SShawn McCarney * distributed under the License is distributed on an "AS IS" BASIS,
12*73944676SShawn McCarney * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*73944676SShawn McCarney * See the License for the specific language governing permissions and
14*73944676SShawn McCarney * limitations under the License.
15*73944676SShawn McCarney */
16*73944676SShawn McCarney
17*73944676SShawn McCarney #include "basic_device.hpp"
18*73944676SShawn McCarney #include "mock_gpio.hpp"
19*73944676SShawn McCarney #include "mock_services.hpp"
20*73944676SShawn McCarney #include "rail.hpp"
21*73944676SShawn McCarney #include "services.hpp"
22*73944676SShawn McCarney
23*73944676SShawn McCarney #include <cstdint>
24*73944676SShawn McCarney #include <map>
25*73944676SShawn McCarney #include <memory>
26*73944676SShawn McCarney #include <optional>
27*73944676SShawn McCarney #include <string>
28*73944676SShawn McCarney #include <utility>
29*73944676SShawn McCarney #include <vector>
30*73944676SShawn McCarney
31*73944676SShawn McCarney #include <gmock/gmock.h>
32*73944676SShawn McCarney #include <gtest/gtest.h>
33*73944676SShawn McCarney
34*73944676SShawn McCarney using namespace phosphor::power::sequencer;
35*73944676SShawn McCarney
36*73944676SShawn McCarney using ::testing::Return;
37*73944676SShawn McCarney using ::testing::Throw;
38*73944676SShawn McCarney
39*73944676SShawn McCarney /**
40*73944676SShawn McCarney * @class BasicDeviceImpl
41*73944676SShawn McCarney *
42*73944676SShawn McCarney * Concrete subclass of the BasicDevice abstract class.
43*73944676SShawn McCarney *
44*73944676SShawn McCarney * This subclass is required because BasicDevice does not implement all the pure
45*73944676SShawn McCarney * virtual methods inherited for PowerSequencerDevice, meaning it cannot be
46*73944676SShawn McCarney * instantiated.
47*73944676SShawn McCarney *
48*73944676SShawn McCarney * This class is not intended to be used outside of this file. It is
49*73944676SShawn McCarney * implementation detail for testing the BasicDevice class.
50*73944676SShawn McCarney */
51*73944676SShawn McCarney class BasicDeviceImpl : public BasicDevice
52*73944676SShawn McCarney {
53*73944676SShawn McCarney public:
54*73944676SShawn McCarney BasicDeviceImpl() = delete;
55*73944676SShawn McCarney BasicDeviceImpl(const BasicDeviceImpl&) = delete;
56*73944676SShawn McCarney BasicDeviceImpl(BasicDeviceImpl&&) = delete;
57*73944676SShawn McCarney BasicDeviceImpl& operator=(const BasicDeviceImpl&) = delete;
58*73944676SShawn McCarney BasicDeviceImpl& operator=(BasicDeviceImpl&&) = delete;
59*73944676SShawn McCarney virtual ~BasicDeviceImpl() = default;
60*73944676SShawn McCarney
BasicDeviceImpl(const std::string & name,uint8_t bus,uint16_t address,const std::string & powerControlGPIOName,const std::string & powerGoodGPIOName,std::vector<std::unique_ptr<Rail>> rails,Services & services)61*73944676SShawn McCarney explicit BasicDeviceImpl(
62*73944676SShawn McCarney const std::string& name, uint8_t bus, uint16_t address,
63*73944676SShawn McCarney const std::string& powerControlGPIOName,
64*73944676SShawn McCarney const std::string& powerGoodGPIOName,
65*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails, Services& services) :
66*73944676SShawn McCarney BasicDevice(name, bus, address, powerControlGPIOName, powerGoodGPIOName,
67*73944676SShawn McCarney std::move(rails), services)
68*73944676SShawn McCarney {}
69*73944676SShawn McCarney
70*73944676SShawn McCarney // Mock pure virtual methods
71*73944676SShawn McCarney MOCK_METHOD(std::vector<int>, getGPIOValues, (Services & services),
72*73944676SShawn McCarney (override));
73*73944676SShawn McCarney MOCK_METHOD(uint16_t, getStatusWord, (uint8_t page), (override));
74*73944676SShawn McCarney MOCK_METHOD(uint8_t, getStatusVout, (uint8_t page), (override));
75*73944676SShawn McCarney MOCK_METHOD(double, getReadVout, (uint8_t page), (override));
76*73944676SShawn McCarney MOCK_METHOD(double, getVoutUVFaultLimit, (uint8_t page), (override));
77*73944676SShawn McCarney MOCK_METHOD(std::string, findPgoodFault,
78*73944676SShawn McCarney (Services & services, const std::string& powerSupplyError,
79*73944676SShawn McCarney (std::map<std::string, std::string> & additionalData)),
80*73944676SShawn McCarney (override));
81*73944676SShawn McCarney };
82*73944676SShawn McCarney
83*73944676SShawn McCarney /**
84*73944676SShawn McCarney * Creates a Rail object that checks for a pgood fault using a GPIO.
85*73944676SShawn McCarney *
86*73944676SShawn McCarney * @param name Unique name for the rail
87*73944676SShawn McCarney * @param gpio GPIO line to read to determine the pgood status of the rail
88*73944676SShawn McCarney * @return Rail object
89*73944676SShawn McCarney */
createRail(const std::string & name,unsigned int gpioLine)90*73944676SShawn McCarney static std::unique_ptr<Rail> createRail(const std::string& name,
91*73944676SShawn McCarney unsigned int gpioLine)
92*73944676SShawn McCarney {
93*73944676SShawn McCarney std::optional<std::string> presence{};
94*73944676SShawn McCarney std::optional<uint8_t> page{};
95*73944676SShawn McCarney bool isPowerSupplyRail{false};
96*73944676SShawn McCarney bool checkStatusVout{false};
97*73944676SShawn McCarney bool compareVoltageToLimit{false};
98*73944676SShawn McCarney bool activeLow{false};
99*73944676SShawn McCarney std::optional<PgoodGPIO> gpio{PgoodGPIO{gpioLine, activeLow}};
100*73944676SShawn McCarney return std::make_unique<Rail>(name, presence, page, isPowerSupplyRail,
101*73944676SShawn McCarney checkStatusVout, compareVoltageToLimit, gpio);
102*73944676SShawn McCarney }
103*73944676SShawn McCarney
TEST(BasicDeviceTests,Constructor)104*73944676SShawn McCarney TEST(BasicDeviceTests, Constructor)
105*73944676SShawn McCarney {
106*73944676SShawn McCarney // Test where works: Empty vector of rails
107*73944676SShawn McCarney {
108*73944676SShawn McCarney std::string name{"xyz_pseq"};
109*73944676SShawn McCarney uint8_t bus{3};
110*73944676SShawn McCarney uint16_t address{0x72};
111*73944676SShawn McCarney std::string powerControlGPIOName{"power-chassis-control"};
112*73944676SShawn McCarney std::string powerGoodGPIOName{"power-chassis-good"};
113*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
114*73944676SShawn McCarney MockServices services;
115*73944676SShawn McCarney BasicDeviceImpl device{
116*73944676SShawn McCarney name,
117*73944676SShawn McCarney bus,
118*73944676SShawn McCarney address,
119*73944676SShawn McCarney powerControlGPIOName,
120*73944676SShawn McCarney powerGoodGPIOName,
121*73944676SShawn McCarney std::move(rails),
122*73944676SShawn McCarney services};
123*73944676SShawn McCarney
124*73944676SShawn McCarney EXPECT_EQ(device.getName(), name);
125*73944676SShawn McCarney EXPECT_EQ(device.getBus(), bus);
126*73944676SShawn McCarney EXPECT_EQ(device.getAddress(), address);
127*73944676SShawn McCarney EXPECT_EQ(device.getPowerControlGPIOName(), powerControlGPIOName);
128*73944676SShawn McCarney EXPECT_EQ(device.getPowerGoodGPIOName(), powerGoodGPIOName);
129*73944676SShawn McCarney EXPECT_TRUE(device.getRails().empty());
130*73944676SShawn McCarney }
131*73944676SShawn McCarney
132*73944676SShawn McCarney // Test where works: Non-empty vector of rails
133*73944676SShawn McCarney {
134*73944676SShawn McCarney std::string name{"abc_pseq"};
135*73944676SShawn McCarney uint8_t bus{0};
136*73944676SShawn McCarney uint16_t address{0x23};
137*73944676SShawn McCarney std::string powerControlGPIOName{"power-chassis-control"};
138*73944676SShawn McCarney std::string powerGoodGPIOName{"power-chassis-good"};
139*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
140*73944676SShawn McCarney rails.emplace_back(createRail("VDD", 5));
141*73944676SShawn McCarney rails.emplace_back(createRail("VIO", 7));
142*73944676SShawn McCarney MockServices services;
143*73944676SShawn McCarney BasicDeviceImpl device{
144*73944676SShawn McCarney name,
145*73944676SShawn McCarney bus,
146*73944676SShawn McCarney address,
147*73944676SShawn McCarney powerControlGPIOName,
148*73944676SShawn McCarney powerGoodGPIOName,
149*73944676SShawn McCarney std::move(rails),
150*73944676SShawn McCarney services};
151*73944676SShawn McCarney
152*73944676SShawn McCarney EXPECT_EQ(device.getName(), name);
153*73944676SShawn McCarney EXPECT_EQ(device.getBus(), bus);
154*73944676SShawn McCarney EXPECT_EQ(device.getAddress(), address);
155*73944676SShawn McCarney EXPECT_EQ(device.getPowerControlGPIOName(), powerControlGPIOName);
156*73944676SShawn McCarney EXPECT_EQ(device.getPowerGoodGPIOName(), powerGoodGPIOName);
157*73944676SShawn McCarney EXPECT_EQ(device.getRails().size(), 2);
158*73944676SShawn McCarney EXPECT_EQ(device.getRails()[0]->getName(), "VDD");
159*73944676SShawn McCarney EXPECT_EQ(device.getRails()[1]->getName(), "VIO");
160*73944676SShawn McCarney }
161*73944676SShawn McCarney }
162*73944676SShawn McCarney
TEST(BasicDeviceTests,GetName)163*73944676SShawn McCarney TEST(BasicDeviceTests, GetName)
164*73944676SShawn McCarney {
165*73944676SShawn McCarney std::string name{"xyz_pseq"};
166*73944676SShawn McCarney uint8_t bus{0};
167*73944676SShawn McCarney uint16_t address{0x23};
168*73944676SShawn McCarney std::string powerControlGPIOName{"power-chassis-control"};
169*73944676SShawn McCarney std::string powerGoodGPIOName{"power-chassis-good"};
170*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
171*73944676SShawn McCarney MockServices services;
172*73944676SShawn McCarney BasicDeviceImpl device{
173*73944676SShawn McCarney name,
174*73944676SShawn McCarney bus,
175*73944676SShawn McCarney address,
176*73944676SShawn McCarney powerControlGPIOName,
177*73944676SShawn McCarney powerGoodGPIOName,
178*73944676SShawn McCarney std::move(rails),
179*73944676SShawn McCarney services};
180*73944676SShawn McCarney
181*73944676SShawn McCarney EXPECT_EQ(device.getName(), name);
182*73944676SShawn McCarney }
183*73944676SShawn McCarney
TEST(BasicDeviceTests,GetBus)184*73944676SShawn McCarney TEST(BasicDeviceTests, GetBus)
185*73944676SShawn McCarney {
186*73944676SShawn McCarney std::string name{"abc_pseq"};
187*73944676SShawn McCarney uint8_t bus{1};
188*73944676SShawn McCarney uint16_t address{0x23};
189*73944676SShawn McCarney std::string powerControlGPIOName{"power-chassis-control"};
190*73944676SShawn McCarney std::string powerGoodGPIOName{"power-chassis-good"};
191*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
192*73944676SShawn McCarney MockServices services;
193*73944676SShawn McCarney BasicDeviceImpl device{
194*73944676SShawn McCarney name,
195*73944676SShawn McCarney bus,
196*73944676SShawn McCarney address,
197*73944676SShawn McCarney powerControlGPIOName,
198*73944676SShawn McCarney powerGoodGPIOName,
199*73944676SShawn McCarney std::move(rails),
200*73944676SShawn McCarney services};
201*73944676SShawn McCarney
202*73944676SShawn McCarney EXPECT_EQ(device.getBus(), bus);
203*73944676SShawn McCarney }
204*73944676SShawn McCarney
TEST(BasicDeviceTests,GetAddress)205*73944676SShawn McCarney TEST(BasicDeviceTests, GetAddress)
206*73944676SShawn McCarney {
207*73944676SShawn McCarney std::string name{"abc_pseq"};
208*73944676SShawn McCarney uint8_t bus{1};
209*73944676SShawn McCarney uint16_t address{0x24};
210*73944676SShawn McCarney std::string powerControlGPIOName{"power-chassis-control"};
211*73944676SShawn McCarney std::string powerGoodGPIOName{"power-chassis-good"};
212*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
213*73944676SShawn McCarney MockServices services;
214*73944676SShawn McCarney BasicDeviceImpl device{
215*73944676SShawn McCarney name,
216*73944676SShawn McCarney bus,
217*73944676SShawn McCarney address,
218*73944676SShawn McCarney powerControlGPIOName,
219*73944676SShawn McCarney powerGoodGPIOName,
220*73944676SShawn McCarney std::move(rails),
221*73944676SShawn McCarney services};
222*73944676SShawn McCarney
223*73944676SShawn McCarney EXPECT_EQ(device.getAddress(), address);
224*73944676SShawn McCarney }
225*73944676SShawn McCarney
TEST(BasicDeviceTests,GetPowerControlGPIOName)226*73944676SShawn McCarney TEST(BasicDeviceTests, GetPowerControlGPIOName)
227*73944676SShawn McCarney {
228*73944676SShawn McCarney std::string name{"xyz_pseq"};
229*73944676SShawn McCarney uint8_t bus{0};
230*73944676SShawn McCarney uint16_t address{0x23};
231*73944676SShawn McCarney std::string powerControlGPIOName{"power-on"};
232*73944676SShawn McCarney std::string powerGoodGPIOName{"chassis-pgood"};
233*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
234*73944676SShawn McCarney MockServices services;
235*73944676SShawn McCarney BasicDeviceImpl device{
236*73944676SShawn McCarney name,
237*73944676SShawn McCarney bus,
238*73944676SShawn McCarney address,
239*73944676SShawn McCarney powerControlGPIOName,
240*73944676SShawn McCarney powerGoodGPIOName,
241*73944676SShawn McCarney std::move(rails),
242*73944676SShawn McCarney services};
243*73944676SShawn McCarney
244*73944676SShawn McCarney EXPECT_EQ(device.getPowerControlGPIOName(), powerControlGPIOName);
245*73944676SShawn McCarney }
246*73944676SShawn McCarney
TEST(BasicDeviceTests,GetPowerGoodGPIOName)247*73944676SShawn McCarney TEST(BasicDeviceTests, GetPowerGoodGPIOName)
248*73944676SShawn McCarney {
249*73944676SShawn McCarney std::string name{"xyz_pseq"};
250*73944676SShawn McCarney uint8_t bus{0};
251*73944676SShawn McCarney uint16_t address{0x23};
252*73944676SShawn McCarney std::string powerControlGPIOName{"power-on"};
253*73944676SShawn McCarney std::string powerGoodGPIOName{"chassis-pgood"};
254*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
255*73944676SShawn McCarney MockServices services;
256*73944676SShawn McCarney BasicDeviceImpl device{
257*73944676SShawn McCarney name,
258*73944676SShawn McCarney bus,
259*73944676SShawn McCarney address,
260*73944676SShawn McCarney powerControlGPIOName,
261*73944676SShawn McCarney powerGoodGPIOName,
262*73944676SShawn McCarney std::move(rails),
263*73944676SShawn McCarney services};
264*73944676SShawn McCarney
265*73944676SShawn McCarney EXPECT_EQ(device.getPowerGoodGPIOName(), powerGoodGPIOName);
266*73944676SShawn McCarney }
267*73944676SShawn McCarney
TEST(BasicDeviceTests,GetRails)268*73944676SShawn McCarney TEST(BasicDeviceTests, GetRails)
269*73944676SShawn McCarney {
270*73944676SShawn McCarney // Empty vector of rails
271*73944676SShawn McCarney {
272*73944676SShawn McCarney std::string name{"xyz_pseq"};
273*73944676SShawn McCarney uint8_t bus{0};
274*73944676SShawn McCarney uint16_t address{0x23};
275*73944676SShawn McCarney std::string powerControlGPIOName{"power-chassis-control"};
276*73944676SShawn McCarney std::string powerGoodGPIOName{"power-chassis-good"};
277*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
278*73944676SShawn McCarney MockServices services;
279*73944676SShawn McCarney BasicDeviceImpl device{
280*73944676SShawn McCarney name,
281*73944676SShawn McCarney bus,
282*73944676SShawn McCarney address,
283*73944676SShawn McCarney powerControlGPIOName,
284*73944676SShawn McCarney powerGoodGPIOName,
285*73944676SShawn McCarney std::move(rails),
286*73944676SShawn McCarney services};
287*73944676SShawn McCarney
288*73944676SShawn McCarney EXPECT_TRUE(device.getRails().empty());
289*73944676SShawn McCarney }
290*73944676SShawn McCarney
291*73944676SShawn McCarney // Non-empty vector of rails
292*73944676SShawn McCarney {
293*73944676SShawn McCarney std::string name{"abc_pseq"};
294*73944676SShawn McCarney uint8_t bus{0};
295*73944676SShawn McCarney uint16_t address{0x23};
296*73944676SShawn McCarney std::string powerControlGPIOName{"power-chassis-control"};
297*73944676SShawn McCarney std::string powerGoodGPIOName{"power-chassis-good"};
298*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
299*73944676SShawn McCarney rails.emplace_back(createRail("VDD", 5));
300*73944676SShawn McCarney rails.emplace_back(createRail("VIO", 7));
301*73944676SShawn McCarney rails.emplace_back(createRail("VDDR", 9));
302*73944676SShawn McCarney MockServices services;
303*73944676SShawn McCarney BasicDeviceImpl device{
304*73944676SShawn McCarney name,
305*73944676SShawn McCarney bus,
306*73944676SShawn McCarney address,
307*73944676SShawn McCarney powerControlGPIOName,
308*73944676SShawn McCarney powerGoodGPIOName,
309*73944676SShawn McCarney std::move(rails),
310*73944676SShawn McCarney services};
311*73944676SShawn McCarney
312*73944676SShawn McCarney EXPECT_EQ(device.getRails().size(), 3);
313*73944676SShawn McCarney EXPECT_EQ(device.getRails()[0]->getName(), "VDD");
314*73944676SShawn McCarney EXPECT_EQ(device.getRails()[1]->getName(), "VIO");
315*73944676SShawn McCarney EXPECT_EQ(device.getRails()[2]->getName(), "VDDR");
316*73944676SShawn McCarney }
317*73944676SShawn McCarney }
318*73944676SShawn McCarney
TEST(BasicDeviceTests,GetPowerControlGPIO)319*73944676SShawn McCarney TEST(BasicDeviceTests, GetPowerControlGPIO)
320*73944676SShawn McCarney {
321*73944676SShawn McCarney std::string name{"xyz_pseq"};
322*73944676SShawn McCarney uint8_t bus{0};
323*73944676SShawn McCarney uint16_t address{0x23};
324*73944676SShawn McCarney std::string powerControlGPIOName{"power-on"};
325*73944676SShawn McCarney std::string powerGoodGPIOName{"chassis-pgood"};
326*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
327*73944676SShawn McCarney MockServices services;
328*73944676SShawn McCarney BasicDeviceImpl device{
329*73944676SShawn McCarney name,
330*73944676SShawn McCarney bus,
331*73944676SShawn McCarney address,
332*73944676SShawn McCarney powerControlGPIOName,
333*73944676SShawn McCarney powerGoodGPIOName,
334*73944676SShawn McCarney std::move(rails),
335*73944676SShawn McCarney services};
336*73944676SShawn McCarney
337*73944676SShawn McCarney MockGPIO& gpio = static_cast<MockGPIO&>(device.getPowerControlGPIO());
338*73944676SShawn McCarney EXPECT_CALL(gpio, setValue(1)).Times(1);
339*73944676SShawn McCarney device.powerOn();
340*73944676SShawn McCarney }
341*73944676SShawn McCarney
TEST(BasicDeviceTests,GetPowerGoodGPIO)342*73944676SShawn McCarney TEST(BasicDeviceTests, GetPowerGoodGPIO)
343*73944676SShawn McCarney {
344*73944676SShawn McCarney std::string name{"xyz_pseq"};
345*73944676SShawn McCarney uint8_t bus{0};
346*73944676SShawn McCarney uint16_t address{0x23};
347*73944676SShawn McCarney std::string powerControlGPIOName{"power-on"};
348*73944676SShawn McCarney std::string powerGoodGPIOName{"chassis-pgood"};
349*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
350*73944676SShawn McCarney MockServices services;
351*73944676SShawn McCarney BasicDeviceImpl device{
352*73944676SShawn McCarney name,
353*73944676SShawn McCarney bus,
354*73944676SShawn McCarney address,
355*73944676SShawn McCarney powerControlGPIOName,
356*73944676SShawn McCarney powerGoodGPIOName,
357*73944676SShawn McCarney std::move(rails),
358*73944676SShawn McCarney services};
359*73944676SShawn McCarney
360*73944676SShawn McCarney MockGPIO& gpio = static_cast<MockGPIO&>(device.getPowerGoodGPIO());
361*73944676SShawn McCarney EXPECT_CALL(gpio, getValue()).Times(1).WillOnce(Return(0));
362*73944676SShawn McCarney EXPECT_FALSE(device.getPowerGood());
363*73944676SShawn McCarney }
364*73944676SShawn McCarney
TEST(BasicDeviceTests,PowerOn)365*73944676SShawn McCarney TEST(BasicDeviceTests, PowerOn)
366*73944676SShawn McCarney {
367*73944676SShawn McCarney // Test where works
368*73944676SShawn McCarney {
369*73944676SShawn McCarney std::string name{"xyz_pseq"};
370*73944676SShawn McCarney uint8_t bus{0};
371*73944676SShawn McCarney uint16_t address{0x23};
372*73944676SShawn McCarney std::string powerControlGPIOName{"power-on"};
373*73944676SShawn McCarney std::string powerGoodGPIOName{"chassis-pgood"};
374*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
375*73944676SShawn McCarney MockServices services;
376*73944676SShawn McCarney BasicDeviceImpl device{
377*73944676SShawn McCarney name,
378*73944676SShawn McCarney bus,
379*73944676SShawn McCarney address,
380*73944676SShawn McCarney powerControlGPIOName,
381*73944676SShawn McCarney powerGoodGPIOName,
382*73944676SShawn McCarney std::move(rails),
383*73944676SShawn McCarney services};
384*73944676SShawn McCarney
385*73944676SShawn McCarney MockGPIO& gpio = static_cast<MockGPIO&>(device.getPowerControlGPIO());
386*73944676SShawn McCarney EXPECT_CALL(gpio, requestWrite(1)).Times(1);
387*73944676SShawn McCarney EXPECT_CALL(gpio, setValue(1)).Times(1);
388*73944676SShawn McCarney EXPECT_CALL(gpio, release()).Times(1);
389*73944676SShawn McCarney device.powerOn();
390*73944676SShawn McCarney }
391*73944676SShawn McCarney
392*73944676SShawn McCarney // Test where fails with exception
393*73944676SShawn McCarney try
394*73944676SShawn McCarney {
395*73944676SShawn McCarney std::string name{"xyz_pseq"};
396*73944676SShawn McCarney uint8_t bus{0};
397*73944676SShawn McCarney uint16_t address{0x23};
398*73944676SShawn McCarney std::string powerControlGPIOName{"power-on"};
399*73944676SShawn McCarney std::string powerGoodGPIOName{"chassis-pgood"};
400*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
401*73944676SShawn McCarney MockServices services;
402*73944676SShawn McCarney BasicDeviceImpl device{
403*73944676SShawn McCarney name,
404*73944676SShawn McCarney bus,
405*73944676SShawn McCarney address,
406*73944676SShawn McCarney powerControlGPIOName,
407*73944676SShawn McCarney powerGoodGPIOName,
408*73944676SShawn McCarney std::move(rails),
409*73944676SShawn McCarney services};
410*73944676SShawn McCarney
411*73944676SShawn McCarney MockGPIO& gpio = static_cast<MockGPIO&>(device.getPowerControlGPIO());
412*73944676SShawn McCarney EXPECT_CALL(gpio, requestWrite(1))
413*73944676SShawn McCarney .Times(1)
414*73944676SShawn McCarney .WillOnce(Throw(std::runtime_error{"Unable to write GPIO"}));
415*73944676SShawn McCarney device.powerOn();
416*73944676SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
417*73944676SShawn McCarney }
418*73944676SShawn McCarney catch (const std::exception& e)
419*73944676SShawn McCarney {
420*73944676SShawn McCarney EXPECT_STREQ(e.what(), "Unable to write GPIO");
421*73944676SShawn McCarney }
422*73944676SShawn McCarney }
423*73944676SShawn McCarney
TEST(BasicDeviceTests,PowerOff)424*73944676SShawn McCarney TEST(BasicDeviceTests, PowerOff)
425*73944676SShawn McCarney {
426*73944676SShawn McCarney // Test where works
427*73944676SShawn McCarney {
428*73944676SShawn McCarney std::string name{"xyz_pseq"};
429*73944676SShawn McCarney uint8_t bus{0};
430*73944676SShawn McCarney uint16_t address{0x23};
431*73944676SShawn McCarney std::string powerControlGPIOName{"power-on"};
432*73944676SShawn McCarney std::string powerGoodGPIOName{"chassis-pgood"};
433*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
434*73944676SShawn McCarney MockServices services;
435*73944676SShawn McCarney BasicDeviceImpl device{
436*73944676SShawn McCarney name,
437*73944676SShawn McCarney bus,
438*73944676SShawn McCarney address,
439*73944676SShawn McCarney powerControlGPIOName,
440*73944676SShawn McCarney powerGoodGPIOName,
441*73944676SShawn McCarney std::move(rails),
442*73944676SShawn McCarney services};
443*73944676SShawn McCarney
444*73944676SShawn McCarney MockGPIO& gpio = static_cast<MockGPIO&>(device.getPowerControlGPIO());
445*73944676SShawn McCarney EXPECT_CALL(gpio, requestWrite(0)).Times(1);
446*73944676SShawn McCarney EXPECT_CALL(gpio, setValue(0)).Times(1);
447*73944676SShawn McCarney EXPECT_CALL(gpio, release()).Times(1);
448*73944676SShawn McCarney device.powerOff();
449*73944676SShawn McCarney }
450*73944676SShawn McCarney
451*73944676SShawn McCarney // Test where fails with exception
452*73944676SShawn McCarney try
453*73944676SShawn McCarney {
454*73944676SShawn McCarney std::string name{"xyz_pseq"};
455*73944676SShawn McCarney uint8_t bus{0};
456*73944676SShawn McCarney uint16_t address{0x23};
457*73944676SShawn McCarney std::string powerControlGPIOName{"power-on"};
458*73944676SShawn McCarney std::string powerGoodGPIOName{"chassis-pgood"};
459*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
460*73944676SShawn McCarney MockServices services;
461*73944676SShawn McCarney BasicDeviceImpl device{
462*73944676SShawn McCarney name,
463*73944676SShawn McCarney bus,
464*73944676SShawn McCarney address,
465*73944676SShawn McCarney powerControlGPIOName,
466*73944676SShawn McCarney powerGoodGPIOName,
467*73944676SShawn McCarney std::move(rails),
468*73944676SShawn McCarney services};
469*73944676SShawn McCarney
470*73944676SShawn McCarney MockGPIO& gpio = static_cast<MockGPIO&>(device.getPowerControlGPIO());
471*73944676SShawn McCarney EXPECT_CALL(gpio, requestWrite(0)).Times(1);
472*73944676SShawn McCarney EXPECT_CALL(gpio, setValue(0))
473*73944676SShawn McCarney .Times(1)
474*73944676SShawn McCarney .WillOnce(Throw(std::runtime_error{"Unable to write GPIO"}));
475*73944676SShawn McCarney device.powerOff();
476*73944676SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
477*73944676SShawn McCarney }
478*73944676SShawn McCarney catch (const std::exception& e)
479*73944676SShawn McCarney {
480*73944676SShawn McCarney EXPECT_STREQ(e.what(), "Unable to write GPIO");
481*73944676SShawn McCarney }
482*73944676SShawn McCarney }
483*73944676SShawn McCarney
TEST(BasicDeviceTests,GetPowerGood)484*73944676SShawn McCarney TEST(BasicDeviceTests, GetPowerGood)
485*73944676SShawn McCarney {
486*73944676SShawn McCarney // Test where works: Value is false
487*73944676SShawn McCarney {
488*73944676SShawn McCarney std::string name{"xyz_pseq"};
489*73944676SShawn McCarney uint8_t bus{0};
490*73944676SShawn McCarney uint16_t address{0x23};
491*73944676SShawn McCarney std::string powerControlGPIOName{"power-on"};
492*73944676SShawn McCarney std::string powerGoodGPIOName{"chassis-pgood"};
493*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
494*73944676SShawn McCarney MockServices services;
495*73944676SShawn McCarney BasicDeviceImpl device{
496*73944676SShawn McCarney name,
497*73944676SShawn McCarney bus,
498*73944676SShawn McCarney address,
499*73944676SShawn McCarney powerControlGPIOName,
500*73944676SShawn McCarney powerGoodGPIOName,
501*73944676SShawn McCarney std::move(rails),
502*73944676SShawn McCarney services};
503*73944676SShawn McCarney
504*73944676SShawn McCarney MockGPIO& gpio = static_cast<MockGPIO&>(device.getPowerGoodGPIO());
505*73944676SShawn McCarney EXPECT_CALL(gpio, getValue()).Times(1).WillOnce(Return(0));
506*73944676SShawn McCarney EXPECT_FALSE(device.getPowerGood());
507*73944676SShawn McCarney }
508*73944676SShawn McCarney
509*73944676SShawn McCarney // Test where works: Value is true
510*73944676SShawn McCarney {
511*73944676SShawn McCarney std::string name{"xyz_pseq"};
512*73944676SShawn McCarney uint8_t bus{0};
513*73944676SShawn McCarney uint16_t address{0x23};
514*73944676SShawn McCarney std::string powerControlGPIOName{"power-on"};
515*73944676SShawn McCarney std::string powerGoodGPIOName{"chassis-pgood"};
516*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
517*73944676SShawn McCarney MockServices services;
518*73944676SShawn McCarney BasicDeviceImpl device{
519*73944676SShawn McCarney name,
520*73944676SShawn McCarney bus,
521*73944676SShawn McCarney address,
522*73944676SShawn McCarney powerControlGPIOName,
523*73944676SShawn McCarney powerGoodGPIOName,
524*73944676SShawn McCarney std::move(rails),
525*73944676SShawn McCarney services};
526*73944676SShawn McCarney
527*73944676SShawn McCarney MockGPIO& gpio = static_cast<MockGPIO&>(device.getPowerGoodGPIO());
528*73944676SShawn McCarney EXPECT_CALL(gpio, getValue()).Times(1).WillOnce(Return(1));
529*73944676SShawn McCarney EXPECT_TRUE(device.getPowerGood());
530*73944676SShawn McCarney }
531*73944676SShawn McCarney
532*73944676SShawn McCarney // Test where fails with exception
533*73944676SShawn McCarney try
534*73944676SShawn McCarney {
535*73944676SShawn McCarney std::string name{"xyz_pseq"};
536*73944676SShawn McCarney uint8_t bus{0};
537*73944676SShawn McCarney uint16_t address{0x23};
538*73944676SShawn McCarney std::string powerControlGPIOName{"power-on"};
539*73944676SShawn McCarney std::string powerGoodGPIOName{"chassis-pgood"};
540*73944676SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{};
541*73944676SShawn McCarney MockServices services;
542*73944676SShawn McCarney BasicDeviceImpl device{
543*73944676SShawn McCarney name,
544*73944676SShawn McCarney bus,
545*73944676SShawn McCarney address,
546*73944676SShawn McCarney powerControlGPIOName,
547*73944676SShawn McCarney powerGoodGPIOName,
548*73944676SShawn McCarney std::move(rails),
549*73944676SShawn McCarney services};
550*73944676SShawn McCarney
551*73944676SShawn McCarney MockGPIO& gpio = static_cast<MockGPIO&>(device.getPowerGoodGPIO());
552*73944676SShawn McCarney EXPECT_CALL(gpio, getValue())
553*73944676SShawn McCarney .Times(1)
554*73944676SShawn McCarney .WillOnce(Throw(std::runtime_error{"Unable to read GPIO"}));
555*73944676SShawn McCarney device.getPowerGood();
556*73944676SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
557*73944676SShawn McCarney }
558*73944676SShawn McCarney catch (const std::exception& e)
559*73944676SShawn McCarney {
560*73944676SShawn McCarney EXPECT_STREQ(e.what(), "Unable to read GPIO");
561*73944676SShawn McCarney }
562*73944676SShawn McCarney }
563