blob: 647290741ca6f378bd313c704b1e1acc56decc9a [file] [log] [blame]
Patrick Williams4fe85a32016-09-08 15:03:56 -05001#include <iostream>
2#include <cassert>
3#include <sdbusplus/message.hpp>
4#include <sdbusplus/bus.hpp>
5
6// Global to share the dbus type string between client and server.
7static std::string verifyTypeString;
8
9using verifyCallback_t = void(*)(sdbusplus::message::message&);
10verifyCallback_t verifyCallback = nullptr;
11
12static constexpr auto SERVICE = "sdbusplus.test";
13static constexpr auto INTERFACE = SERVICE;
14static constexpr auto TEST_METHOD = "test";
15static constexpr auto QUIT_METHOD = "quit";
16
17// Open up the sdbus and claim SERVICE name.
18auto serverInit()
19{
20 auto b = sdbusplus::bus::new_default();
21 b.request_name(SERVICE);
22
23 return std::move(b);
24}
25
26// Thread to run the dbus server.
27void* server(void* b)
28{
29 auto bus = sdbusplus::bus::bus(reinterpret_cast<sdbusplus::bus::busp_t>(b));
30
31 while(1)
32 {
33 // Wait for messages.
34 auto m = bus.process();
35
36 if(!m)
37 {
38 bus.wait();
39 continue;
40 }
41
42 if (m.is_method_call(INTERFACE, TEST_METHOD))
43 {
44 // Verify the message type matches what the test expects.
45 assert(verifyTypeString == m.get_signature());
46
47 if (verifyCallback)
48 {
49
50 verifyCallback(m);
51 verifyCallback = nullptr;
52 }
53 else
54 {
55 std::cout << "Warning: No verification for "
56 << verifyTypeString << std::endl;
57 }
58 // Reply to client.
59 sd_bus_reply_method_return(m.release(), nullptr);
60 }
61 else if (m.is_method_call(INTERFACE, QUIT_METHOD))
62 {
63 // Reply and exit.
64 sd_bus_reply_method_return(m.release(), nullptr);
65 break;
66 }
67 }
68}
69
70auto newMethodCall__test(sdbusplus::bus::bus& b)
71{
72 // Allocate a method-call message for INTERFACE,TEST_METHOD.
73 return b.new_method_call(SERVICE, "/", INTERFACE, TEST_METHOD);
74}
75
76void runTests()
77{
78 using namespace std::literals;
79
80 auto b = sdbusplus::bus::new_default();
81
82 // Test r-value int.
83 {
84 auto m = newMethodCall__test(b);
85 m.append(1);
86 verifyTypeString = "i";
87
88 struct verify
89 {
90 static void op(sdbusplus::message::message& m)
91 {
92 int32_t i = 0;
93 m.read(i);
94 assert(i == 1);
95 }
96 };
97 verifyCallback = &verify::op;
98
99 b.call_noreply(m);
100 }
101 // Test l-value int.
102 {
103 auto m = newMethodCall__test(b);
104 int a = 1;
105 m.append(a, a);
106 verifyTypeString = "ii";
107
108 struct verify
109 {
110 static void op(sdbusplus::message::message& m)
111 {
112 int32_t a = 0, b = 0;
113 m.read(a, b);
114 assert(a == 1);
115 assert(b == 1);
116 }
117 };
118 verifyCallback = &verify::op;
119
120 b.call_noreply(m);
121 }
122
123 // Test multiple ints.
124 {
125 auto m = newMethodCall__test(b);
126 m.append(1, 2, 3, 4, 5);
127 verifyTypeString = "iiiii";
128
129 struct verify
130 {
131 static void op(sdbusplus::message::message& m)
132 {
133 int32_t a = 0, b = 0, c = 0, d = 0, e = 0;
134 m.read(a,b,c,d,e);
135 assert(a == 1);
136 assert(b == 2);
137 assert(c == 3);
138 assert(d == 4);
139 assert(e == 5);
140 }
141 };
142 verifyCallback = &verify::op;
143
144 b.call_noreply(m);
145 }
146
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500147 // Test double and bool.
148 {
149 auto m = newMethodCall__test(b);
150 bool t = true;
151 m.append(t, true, false, 1.1);
152 verifyTypeString = "bbbd";
153
154 struct verify
155 {
156 static void op(sdbusplus::message::message& m)
157 {
158 bool t1, t2, f1;
159 double d;
160 m.read(t1, t2, f1, d);
161 assert(t1);
162 assert(t2);
163 assert(!f1);
164 assert(d == 1.1);
165 }
166 };
167 verifyCallback = &verify::op;
168
169 b.call_noreply(m);
170 }
171
Patrick Williams4fe85a32016-09-08 15:03:56 -0500172 // Test r-value string.
173 {
174 auto m = newMethodCall__test(b);
175 m.append("asdf"s);
176 verifyTypeString = "s";
177
178 struct verify
179 {
180 static void op(sdbusplus::message::message& m)
181 {
182 const char* s = nullptr;
183 m.read(s);
184 assert(0 == strcmp("asdf", s));
185 }
186 };
187 verifyCallback = &verify::op;
188
189 b.call_noreply(m);
190 }
191
192 // Test multiple strings, various forms.
193 {
194 auto m = newMethodCall__test(b);
195 auto str = "jkl;"s;
196 auto str2 = "JKL:"s;
197 m.append(1, "asdf", "ASDF"s, str,
198 std::move(str2), 5);
199 verifyTypeString = "issssi";
200
201 struct verify
202 {
203 static void op(sdbusplus::message::message& m)
204 {
205 int32_t a = 0, b = 0;
206 std::string s0, s1, s2, s3;
207 m.read(a, s0, s1, s2, s3, b);
208 assert(a == 1);
209 assert(b == 5);
210 assert(s0 == "asdf"s);
211 assert(s1 == "ASDF"s);
212 assert(s2 == "jkl;"s);
213 assert(s3 == "JKL:");
214 }
215 };
216 verifyCallback = &verify::op;
217
218 b.call_noreply(m);
219 }
220
Patrick Williams930460c2016-07-20 17:52:55 -0500221 // Test vector.
222 {
223 auto m = newMethodCall__test(b);
224 std::vector<std::string> s{ "1", "2", "3"};
225 m.append(1, s, 2);
226 verifyTypeString = "iasi";
227
228 struct verify
229 {
230 static void op(sdbusplus::message::message& m)
231 {
232 int32_t a = 0;
233 std::vector<std::string> s;
234 m.read(a, s);
235 assert(a == 1);
236 assert(s[0] == "1");
237 assert(s[1] == "2");
238 assert(s[2] == "3");
239 decltype(s) s2 = { "1" , "2" , "3" };
240 assert(s == s2);
241 }
242 };
243 verifyCallback = &verify::op;
244
245 b.call_noreply(m);
246 }
247
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500248 // Test map.
249 {
250 auto m = newMethodCall__test(b);
251 std::map<std::string, int> s = { { "asdf", 3 }, { "jkl;", 4 } };
252 m.append(1, s, 2);
253 verifyTypeString = "ia{si}i";
254
255 struct verify
256 {
257 static void op(sdbusplus::message::message& m)
258 {
259 int32_t a = 0, b = 0;
260 std::map<std::string, int> s{};
261
262 m.read(a, s, b);
263 assert(a == 1);
264 assert(s.size() == 2);
265 assert(s["asdf"] == 3);
266 assert(s["jkl;"] == 4);
267 assert(b == 2);
268 }
269 };
270 verifyCallback = &verify::op;
271
272 b.call_noreply(m);
273 }
274
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500275 // Test tuple.
276 {
277 auto m = newMethodCall__test(b);
278 std::tuple<int, double, std::string> a{ 3, 4.1, "asdf" };
279 m.append(1, a, 2);
280 verifyTypeString = "i(ids)i";
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500281
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500282 struct verify
283 {
284 static void op(sdbusplus::message::message& m)
285 {
286 int32_t a = 0, b = 0;
287 std::tuple<int, double, std::string> c{};
288
289 m.read(a, c, b);
290 assert(a == 1);
291 assert(b == 2);
292 assert(c == std::make_tuple(3, 4.1, "asdf"s));
293 }
294 };
295 verifyCallback = &verify::op;
296
297 b.call_noreply(m);
298 }
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500299
Patrick Williams75596782016-09-11 21:14:10 -0500300 // Test variant.
301 {
302 auto m = newMethodCall__test(b);
303 sdbusplus::message::variant<int, double> a1{3.1}, a2{4};
304 m.append(1, a1, a2, 2);
305 verifyTypeString = "ivvi";
306
307 struct verify
308 {
309 static void op(sdbusplus::message::message& m)
310 {
311 int32_t a, b;
312 sdbusplus::message::variant<int, double> a1{}, a2{};
313
314 m.read(a, a1, a2, b);
315 assert(a == 1);
316 assert(a1 == 3.1);
317 assert(a2 == 4);
318 assert(b == 2);
319 }
320 };
321 verifyCallback = &verify::op;
322
323 b.call_noreply(m);
324 }
325
326 // Test map-variant.
327 {
328 auto m = newMethodCall__test(b);
329 std::map<std::string, sdbusplus::message::variant<int, double>> a1 =
330 { { "asdf", 3 }, { "jkl;", 4.1 } };
331 m.append(1, a1, 2);
332 verifyTypeString = "ia{sv}i";
333
334 struct verify
335 {
336 static void op(sdbusplus::message::message& m)
337 {
338 int32_t a = 0, b = 0;
339 std::map<std::string,
340 sdbusplus::message::variant<int, double>> a1{};
341
342 m.read(a, a1, b);
343 assert(a == 1);
344 assert(a1["asdf"] == 3);
345 assert(a1["jkl;"] == 4.1);
346 assert(b == 2);
347 }
348 };
349 verifyCallback = &verify::op;
350
351 b.call_noreply(m);
352 }
353
354
Patrick Williams4fe85a32016-09-08 15:03:56 -0500355 // Shutdown server.
356 {
357 auto m = b.new_method_call(SERVICE, "/", INTERFACE, QUIT_METHOD);
358 b.call_noreply(m);
359 }
360}
361
362int main()
363{
364
365 // Initialize and start server thread.
366 pthread_t t;
367 {
368 auto b = serverInit();
369 pthread_create(&t, NULL, server, b.release());
370 }
371
372 runTests();
373
374 // Wait for server thread to exit.
375 pthread_join(t, NULL);
376
377 return 0;
378}