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