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