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