xref: /openbmc/entity-manager/test/test_gpio_presence_state.cpp (revision a005e3e656021be5e8291e8df86503b27942f237)
1*a005e3e6SPatrick Williams #include "gpio-presence/device_presence.hpp"
2*a005e3e6SPatrick Williams #include "gpio-presence/gpio_presence_manager.hpp"
3*a005e3e6SPatrick Williams 
4*a005e3e6SPatrick Williams #include <gpiod.hpp>
5*a005e3e6SPatrick Williams #include <phosphor-logging/lg2.hpp>
6*a005e3e6SPatrick Williams 
7*a005e3e6SPatrick Williams #include <gtest/gtest.h>
8*a005e3e6SPatrick Williams 
9*a005e3e6SPatrick Williams using namespace gpio_presence;
10*a005e3e6SPatrick Williams 
11*a005e3e6SPatrick Williams class DevicePresenceDetailedTest : public ::testing::Test
12*a005e3e6SPatrick Williams {
13*a005e3e6SPatrick Williams   protected:
14*a005e3e6SPatrick Williams     DevicePresenceDetailedTest() = default;
15*a005e3e6SPatrick Williams     ~DevicePresenceDetailedTest() noexcept override = default;
16*a005e3e6SPatrick Williams 
17*a005e3e6SPatrick Williams     sdbusplus::async::context ctx;
18*a005e3e6SPatrick Williams     std::unordered_map<std::string, bool> gpioState;
19*a005e3e6SPatrick Williams };
20*a005e3e6SPatrick Williams 
21*a005e3e6SPatrick Williams // Test DevicePresence constructor with single GPIO, active low
22*a005e3e6SPatrick Williams TEST_F(DevicePresenceDetailedTest, ConstructorSingleGpioActiveLow)
23*a005e3e6SPatrick Williams {
24*a005e3e6SPatrick Williams     std::vector<std::string> gpioNames = {"GPIO1"};
25*a005e3e6SPatrick Williams     std::vector<uint64_t> gpioValues = {0}; // Active low
26*a005e3e6SPatrick Williams     std::string deviceName = "device1";
27*a005e3e6SPatrick Williams 
28*a005e3e6SPatrick Williams     DevicePresence device(ctx, gpioNames, gpioValues, deviceName, gpioState);
29*a005e3e6SPatrick Williams 
30*a005e3e6SPatrick Williams     EXPECT_EQ(device.deviceName, deviceName);
31*a005e3e6SPatrick Williams     EXPECT_EQ(device.gpioPolarity.size(), 1);
32*a005e3e6SPatrick Williams     EXPECT_EQ(device.gpioPolarity["GPIO1"], ACTIVE_LOW);
33*a005e3e6SPatrick Williams }
34*a005e3e6SPatrick Williams 
35*a005e3e6SPatrick Williams // Test DevicePresence constructor with single GPIO, active high
36*a005e3e6SPatrick Williams TEST_F(DevicePresenceDetailedTest, ConstructorSingleGpioActiveHigh)
37*a005e3e6SPatrick Williams {
38*a005e3e6SPatrick Williams     std::vector<std::string> gpioNames = {"GPIO2"};
39*a005e3e6SPatrick Williams     std::vector<uint64_t> gpioValues = {1}; // Active high
40*a005e3e6SPatrick Williams     std::string deviceName = "device2";
41*a005e3e6SPatrick Williams 
42*a005e3e6SPatrick Williams     DevicePresence device(ctx, gpioNames, gpioValues, deviceName, gpioState);
43*a005e3e6SPatrick Williams 
44*a005e3e6SPatrick Williams     EXPECT_EQ(device.deviceName, deviceName);
45*a005e3e6SPatrick Williams     EXPECT_EQ(device.gpioPolarity.size(), 1);
46*a005e3e6SPatrick Williams     EXPECT_EQ(device.gpioPolarity["GPIO2"], ACTIVE_HIGH);
47*a005e3e6SPatrick Williams }
48*a005e3e6SPatrick Williams 
49*a005e3e6SPatrick Williams // Test DevicePresence constructor with multiple GPIOs with mixed polarities
50*a005e3e6SPatrick Williams TEST_F(DevicePresenceDetailedTest, ConstructorMultipleGpiosMixedPolarities)
51*a005e3e6SPatrick Williams {
52*a005e3e6SPatrick Williams     std::vector<std::string> gpioNames = {"GPIO1", "GPIO2", "GPIO3"};
53*a005e3e6SPatrick Williams     std::vector<uint64_t> gpioValues = {0, 1, 0}; // Active low, high, low
54*a005e3e6SPatrick Williams     std::string deviceName = "device3";
55*a005e3e6SPatrick Williams 
56*a005e3e6SPatrick Williams     DevicePresence device(ctx, gpioNames, gpioValues, deviceName, gpioState);
57*a005e3e6SPatrick Williams 
58*a005e3e6SPatrick Williams     EXPECT_EQ(device.deviceName, deviceName);
59*a005e3e6SPatrick Williams     EXPECT_EQ(device.gpioPolarity.size(), 3);
60*a005e3e6SPatrick Williams     EXPECT_EQ(device.gpioPolarity["GPIO1"], ACTIVE_LOW);
61*a005e3e6SPatrick Williams     EXPECT_EQ(device.gpioPolarity["GPIO2"], ACTIVE_HIGH);
62*a005e3e6SPatrick Williams     EXPECT_EQ(device.gpioPolarity["GPIO3"], ACTIVE_LOW);
63*a005e3e6SPatrick Williams }
64*a005e3e6SPatrick Williams 
65*a005e3e6SPatrick Williams // Test DevicePresence isPresent method with active low GPIO is low (device
66*a005e3e6SPatrick Williams // present)
67*a005e3e6SPatrick Williams TEST_F(DevicePresenceDetailedTest, IsPresentActiveLowGpioLow)
68*a005e3e6SPatrick Williams {
69*a005e3e6SPatrick Williams     std::unordered_map<std::string, bool> localGpioState;
70*a005e3e6SPatrick Williams     std::vector<std::string> gpioNames = {"GPIO1"};
71*a005e3e6SPatrick Williams     std::vector<uint64_t> gpioValues = {0}; // Active low
72*a005e3e6SPatrick Williams     std::string deviceName = "device1";
73*a005e3e6SPatrick Williams 
74*a005e3e6SPatrick Williams     localGpioState["GPIO1"] = false; // GPIO is low
75*a005e3e6SPatrick Williams 
76*a005e3e6SPatrick Williams     DevicePresence device(ctx, gpioNames, gpioValues, deviceName,
77*a005e3e6SPatrick Williams                           localGpioState);
78*a005e3e6SPatrick Williams     EXPECT_TRUE(device.isPresent());
79*a005e3e6SPatrick Williams }
80*a005e3e6SPatrick Williams 
81*a005e3e6SPatrick Williams // Test DevicePresence isPresent method with active low GPIO is high (device
82*a005e3e6SPatrick Williams // absent)
83*a005e3e6SPatrick Williams TEST_F(DevicePresenceDetailedTest, IsPresentActiveLowGpioHigh)
84*a005e3e6SPatrick Williams {
85*a005e3e6SPatrick Williams     std::unordered_map<std::string, bool> localGpioState;
86*a005e3e6SPatrick Williams     std::vector<std::string> gpioNames = {"GPIO1"};
87*a005e3e6SPatrick Williams     std::vector<uint64_t> gpioValues = {0}; // Active low
88*a005e3e6SPatrick Williams     std::string deviceName = "device1";
89*a005e3e6SPatrick Williams 
90*a005e3e6SPatrick Williams     localGpioState["GPIO1"] = true; // GPIO is high
91*a005e3e6SPatrick Williams 
92*a005e3e6SPatrick Williams     DevicePresence device(ctx, gpioNames, gpioValues, deviceName,
93*a005e3e6SPatrick Williams                           localGpioState);
94*a005e3e6SPatrick Williams     EXPECT_FALSE(device.isPresent());
95*a005e3e6SPatrick Williams }
96*a005e3e6SPatrick Williams 
97*a005e3e6SPatrick Williams // Test DevicePresence isPresent method with active high GPIO is high (device
98*a005e3e6SPatrick Williams // present)
99*a005e3e6SPatrick Williams TEST_F(DevicePresenceDetailedTest, IsPresentActiveHighGpioHigh)
100*a005e3e6SPatrick Williams {
101*a005e3e6SPatrick Williams     std::unordered_map<std::string, bool> localGpioState;
102*a005e3e6SPatrick Williams     std::vector<std::string> gpioNames = {"GPIO1"};
103*a005e3e6SPatrick Williams     std::vector<uint64_t> gpioValues = {1}; // Active high
104*a005e3e6SPatrick Williams     std::string deviceName = "device1";
105*a005e3e6SPatrick Williams 
106*a005e3e6SPatrick Williams     localGpioState["GPIO1"] = true; // GPIO is high
107*a005e3e6SPatrick Williams 
108*a005e3e6SPatrick Williams     DevicePresence device(ctx, gpioNames, gpioValues, deviceName,
109*a005e3e6SPatrick Williams                           localGpioState);
110*a005e3e6SPatrick Williams     EXPECT_TRUE(device.isPresent());
111*a005e3e6SPatrick Williams }
112*a005e3e6SPatrick Williams 
113*a005e3e6SPatrick Williams // Test DevicePresence isPresent method with active high GPIO is low (device
114*a005e3e6SPatrick Williams // absent)
115*a005e3e6SPatrick Williams TEST_F(DevicePresenceDetailedTest, IsPresentActiveHighGpioLow)
116*a005e3e6SPatrick Williams {
117*a005e3e6SPatrick Williams     std::unordered_map<std::string, bool> localGpioState;
118*a005e3e6SPatrick Williams     std::vector<std::string> gpioNames = {"GPIO1"};
119*a005e3e6SPatrick Williams     std::vector<uint64_t> gpioValues = {1}; // Active high
120*a005e3e6SPatrick Williams     std::string deviceName = "device1";
121*a005e3e6SPatrick Williams 
122*a005e3e6SPatrick Williams     localGpioState["GPIO1"] = false; // GPIO is low
123*a005e3e6SPatrick Williams 
124*a005e3e6SPatrick Williams     DevicePresence device(ctx, gpioNames, gpioValues, deviceName,
125*a005e3e6SPatrick Williams                           localGpioState);
126*a005e3e6SPatrick Williams     EXPECT_FALSE(device.isPresent());
127*a005e3e6SPatrick Williams }
128*a005e3e6SPatrick Williams 
129*a005e3e6SPatrick Williams // Test DevicePresence isPresent method with multiple GPIOs all correct (device
130*a005e3e6SPatrick Williams // present)
131*a005e3e6SPatrick Williams TEST_F(DevicePresenceDetailedTest, IsPresentMultipleGpiosAllCorrect)
132*a005e3e6SPatrick Williams {
133*a005e3e6SPatrick Williams     std::unordered_map<std::string, bool> localGpioState;
134*a005e3e6SPatrick Williams     std::vector<std::string> gpioNames = {"GPIO1", "GPIO2", "GPIO3"};
135*a005e3e6SPatrick Williams     std::vector<uint64_t> gpioValues = {0, 1, 0}; // Active low, high, low
136*a005e3e6SPatrick Williams     std::string deviceName = "device1";
137*a005e3e6SPatrick Williams 
138*a005e3e6SPatrick Williams     localGpioState["GPIO1"] = false; // Active low, should be low
139*a005e3e6SPatrick Williams     localGpioState["GPIO2"] = true;  // Active high, should be high
140*a005e3e6SPatrick Williams     localGpioState["GPIO3"] = false; // Active low, should be low
141*a005e3e6SPatrick Williams 
142*a005e3e6SPatrick Williams     DevicePresence device(ctx, gpioNames, gpioValues, deviceName,
143*a005e3e6SPatrick Williams                           localGpioState);
144*a005e3e6SPatrick Williams     EXPECT_TRUE(device.isPresent());
145*a005e3e6SPatrick Williams }
146*a005e3e6SPatrick Williams 
147*a005e3e6SPatrick Williams // Test DevicePresence isPresent method with multiple GPIOs one incorrect
148*a005e3e6SPatrick Williams // (device absent)
149*a005e3e6SPatrick Williams TEST_F(DevicePresenceDetailedTest, IsPresentMultipleGpiosOneIncorrect)
150*a005e3e6SPatrick Williams {
151*a005e3e6SPatrick Williams     std::unordered_map<std::string, bool> localGpioState;
152*a005e3e6SPatrick Williams     std::vector<std::string> gpioNames = {"GPIO1", "GPIO2", "GPIO3"};
153*a005e3e6SPatrick Williams     std::vector<uint64_t> gpioValues = {0, 1, 0}; // Active low, high, low
154*a005e3e6SPatrick Williams     std::string deviceName = "device1";
155*a005e3e6SPatrick Williams 
156*a005e3e6SPatrick Williams     localGpioState["GPIO1"] = false; // Active low, should be low - correct
157*a005e3e6SPatrick Williams     localGpioState["GPIO2"] = false; // Active high, should be high - incorrect
158*a005e3e6SPatrick Williams     localGpioState["GPIO3"] = false; // Active low, should be low - correct
159*a005e3e6SPatrick Williams 
160*a005e3e6SPatrick Williams     DevicePresence device(ctx, gpioNames, gpioValues, deviceName,
161*a005e3e6SPatrick Williams                           localGpioState);
162*a005e3e6SPatrick Williams     EXPECT_FALSE(device.isPresent());
163*a005e3e6SPatrick Williams }
164*a005e3e6SPatrick Williams 
165*a005e3e6SPatrick Williams // Test DevicePresence isPresent method with missing GPIO state (device absent)
166*a005e3e6SPatrick Williams TEST_F(DevicePresenceDetailedTest, IsPresentMissingGpioState)
167*a005e3e6SPatrick Williams {
168*a005e3e6SPatrick Williams     std::unordered_map<std::string, bool> localGpioState;
169*a005e3e6SPatrick Williams     std::vector<std::string> gpioNames = {"GPIO1"};
170*a005e3e6SPatrick Williams     std::vector<uint64_t> gpioValues = {0}; // Active low
171*a005e3e6SPatrick Williams     std::string deviceName = "device1";
172*a005e3e6SPatrick Williams 
173*a005e3e6SPatrick Williams     // localGpioState["GPIO1"] is not set - simulating missing GPIO
174*a005e3e6SPatrick Williams 
175*a005e3e6SPatrick Williams     DevicePresence device(ctx, gpioNames, gpioValues, deviceName,
176*a005e3e6SPatrick Williams                           localGpioState);
177*a005e3e6SPatrick Williams     EXPECT_FALSE(device.isPresent());
178*a005e3e6SPatrick Williams }
179*a005e3e6SPatrick Williams 
180*a005e3e6SPatrick Williams // Test DevicePresence getObjPath method
181*a005e3e6SPatrick Williams TEST_F(DevicePresenceDetailedTest, GetObjPathTest)
182*a005e3e6SPatrick Williams {
183*a005e3e6SPatrick Williams     std::vector<std::string> gpioNames = {"GPIO1"};
184*a005e3e6SPatrick Williams     std::vector<uint64_t> gpioValues = {0};
185*a005e3e6SPatrick Williams     std::string deviceName = "test_device";
186*a005e3e6SPatrick Williams 
187*a005e3e6SPatrick Williams     DevicePresence device(ctx, gpioNames, gpioValues, deviceName, gpioState);
188*a005e3e6SPatrick Williams 
189*a005e3e6SPatrick Williams     sdbusplus::message::object_path objPath = device.getObjPath();
190*a005e3e6SPatrick Williams     std::string expectedPath =
191*a005e3e6SPatrick Williams         "/xyz/openbmc_project/GPIODeviceDetected/" + deviceName;
192*a005e3e6SPatrick Williams 
193*a005e3e6SPatrick Williams     EXPECT_EQ(objPath.str, expectedPath);
194*a005e3e6SPatrick Williams }
195