blob: cd31b6156605361e8c098020ec4c75303cb5aa36 [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>
Ed Tanous28dc36d2018-02-21 12:22:54 -08005#include <unordered_map>
6#include <set>
Patrick Williams4fe85a32016-09-08 15:03:56 -05007
8// Global to share the dbus type string between client and server.
9static std::string verifyTypeString;
10
Andrew Geissler072da3e2018-01-18 07:21:42 -080011using verifyCallback_t = void (*)(sdbusplus::message::message&);
Patrick Williams4fe85a32016-09-08 15:03:56 -050012verifyCallback_t verifyCallback = nullptr;
13
Patrick Williams24fb2962016-11-04 17:08:59 -050014static constexpr auto SERVICE = "sdbusplus.test.message.read";
Patrick Williams4fe85a32016-09-08 15:03:56 -050015static constexpr auto INTERFACE = SERVICE;
16static constexpr auto TEST_METHOD = "test";
17static constexpr auto QUIT_METHOD = "quit";
18
19// Open up the sdbus and claim SERVICE name.
20auto serverInit()
21{
22 auto b = sdbusplus::bus::new_default();
23 b.request_name(SERVICE);
24
25 return std::move(b);
26}
27
28// Thread to run the dbus server.
29void* server(void* b)
30{
31 auto bus = sdbusplus::bus::bus(reinterpret_cast<sdbusplus::bus::busp_t>(b));
32
Andrew Geissler072da3e2018-01-18 07:21:42 -080033 while (1)
Patrick Williams4fe85a32016-09-08 15:03:56 -050034 {
35 // Wait for messages.
36 auto m = bus.process();
37
Andrew Geissler072da3e2018-01-18 07:21:42 -080038 if (!m)
Patrick Williams4fe85a32016-09-08 15:03:56 -050039 {
40 bus.wait();
41 continue;
42 }
43
44 if (m.is_method_call(INTERFACE, TEST_METHOD))
45 {
46 // Verify the message type matches what the test expects.
47 assert(verifyTypeString == m.get_signature());
48
49 if (verifyCallback)
50 {
51
52 verifyCallback(m);
53 verifyCallback = nullptr;
54 }
55 else
56 {
Andrew Geissler072da3e2018-01-18 07:21:42 -080057 std::cout << "Warning: No verification for " << verifyTypeString
58 << std::endl;
Patrick Williams4fe85a32016-09-08 15:03:56 -050059 }
60 // Reply to client.
61 sd_bus_reply_method_return(m.release(), nullptr);
62 }
63 else if (m.is_method_call(INTERFACE, QUIT_METHOD))
64 {
65 // Reply and exit.
66 sd_bus_reply_method_return(m.release(), nullptr);
67 break;
68 }
69 }
Patrick Williams696e3152016-11-04 17:03:39 -050070
71 return nullptr;
Patrick Williams4fe85a32016-09-08 15:03:56 -050072}
73
74auto newMethodCall__test(sdbusplus::bus::bus& b)
75{
76 // Allocate a method-call message for INTERFACE,TEST_METHOD.
77 return b.new_method_call(SERVICE, "/", INTERFACE, TEST_METHOD);
78}
79
80void runTests()
81{
82 using namespace std::literals;
83
84 auto b = sdbusplus::bus::new_default();
85
86 // Test r-value int.
87 {
88 auto m = newMethodCall__test(b);
89 m.append(1);
90 verifyTypeString = "i";
91
92 struct verify
93 {
94 static void op(sdbusplus::message::message& m)
95 {
96 int32_t i = 0;
97 m.read(i);
98 assert(i == 1);
99 }
100 };
101 verifyCallback = &verify::op;
102
103 b.call_noreply(m);
104 }
105 // Test l-value int.
106 {
107 auto m = newMethodCall__test(b);
108 int a = 1;
109 m.append(a, a);
110 verifyTypeString = "ii";
111
112 struct verify
113 {
114 static void op(sdbusplus::message::message& m)
115 {
116 int32_t a = 0, b = 0;
117 m.read(a, b);
118 assert(a == 1);
119 assert(b == 1);
120 }
121 };
122 verifyCallback = &verify::op;
123
124 b.call_noreply(m);
125 }
126
127 // Test multiple ints.
128 {
129 auto m = newMethodCall__test(b);
130 m.append(1, 2, 3, 4, 5);
131 verifyTypeString = "iiiii";
132
133 struct verify
134 {
135 static void op(sdbusplus::message::message& m)
136 {
137 int32_t a = 0, b = 0, c = 0, d = 0, e = 0;
Andrew Geissler072da3e2018-01-18 07:21:42 -0800138 m.read(a, b, c, d, e);
Patrick Williams4fe85a32016-09-08 15:03:56 -0500139 assert(a == 1);
140 assert(b == 2);
141 assert(c == 3);
142 assert(d == 4);
143 assert(e == 5);
144 }
145 };
146 verifyCallback = &verify::op;
147
148 b.call_noreply(m);
149 }
150
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500151 // Test double and bool.
152 {
153 auto m = newMethodCall__test(b);
154 bool t = true;
Patrick Williamsb760a992016-11-28 11:26:55 -0600155 bool f = false;
156 bool f2 = false;
157 m.append(t, true, f, std::move(f2), false, 1.1);
158 verifyTypeString = "bbbbbd";
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500159
160 struct verify
161 {
162 static void op(sdbusplus::message::message& m)
163 {
Patrick Williamsb760a992016-11-28 11:26:55 -0600164 bool t1, t2, f1, f2, f3;
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500165 double d;
Patrick Williamsb760a992016-11-28 11:26:55 -0600166 m.read(t1, t2, f1, f2, f3, d);
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500167 assert(t1);
168 assert(t2);
169 assert(!f1);
Patrick Williamsb760a992016-11-28 11:26:55 -0600170 assert(!f2);
171 assert(!f3);
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500172 assert(d == 1.1);
173 }
174 };
175 verifyCallback = &verify::op;
176
177 b.call_noreply(m);
178 }
179
Patrick Williams4fe85a32016-09-08 15:03:56 -0500180 // Test r-value string.
181 {
182 auto m = newMethodCall__test(b);
183 m.append("asdf"s);
184 verifyTypeString = "s";
185
186 struct verify
187 {
188 static void op(sdbusplus::message::message& m)
189 {
190 const char* s = nullptr;
191 m.read(s);
192 assert(0 == strcmp("asdf", s));
193 }
194 };
195 verifyCallback = &verify::op;
196
197 b.call_noreply(m);
198 }
199
200 // Test multiple strings, various forms.
201 {
202 auto m = newMethodCall__test(b);
203 auto str = "jkl;"s;
204 auto str2 = "JKL:"s;
Andrew Geissler072da3e2018-01-18 07:21:42 -0800205 m.append(1, "asdf", "ASDF"s, str, std::move(str2), 5);
Patrick Williams4fe85a32016-09-08 15:03:56 -0500206 verifyTypeString = "issssi";
207
208 struct verify
209 {
210 static void op(sdbusplus::message::message& m)
211 {
212 int32_t a = 0, b = 0;
213 std::string s0, s1, s2, s3;
214 m.read(a, s0, s1, s2, s3, b);
215 assert(a == 1);
216 assert(b == 5);
217 assert(s0 == "asdf"s);
218 assert(s1 == "ASDF"s);
219 assert(s2 == "jkl;"s);
220 assert(s3 == "JKL:");
221 }
222 };
223 verifyCallback = &verify::op;
224
225 b.call_noreply(m);
226 }
227
Patrick Williams572a8ea2017-01-06 16:23:14 -0600228 // Test object_path and signature.
229 {
230 auto m = newMethodCall__test(b);
231 auto o = sdbusplus::message::object_path("/asdf");
232 auto s = sdbusplus::message::signature("iii");
233 m.append(1, o, s, 4);
234 verifyTypeString = "iogi";
235
236 struct verify
237 {
238 static void op(sdbusplus::message::message& m)
239 {
240 int32_t a = 0, b = 0;
241 sdbusplus::message::object_path o;
242 sdbusplus::message::signature s;
243 m.read(a, o, s, b);
244 assert(a == 1);
245 assert(b == 4);
246 assert(std::string(o) == "/asdf"s);
247 assert(std::string(s) == "iii"s);
248 }
249 };
250 verifyCallback = &verify::op;
251
252 b.call_noreply(m);
253 }
254
Patrick Williams930460c2016-07-20 17:52:55 -0500255 // Test vector.
256 {
257 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800258 std::vector<std::string> s{"1", "2", "3"};
Patrick Williams930460c2016-07-20 17:52:55 -0500259 m.append(1, s, 2);
260 verifyTypeString = "iasi";
261
262 struct verify
263 {
264 static void op(sdbusplus::message::message& m)
265 {
266 int32_t a = 0;
267 std::vector<std::string> s;
268 m.read(a, s);
269 assert(a == 1);
270 assert(s[0] == "1");
271 assert(s[1] == "2");
272 assert(s[2] == "3");
Andrew Geissler072da3e2018-01-18 07:21:42 -0800273 decltype(s) s2 = {"1", "2", "3"};
Patrick Williams930460c2016-07-20 17:52:55 -0500274 assert(s == s2);
275 }
276 };
277 verifyCallback = &verify::op;
278
279 b.call_noreply(m);
280 }
281
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500282 // Test map.
283 {
284 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800285 std::map<std::string, int> s = {{"asdf", 3}, {"jkl;", 4}};
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500286 m.append(1, s, 2);
287 verifyTypeString = "ia{si}i";
288
289 struct verify
290 {
291 static void op(sdbusplus::message::message& m)
292 {
293 int32_t a = 0, b = 0;
294 std::map<std::string, int> s{};
295
296 m.read(a, s, b);
297 assert(a == 1);
298 assert(s.size() == 2);
299 assert(s["asdf"] == 3);
300 assert(s["jkl;"] == 4);
301 assert(b == 2);
302 }
303 };
304 verifyCallback = &verify::op;
305
306 b.call_noreply(m);
307 }
308
Ed Tanous28dc36d2018-02-21 12:22:54 -0800309 // Test unordered_map.
310 {
311 auto m = newMethodCall__test(b);
312 std::unordered_map<std::string, int> s = {{"asdf", 3}, {"jkl;", 4}};
313 m.append(1, s, 2);
314 verifyTypeString = "ia{si}i";
315
316 struct verify
317 {
318 static void op(sdbusplus::message::message& m)
319 {
320 int32_t a = 0, b = 0;
321 std::unordered_map<std::string, int> s{};
322
323 m.read(a, s, b);
324 assert(a == 1);
325 assert(s.size() == 2);
326 assert(s["asdf"] == 3);
327 assert(s["jkl;"] == 4);
328 assert(b == 2);
329 }
330 };
331 verifyCallback = &verify::op;
332
333 b.call_noreply(m);
334 }
335
336 // Test set.
337 {
338 auto m = newMethodCall__test(b);
339 std::set<std::string> s = {{"asdf"}, {"jkl;"}};
340 m.append(1, s, 2);
341 verifyTypeString = "iasi";
342
343 struct verify
344 {
345 static void op(sdbusplus::message::message& m)
346 {
347 int32_t a = 0, b = 0;
348 std::set<std::string> s{};
349
350 m.read(a, s, b);
351 assert(a == 1);
352 assert(s.size() == 2);
353 assert(s.find("asdf") != s.end());
354 assert(s.find("jkl;") != s.end());
355 assert(b == 2);
356 }
357 };
358 verifyCallback = &verify::op;
359
360 b.call_noreply(m);
361 }
362
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500363 // Test tuple.
364 {
365 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800366 std::tuple<int, double, std::string> a{3, 4.1, "asdf"};
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500367 m.append(1, a, 2);
368 verifyTypeString = "i(ids)i";
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500369
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500370 struct verify
371 {
372 static void op(sdbusplus::message::message& m)
373 {
374 int32_t a = 0, b = 0;
375 std::tuple<int, double, std::string> c{};
376
377 m.read(a, c, b);
378 assert(a == 1);
379 assert(b == 2);
380 assert(c == std::make_tuple(3, 4.1, "asdf"s));
381 }
382 };
383 verifyCallback = &verify::op;
384
385 b.call_noreply(m);
386 }
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500387
Patrick Williams75596782016-09-11 21:14:10 -0500388 // Test variant.
389 {
390 auto m = newMethodCall__test(b);
391 sdbusplus::message::variant<int, double> a1{3.1}, a2{4};
392 m.append(1, a1, a2, 2);
393 verifyTypeString = "ivvi";
394
395 struct verify
396 {
397 static void op(sdbusplus::message::message& m)
398 {
399 int32_t a, b;
400 sdbusplus::message::variant<int, double> a1{}, a2{};
401
402 m.read(a, a1, a2, b);
403 assert(a == 1);
404 assert(a1 == 3.1);
405 assert(a2 == 4);
406 assert(b == 2);
407 }
408 };
409 verifyCallback = &verify::op;
410
411 b.call_noreply(m);
412 }
413
Patrick Williamsf101ee22016-11-04 17:44:04 -0500414 // Test variant with missing/wrong type.
415 {
416 auto m = newMethodCall__test(b);
417 sdbusplus::message::variant<uint64_t, double> a1{3.1}, a2{uint64_t(4)};
418 m.append(1, a1, a2, 2);
419 verifyTypeString = "ivvi";
420
421 struct verify
422 {
423 static void op(sdbusplus::message::message& m)
424 {
425 int32_t a, b;
426 sdbusplus::message::variant<uint8_t, double> a1{}, a2{};
427
428 m.read(a, a1, a2, b);
429 assert(a == 1);
430 assert(a1 == 3.1);
431 assert(a2 == uint8_t());
432 assert(b == 2);
433 }
434 };
435 verifyCallback = &verify::op;
436
437 b.call_noreply(m);
438 }
439
Patrick Williams75596782016-09-11 21:14:10 -0500440 // Test map-variant.
441 {
442 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800443 std::map<std::string, sdbusplus::message::variant<int, double>> a1 = {
444 {"asdf", 3}, {"jkl;", 4.1}};
Patrick Williams75596782016-09-11 21:14:10 -0500445 m.append(1, a1, 2);
446 verifyTypeString = "ia{sv}i";
447
448 struct verify
449 {
450 static void op(sdbusplus::message::message& m)
451 {
452 int32_t a = 0, b = 0;
Andrew Geissler072da3e2018-01-18 07:21:42 -0800453 std::map<std::string, sdbusplus::message::variant<int, double>>
454 a1{};
Patrick Williams75596782016-09-11 21:14:10 -0500455
456 m.read(a, a1, b);
457 assert(a == 1);
458 assert(a1["asdf"] == 3);
459 assert(a1["jkl;"] == 4.1);
460 assert(b == 2);
461 }
462 };
463 verifyCallback = &verify::op;
464
465 b.call_noreply(m);
466 }
467
Patrick Williams4fe85a32016-09-08 15:03:56 -0500468 // Shutdown server.
469 {
470 auto m = b.new_method_call(SERVICE, "/", INTERFACE, QUIT_METHOD);
471 b.call_noreply(m);
472 }
473}
474
475int main()
476{
477
478 // Initialize and start server thread.
479 pthread_t t;
480 {
481 auto b = serverInit();
482 pthread_create(&t, NULL, server, b.release());
483 }
484
485 runTests();
486
487 // Wait for server thread to exit.
488 pthread_join(t, NULL);
489
490 return 0;
491}