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