|  | #include "gpio-presence/device_presence.hpp" | 
|  | #include "gpio-presence/gpio_presence_manager.hpp" | 
|  |  | 
|  | #include <gpiod.hpp> | 
|  | #include <phosphor-logging/lg2.hpp> | 
|  | #include <xyz/openbmc_project/Inventory/Source/DevicePresence/client.hpp> | 
|  |  | 
|  | #include <gtest/gtest.h> | 
|  |  | 
|  | using namespace gpio_presence; | 
|  |  | 
|  | auto requestStop(sdbusplus::async::context& io) -> sdbusplus::async::task<> | 
|  | { | 
|  | io.request_stop(); | 
|  | co_return; | 
|  | } | 
|  |  | 
|  | TEST(GpioPresence, ConstructionSucceeds) | 
|  | { | 
|  | sdbusplus::async::context ctx; | 
|  |  | 
|  | gpio_presence::GPIOPresenceManager s(ctx); | 
|  |  | 
|  | ctx.spawn(requestStop(ctx)); | 
|  | ctx.run(); | 
|  | } | 
|  |  | 
|  | TEST(GpioPresence, AcceptConfig1Gpio) | 
|  | { | 
|  | sdbusplus::async::context ctx; | 
|  |  | 
|  | gpio_presence::GPIOPresenceManager sensor(ctx); | 
|  |  | 
|  | std::string name = "cable0"; | 
|  | std::string gpioName = "TEST_GPIO"; | 
|  |  | 
|  | std::vector<std::string> gpioNames = {gpioName}; | 
|  | std::vector<uint64_t> gpioValues = {0}; | 
|  |  | 
|  | auto c = std::make_unique<gpio_presence::DevicePresence>( | 
|  | ctx, gpioNames, gpioValues, name, sensor.gpioState); | 
|  |  | 
|  | sensor.addConfig(name, std::move(c)); | 
|  |  | 
|  | sensor.updatePresence(gpioName, false); | 
|  |  | 
|  | EXPECT_EQ(sensor.getPresence(name), true); | 
|  |  | 
|  | sensor.updatePresence(gpioName, true); | 
|  |  | 
|  | EXPECT_EQ(sensor.getPresence(name), false); | 
|  |  | 
|  | ctx.spawn(requestStop(ctx)); | 
|  | ctx.run(); | 
|  | } | 
|  |  | 
|  | auto testDevicePresentDbus(sdbusplus::async::context& ctx) | 
|  | -> sdbusplus::async::task<> | 
|  | { | 
|  | gpio_presence::GPIOPresenceManager sensor(ctx); | 
|  |  | 
|  | std::string busName = sensor.setupBusName(); | 
|  |  | 
|  | std::string name = "cable0"; | 
|  | std::string gpioName = "TEST_GPIO"; | 
|  |  | 
|  | std::vector<std::string> gpioNames = {gpioName}; | 
|  | std::vector<uint64_t> gpioValues = {0}; | 
|  |  | 
|  | auto c = std::make_unique<gpio_presence::DevicePresence>( | 
|  | ctx, gpioNames, gpioValues, name, sensor.gpioState); | 
|  |  | 
|  | sdbusplus::message::object_path objPath = c->getObjPath(); | 
|  |  | 
|  | sensor.addConfig(name, std::move(c)); | 
|  |  | 
|  | sensor.updatePresence(gpioName, false); | 
|  |  | 
|  | lg2::debug("found obj path {OBJPATH}", "OBJPATH", objPath); | 
|  |  | 
|  | auto client = sdbusplus::client::xyz::openbmc_project::inventory::source:: | 
|  | DevicePresence<>(ctx) | 
|  | .service(busName) | 
|  | .path(objPath.str); | 
|  |  | 
|  | std::string nameFound = co_await client.name(); | 
|  |  | 
|  | assert(nameFound == "cable0"); | 
|  |  | 
|  | ctx.request_stop(); | 
|  |  | 
|  | co_return; | 
|  | } | 
|  |  | 
|  | TEST(GpioPresence, DevicePresentDbus) | 
|  | { | 
|  | sdbusplus::async::context ctx; | 
|  | ctx.spawn(testDevicePresentDbus(ctx)); | 
|  | ctx.run(); | 
|  | } | 
|  |  | 
|  | auto testDevicePresentThenDisappearDbus(sdbusplus::async::context& ctx) | 
|  | -> sdbusplus::async::task<> | 
|  | { | 
|  | gpio_presence::GPIOPresenceManager sensor(ctx); | 
|  |  | 
|  | std::string busName = sensor.setupBusName(); | 
|  |  | 
|  | std::string name = "cable0"; | 
|  | std::string gpioName = "TEST_GPIO"; | 
|  |  | 
|  | std::vector<std::string> gpioNames = {gpioName}; | 
|  | std::vector<uint64_t> gpioValues = {0}; | 
|  |  | 
|  | auto c = std::make_unique<gpio_presence::DevicePresence>( | 
|  | ctx, gpioNames, gpioValues, name, sensor.gpioState); | 
|  |  | 
|  | sdbusplus::message::object_path objPath = c->getObjPath(); | 
|  |  | 
|  | sensor.addConfig(name, std::move(c)); | 
|  |  | 
|  | sensor.updatePresence(gpioName, false); | 
|  |  | 
|  | lg2::debug("found obj path {OBJPATH}", "OBJPATH", objPath); | 
|  |  | 
|  | auto client = sdbusplus::client::xyz::openbmc_project::inventory::source:: | 
|  | DevicePresence<>(ctx) | 
|  | .service(busName) | 
|  | .path(objPath.str); | 
|  |  | 
|  | std::string nameFound = co_await client.name(); | 
|  |  | 
|  | assert(nameFound == "cable0"); | 
|  |  | 
|  | // gpio goes high, cable 0 should disappear | 
|  | sensor.updatePresence(gpioName, true); | 
|  |  | 
|  | try | 
|  | { | 
|  | co_await client.name(); | 
|  | assert(false); | 
|  | } | 
|  | catch (std::exception& _) | 
|  | { | 
|  | // expected, since cable 0 is gone. | 
|  | // have to do something here to shut up clang-tidy | 
|  | lg2::info(""); | 
|  | } | 
|  |  | 
|  | ctx.request_stop(); | 
|  |  | 
|  | co_return; | 
|  | } | 
|  |  | 
|  | TEST(GpioPresence, DevicePresentThenDisappearDbus) | 
|  | { | 
|  | sdbusplus::async::context ctx; | 
|  | ctx.spawn(testDevicePresentThenDisappearDbus(ctx)); | 
|  | ctx.run(); | 
|  | } |