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