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
requestStop(sdbusplus::async::context & io)12 auto requestStop(sdbusplus::async::context& io) -> sdbusplus::async::task<>
13 {
14 io.request_stop();
15 co_return;
16 }
17
TEST(GpioPresence,ConstructionSucceeds)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
TEST(GpioPresence,AcceptConfig1Gpio)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
testDevicePresentDbus(sdbusplus::async::context & ctx)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
TEST(GpioPresence,DevicePresentDbus)108 TEST(GpioPresence, DevicePresentDbus)
109 {
110 sdbusplus::async::context ctx;
111 ctx.spawn(testDevicePresentDbus(ctx));
112 ctx.run();
113 }
114
testDevicePresentThenDisappearDbus(sdbusplus::async::context & ctx)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
TEST(GpioPresence,DevicePresentThenDisappearDbus)171 TEST(GpioPresence, DevicePresentThenDisappearDbus)
172 {
173 sdbusplus::async::context ctx;
174 ctx.spawn(testDevicePresentThenDisappearDbus(ctx));
175 ctx.run();
176 }
177