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 #include <xyz/openbmc_project/Inventory/Source/DevicePresence/client.hpp> 7 8 #include <gtest/gtest.h> 9 10 using namespace gpio_presence; 11 12 auto requestStop(sdbusplus::async::context& io) -> sdbusplus::async::task<> 13 { 14 io.request_stop(); 15 co_return; 16 } 17 18 TEST(GpioPresence, ConstructionSucceeds) 19 { 20 sdbusplus::async::context ctx; 21 22 gpio_presence::GPIOPresenceManager s(ctx); 23 24 ctx.spawn(requestStop(ctx)); 25 ctx.run(); 26 } 27 28 TEST(GpioPresence, AcceptConfig1Gpio) 29 { 30 sdbusplus::async::context ctx; 31 32 gpio_presence::GPIOPresenceManager sensor(ctx); 33 34 std::string name = "cable0"; 35 std::string gpioName = "TEST_GPIO"; 36 37 std::vector<std::string> gpioNames = {gpioName}; 38 std::vector<uint64_t> gpioValues = {0}; 39 40 std::vector<std::string> parentInvCompatible = {}; 41 42 auto c = std::make_unique<gpio_presence::DevicePresence>( 43 ctx, gpioNames, gpioValues, name, sensor.gpioState, 44 parentInvCompatible); 45 46 sensor.addConfig(name, std::move(c)); 47 48 sensor.updatePresence(gpioName, false); 49 50 EXPECT_EQ(sensor.getPresence(name), true); 51 52 sensor.updatePresence(gpioName, true); 53 54 EXPECT_EQ(sensor.getPresence(name), false); 55 56 ctx.spawn(requestStop(ctx)); 57 ctx.run(); 58 } 59 60 auto testDevicePresentDbus(sdbusplus::async::context& ctx) 61 -> sdbusplus::async::task<> 62 { 63 gpio_presence::GPIOPresenceManager sensor(ctx); 64 65 std::string busName = sensor.setupBusName(); 66 67 std::string name = "cable0"; 68 std::string gpioName = "TEST_GPIO"; 69 70 std::vector<std::string> gpioNames = {gpioName}; 71 std::vector<uint64_t> gpioValues = {0}; 72 73 std::vector<std::string> parentInvCompatible = { 74 "com.ibm.Hardware.Chassis.Model.BlueRidge4U", 75 "com.ibm.Hardware.Chassis.Model.BlueRidge", 76 }; 77 78 auto c = std::make_unique<gpio_presence::DevicePresence>( 79 ctx, gpioNames, gpioValues, name, sensor.gpioState, 80 parentInvCompatible); 81 82 sdbusplus::message::object_path objPath = c->getObjPath(); 83 84 sensor.addConfig(name, std::move(c)); 85 86 sensor.updatePresence(gpioName, false); 87 88 lg2::debug("found obj path {OBJPATH}", "OBJPATH", objPath); 89 90 auto client = sdbusplus::client::xyz::openbmc_project::inventory::source:: 91 DevicePresence<>(ctx) 92 .service(busName) 93 .path(objPath.str); 94 95 std::string nameFound = co_await client.name(); 96 97 assert(nameFound == "cable0"); 98 99 auto compatibleFound = co_await client.compatible(); 100 101 EXPECT_EQ(compatibleFound, "com.ibm.Hardware.Chassis.Model.BlueRidge4U"); 102 103 ctx.request_stop(); 104 105 co_return; 106 } 107 108 TEST(GpioPresence, DevicePresentDbus) 109 { 110 sdbusplus::async::context ctx; 111 ctx.spawn(testDevicePresentDbus(ctx)); 112 ctx.run(); 113 } 114 115 auto testDevicePresentThenDisappearDbus(sdbusplus::async::context& ctx) 116 -> sdbusplus::async::task<> 117 { 118 gpio_presence::GPIOPresenceManager sensor(ctx); 119 120 std::string busName = sensor.setupBusName(); 121 122 std::string name = "cable0"; 123 std::string gpioName = "TEST_GPIO"; 124 125 std::vector<std::string> gpioNames = {gpioName}; 126 std::vector<uint64_t> gpioValues = {0}; 127 128 std::vector<std::string> parentInvCompatible = {}; 129 130 auto c = std::make_unique<gpio_presence::DevicePresence>( 131 ctx, gpioNames, gpioValues, name, sensor.gpioState, 132 parentInvCompatible); 133 134 sdbusplus::message::object_path objPath = c->getObjPath(); 135 136 sensor.addConfig(name, std::move(c)); 137 138 sensor.updatePresence(gpioName, false); 139 140 lg2::debug("found obj path {OBJPATH}", "OBJPATH", objPath); 141 142 auto client = sdbusplus::client::xyz::openbmc_project::inventory::source:: 143 DevicePresence<>(ctx) 144 .service(busName) 145 .path(objPath.str); 146 147 std::string nameFound = co_await client.name(); 148 149 assert(nameFound == "cable0"); 150 151 // gpio goes high, cable 0 should disappear 152 sensor.updatePresence(gpioName, true); 153 154 try 155 { 156 co_await client.name(); 157 assert(false); 158 } 159 catch (std::exception& _) 160 { 161 // expected, since cable 0 is gone. 162 // have to do something here to shut up clang-tidy 163 lg2::info(""); 164 } 165 166 ctx.request_stop(); 167 168 co_return; 169 } 170 171 TEST(GpioPresence, DevicePresentThenDisappearDbus) 172 { 173 sdbusplus::async::context ctx; 174 ctx.spawn(testDevicePresentThenDisappearDbus(ctx)); 175 ctx.run(); 176 } 177