blob: b067e1861a5c732aed1370a67c44c993b169cd4a [file] [log] [blame]
Patrick Williams1807fa42016-08-01 22:23:30 -05001#include <iostream>
Patrick Williams1807fa42016-08-01 22:23:30 -05002#include <cassert>
Patrick Williams7802c072016-09-02 15:20:22 -05003#include <sdbusplus/message.hpp>
Patrick Williams5b485792016-08-02 07:35:14 -05004#include <sdbusplus/bus.hpp>
Ed Tanous28dc36d2018-02-21 12:22:54 -08005#include <unordered_map>
6#include <set>
Patrick Williams1807fa42016-08-01 22:23:30 -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 (*)(sd_bus_message*);
Patrick Williams07e1d6f2016-09-08 15:54:09 -050012verifyCallback_t verifyCallback = nullptr;
13
Patrick Williams24fb2962016-11-04 17:08:59 -050014static constexpr auto SERVICE = "sdbusplus.test.message.append";
Patrick Williams1807fa42016-08-01 22:23:30 -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.
Patrick Williams5b485792016-08-02 07:35:14 -050020auto serverInit()
Patrick Williams1807fa42016-08-01 22:23:30 -050021{
Patrick Williams5b485792016-08-02 07:35:14 -050022 auto b = sdbusplus::bus::new_default();
23 b.request_name(SERVICE);
24
25 return std::move(b);
Patrick Williams1807fa42016-08-01 22:23:30 -050026}
27
28// Thread to run the dbus server.
29void* server(void* b)
30{
William A. Kennington IIIb5645502018-06-19 18:36:41 -070031 auto bus = sdbusplus::bus::bus(reinterpret_cast<sdbusplus::bus::busp_t>(b),
32 std::false_type());
Patrick Williams1807fa42016-08-01 22:23:30 -050033
Andrew Geissler072da3e2018-01-18 07:21:42 -080034 while (1)
Patrick Williams1807fa42016-08-01 22:23:30 -050035 {
36 // Wait for messages.
Patrick Williams13b97c52016-09-09 09:36:55 -050037 auto m = bus.process().release();
Patrick Williams1807fa42016-08-01 22:23:30 -050038
Andrew Geissler072da3e2018-01-18 07:21:42 -080039 if (m == nullptr)
Patrick Williams1807fa42016-08-01 22:23:30 -050040 {
Patrick Williams5b485792016-08-02 07:35:14 -050041 bus.wait();
Patrick Williams1807fa42016-08-01 22:23:30 -050042 continue;
43 }
44
45 if (sd_bus_message_is_method_call(m, INTERFACE, TEST_METHOD))
46 {
47 // Verify the message type matches what the test expects.
Patrick Williams1807fa42016-08-01 22:23:30 -050048 assert(verifyTypeString == sd_bus_message_get_signature(m, true));
Patrick Williams07e1d6f2016-09-08 15:54:09 -050049 if (verifyCallback)
50 {
51 verifyCallback(m);
52 verifyCallback = nullptr;
53 }
54 else
55 {
Andrew Geissler072da3e2018-01-18 07:21:42 -080056 std::cout << "Warning: No verification for " << verifyTypeString
57 << std::endl;
Patrick Williams07e1d6f2016-09-08 15:54:09 -050058 }
Patrick Williams1807fa42016-08-01 22:23:30 -050059 // Reply to client.
60 sd_bus_reply_method_return(m, nullptr);
61 }
62 else if (sd_bus_message_is_method_call(m, INTERFACE, QUIT_METHOD))
63 {
64 // Reply and exit.
65 sd_bus_reply_method_return(m, nullptr);
William A. Kennington IIIb5645502018-06-19 18:36:41 -070066 sd_bus_message_unref(m);
Patrick Williams1807fa42016-08-01 22:23:30 -050067 break;
68 }
William A. Kennington IIIb5645502018-06-19 18:36:41 -070069
70 sd_bus_message_unref(m);
Patrick Williams1807fa42016-08-01 22:23:30 -050071 }
Patrick Williams696e3152016-11-04 17:03:39 -050072
73 return nullptr;
Patrick Williams1807fa42016-08-01 22:23:30 -050074}
75
Patrick Williams7802c072016-09-02 15:20:22 -050076auto newMethodCall__test(sdbusplus::bus::bus& b)
Patrick Williams1807fa42016-08-01 22:23:30 -050077{
78 // Allocate a method-call message for INTERFACE,TEST_METHOD.
Patrick Williams7802c072016-09-02 15:20:22 -050079 return b.new_method_call(SERVICE, "/", INTERFACE, TEST_METHOD);
Patrick Williams1807fa42016-08-01 22:23:30 -050080}
81
82void runTests()
83{
84 using namespace std::literals;
85
Patrick Williams5b485792016-08-02 07:35:14 -050086 auto b = sdbusplus::bus::new_default();
Patrick Williams1807fa42016-08-01 22:23:30 -050087
88 // Test r-value int.
89 {
Patrick Williams7802c072016-09-02 15:20:22 -050090 auto m = newMethodCall__test(b);
91 m.append(1);
Patrick Williams1807fa42016-08-01 22:23:30 -050092 verifyTypeString = "i";
Patrick Williams07e1d6f2016-09-08 15:54:09 -050093
94 struct verify
95 {
96 static void op(sd_bus_message* m)
97 {
98 int32_t i = 0;
99 sd_bus_message_read_basic(m, 'i', &i);
100 assert(i == 1);
101 }
102 };
103 verifyCallback = &verify::op;
104
Patrick Williams5b485792016-08-02 07:35:14 -0500105 b.call_noreply(m);
Patrick Williams1807fa42016-08-01 22:23:30 -0500106 }
Patrick Williams1807fa42016-08-01 22:23:30 -0500107 // Test l-value int.
108 {
Patrick Williams7802c072016-09-02 15:20:22 -0500109 auto m = newMethodCall__test(b);
Patrick Williams1807fa42016-08-01 22:23:30 -0500110 int a = 1;
Patrick Williams7802c072016-09-02 15:20:22 -0500111 m.append(a, a);
Patrick Williams1807fa42016-08-01 22:23:30 -0500112 verifyTypeString = "ii";
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500113
114 struct verify
115 {
116 static void op(sd_bus_message* m)
117 {
118 int32_t a = 0, b = 0;
119 sd_bus_message_read(m, "ii", &a, &b);
120 assert(a == 1);
121 assert(b == 1);
122 }
123 };
124 verifyCallback = &verify::op;
125
Patrick Williams5b485792016-08-02 07:35:14 -0500126 b.call_noreply(m);
Patrick Williams1807fa42016-08-01 22:23:30 -0500127 }
128
129 // Test multiple ints.
130 {
Patrick Williams7802c072016-09-02 15:20:22 -0500131 auto m = newMethodCall__test(b);
132 m.append(1, 2, 3, 4, 5);
Patrick Williams1807fa42016-08-01 22:23:30 -0500133 verifyTypeString = "iiiii";
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500134
135 struct verify
136 {
137 static void op(sd_bus_message* m)
138 {
139 int32_t a = 0, b = 0, c = 0, d = 0, e = 0;
140 sd_bus_message_read(m, "iiiii", &a, &b, &c, &d, &e);
141 assert(a == 1);
142 assert(b == 2);
143 assert(c == 3);
144 assert(d == 4);
145 assert(e == 5);
146 }
147 };
148 verifyCallback = &verify::op;
149
Patrick Williams5b485792016-08-02 07:35:14 -0500150 b.call_noreply(m);
Patrick Williams1807fa42016-08-01 22:23:30 -0500151 }
152
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500153 // Test double and bool.
154 {
155 auto m = newMethodCall__test(b);
156 bool t = true;
Patrick Williamsb760a992016-11-28 11:26:55 -0600157 bool f = false;
158 bool f2 = false;
159 m.append(t, true, f, std::move(f2), false, 1.1);
160 verifyTypeString = "bbbbbd";
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500161
162 struct verify
163 {
164 static void op(sd_bus_message* m)
165 {
Patrick Williamsb760a992016-11-28 11:26:55 -0600166 bool t1, t2, f1, f2, f3;
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500167 double d;
Patrick Williamsb760a992016-11-28 11:26:55 -0600168 sd_bus_message_read(m, "bbbbbd", &t1, &t2, &f1, &f2, &f3, &d);
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500169 assert(t1);
170 assert(t2);
171 assert(!f1);
Patrick Williamsb760a992016-11-28 11:26:55 -0600172 assert(!f2);
173 assert(!f3);
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500174 assert(d == 1.1);
175 }
176 };
177 verifyCallback = &verify::op;
178
179 b.call_noreply(m);
180 }
181
Patrick Williams1807fa42016-08-01 22:23:30 -0500182 // Test r-value string.
183 {
Patrick Williams7802c072016-09-02 15:20:22 -0500184 auto m = newMethodCall__test(b);
185 m.append("asdf"s);
Patrick Williams1807fa42016-08-01 22:23:30 -0500186 verifyTypeString = "s";
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500187
188 struct verify
189 {
190 static void op(sd_bus_message* m)
191 {
192 const char* s = nullptr;
193 sd_bus_message_read_basic(m, 's', &s);
194 assert(0 == strcmp("asdf", s));
195 }
196 };
197 verifyCallback = &verify::op;
198
Patrick Williams5b485792016-08-02 07:35:14 -0500199 b.call_noreply(m);
Patrick Williams1807fa42016-08-01 22:23:30 -0500200 }
201
Patrick Williams16e17532017-02-15 10:23:22 -0600202 // Test const string owned by const struct. openbmc/openbmc#1025
203 {
204 struct
205 {
206 const char* foo;
207
208 void insert(sdbusplus::message::message& m)
209 {
210 m.append(foo);
211 }
212 } s;
213
214 auto m = newMethodCall__test(b);
215 s.foo = "1234";
216 s.insert(m);
217
218 verifyTypeString = "s";
219
220 struct verify
221 {
222 static void op(sd_bus_message* m)
223 {
224 const char* s = nullptr;
225 sd_bus_message_read_basic(m, 's', &s);
226 assert(0 == strcmp("1234", s));
227 }
228 };
229 verifyCallback = &verify::op;
230
231 b.call_noreply(m);
232 }
233
Patrick Williams1807fa42016-08-01 22:23:30 -0500234 // Test multiple strings, various forms.
235 {
Patrick Williams7802c072016-09-02 15:20:22 -0500236 auto m = newMethodCall__test(b);
Patrick Williams1807fa42016-08-01 22:23:30 -0500237 auto str = "jkl;"s;
238 auto str2 = "JKL:"s;
Patrick Williams16e17532017-02-15 10:23:22 -0600239 const char* str3 = "1234";
240 const char* const str4 = "5678";
241 const auto str5 = "!@#$";
Andrew Geissler072da3e2018-01-18 07:21:42 -0800242 m.append(1, "asdf", "ASDF"s, str, std::move(str2), str3, str4, str5, 5);
Patrick Williams16e17532017-02-15 10:23:22 -0600243 verifyTypeString = "isssssssi";
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500244
245 struct verify
246 {
247 static void op(sd_bus_message* m)
248 {
249 int32_t a = 0, b = 0;
250 const char *s0 = nullptr, *s1 = nullptr, *s2 = nullptr,
Patrick Williams16e17532017-02-15 10:23:22 -0600251 *s3 = nullptr, *s4 = nullptr, *s5 = nullptr,
252 *s6 = nullptr;
Andrew Geissler072da3e2018-01-18 07:21:42 -0800253 sd_bus_message_read(m, "isssssssi", &a, &s0, &s1, &s2, &s3, &s4,
254 &s5, &s6, &b);
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500255 assert(a == 1);
256 assert(b == 5);
257 assert(0 == strcmp("asdf", s0));
258 assert(0 == strcmp("ASDF", s1));
259 assert(0 == strcmp("jkl;", s2));
260 assert(0 == strcmp("JKL:", s3));
Patrick Williams16e17532017-02-15 10:23:22 -0600261 assert(0 == strcmp("1234", s4));
262 assert(0 == strcmp("5678", s5));
263 assert(0 == strcmp("!@#$", s6));
264 assert(b == 5);
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500265 }
266 };
267 verifyCallback = &verify::op;
268
Patrick Williams5b485792016-08-02 07:35:14 -0500269 b.call_noreply(m);
Patrick Williams1807fa42016-08-01 22:23:30 -0500270 }
271
Patrick Williamsfd3c4622017-01-06 16:11:47 -0600272 // Test object_path and signature.
273 {
274 auto m = newMethodCall__test(b);
275 auto o = sdbusplus::message::object_path("/asdf");
276 auto s = sdbusplus::message::signature("iii");
277 m.append(1, o, s, 4);
278 verifyTypeString = "iogi";
279
280 struct verify
281 {
282 static void op(sd_bus_message* m)
283 {
284 int32_t a = 0, b = 0;
285 const char *s0 = nullptr, *s1 = nullptr;
286 sd_bus_message_read(m, "iogi", &a, &s0, &s1, &b);
287 assert(a == 1);
288 assert(b == 4);
289 assert(0 == strcmp("/asdf", s0));
290 assert(0 == strcmp("iii", s1));
Patrick Williamsfd3c4622017-01-06 16:11:47 -0600291 }
292 };
293 verifyCallback = &verify::op;
294
295 b.call_noreply(m);
296 }
297
Patrick Williams930460c2016-07-20 17:52:55 -0500298 // Test vector.
299 {
300 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800301 std::vector<std::string> s{"1", "2", "3"};
Patrick Williams930460c2016-07-20 17:52:55 -0500302 m.append(1, s, 2);
303 verifyTypeString = "iasi";
304
305 struct verify
306 {
307 static void op(sd_bus_message* m)
308 {
309 int32_t a = 0;
310 sd_bus_message_read(m, "i", &a);
311 assert(a == 1);
312
Andrew Geissler072da3e2018-01-18 07:21:42 -0800313 auto rc =
314 sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
Patrick Williams930460c2016-07-20 17:52:55 -0500315 assert(0 <= rc);
316
317 const char* s = nullptr;
318 sd_bus_message_read_basic(m, 's', &s);
319 assert(0 == strcmp("1", s));
320 sd_bus_message_read_basic(m, 's', &s);
321 assert(0 == strcmp("2", s));
322 sd_bus_message_read_basic(m, 's', &s);
323 assert(0 == strcmp("3", s));
324 assert(1 == sd_bus_message_at_end(m, false));
325
326 sd_bus_message_exit_container(m);
327
328 sd_bus_message_read(m, "i", &a);
329 assert(a == 2);
Patrick Williams930460c2016-07-20 17:52:55 -0500330 }
331 };
332 verifyCallback = &verify::op;
333
Patrick Williams930460c2016-07-20 17:52:55 -0500334 b.call_noreply(m);
335 }
336
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500337 // Test map.
338 {
339 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800340 std::map<std::string, int> s = {{"asdf", 3}, {"jkl;", 4}};
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500341 m.append(1, s, 2);
342 verifyTypeString = "ia{si}i";
343
344 struct verify
345 {
346 static void op(sd_bus_message* m)
347 {
348 int32_t a = 0;
349 sd_bus_message_read(m, "i", &a);
350 assert(a == 1);
351
Andrew Geissler072da3e2018-01-18 07:21:42 -0800352 auto rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY,
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500353 "{si}");
354 assert(0 <= rc);
355
Andrew Geissler072da3e2018-01-18 07:21:42 -0800356 rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY,
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500357 "si");
358 assert(0 <= rc);
359
360 const char* s = nullptr;
361 sd_bus_message_read_basic(m, 's', &s);
362 assert(0 == strcmp("asdf", s));
363 sd_bus_message_read_basic(m, 'i', &a);
364 assert(a == 3);
365
366 assert(1 == sd_bus_message_at_end(m, false));
367 sd_bus_message_exit_container(m);
368
Andrew Geissler072da3e2018-01-18 07:21:42 -0800369 rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY,
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500370 "si");
371 assert(0 <= rc);
372
373 sd_bus_message_read_basic(m, 's', &s);
374 assert(0 == strcmp("jkl;", s));
375 sd_bus_message_read_basic(m, 'i', &a);
376 assert(a == 4);
377
378 assert(1 == sd_bus_message_at_end(m, false));
379 sd_bus_message_exit_container(m);
380
381 assert(1 == sd_bus_message_at_end(m, false));
382 sd_bus_message_exit_container(m);
383
384 sd_bus_message_read(m, "i", &a);
385 assert(a == 2);
386 }
387 };
388 verifyCallback = &verify::op;
389
390 b.call_noreply(m);
391 }
392
Ed Tanous28dc36d2018-02-21 12:22:54 -0800393 // Test unordered_map.
394 {
395 auto m = newMethodCall__test(b);
396 std::unordered_map<std::string, int> s = {{"asdf", 3}, {"jkl;", 4}};
397 m.append(1, s, 2);
398 verifyTypeString = "ia{si}i";
399
400 struct verify
401 {
402 static void op(sd_bus_message* m)
403 {
404 int32_t a = 0;
405 sd_bus_message_read(m, "i", &a);
406 assert(a == 1);
407
408 auto rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY,
409 "{si}");
410 assert(0 <= rc);
411
412 rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY,
413 "si");
414 assert(0 <= rc);
415
416 const char* s = nullptr;
417 sd_bus_message_read_basic(m, 's', &s);
418 sd_bus_message_read_basic(m, 'i', &a);
419 assert((0 == strcmp("asdf", s) && a == 3) ||
420 (a = 4 && 0 == strcmp("jkl;", s)));
421
422 assert(1 == sd_bus_message_at_end(m, false));
423 sd_bus_message_exit_container(m);
424
425 rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY,
426 "si");
427 assert(0 <= rc);
428
429 sd_bus_message_read_basic(m, 's', &s);
430 sd_bus_message_read_basic(m, 'i', &a);
431 assert((0 == strcmp("asdf", s) && a == 3) ||
432 (a = 4 && 0 == strcmp("jkl;", s)));
433
434 assert(1 == sd_bus_message_at_end(m, false));
435 sd_bus_message_exit_container(m);
436
437 assert(1 == sd_bus_message_at_end(m, false));
438 sd_bus_message_exit_container(m);
439
440 sd_bus_message_read(m, "i", &a);
441 assert(a == 2);
442 }
443 };
444 verifyCallback = &verify::op;
445
446 b.call_noreply(m);
447 }
448
449 // Test set.
450 {
451 auto m = newMethodCall__test(b);
452 std::set<std::string> s = {{"asdf"}, {"jkl;"}};
453 m.append(1, s, 2);
454 verifyTypeString = "iasi";
455
456 struct verify
457 {
458 static void op(sd_bus_message* m)
459 {
460 int32_t a = 0;
461 sd_bus_message_read(m, "i", &a);
462 assert(a == 1);
463
464 auto rc =
465 sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
466 assert(0 <= rc);
467
468 const char* s = nullptr;
469 sd_bus_message_read_basic(m, 's', &s);
470 assert(0 == strcmp("asdf", s));
471
472 sd_bus_message_read_basic(m, 's', &s);
473 assert(0 == strcmp("jkl;", s));
474
475 assert(1 == sd_bus_message_at_end(m, false));
476 sd_bus_message_exit_container(m);
477
478 sd_bus_message_read(m, "i", &a);
479 assert(a == 2);
480 }
481 };
482 verifyCallback = &verify::op;
483
484 b.call_noreply(m);
485 }
486
487 // Test array.
488 {
489 auto m = newMethodCall__test(b);
490 std::array<std::string, 3> s{"1", "2", "3"};
491 m.append(1, s, 2);
492 verifyTypeString = "iasi";
493
494 struct verify
495 {
496 static void op(sd_bus_message* m)
497 {
498 int32_t a = 0;
499 sd_bus_message_read(m, "i", &a);
500 assert(a == 1);
501
502 auto rc =
503 sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
504 assert(0 <= rc);
505
506 const char* s = nullptr;
507 sd_bus_message_read_basic(m, 's', &s);
508 assert(0 == strcmp("1", s));
509 sd_bus_message_read_basic(m, 's', &s);
510 assert(0 == strcmp("2", s));
511 sd_bus_message_read_basic(m, 's', &s);
512 assert(0 == strcmp("3", s));
513 assert(1 == sd_bus_message_at_end(m, false));
514
515 sd_bus_message_exit_container(m);
516
517 sd_bus_message_read(m, "i", &a);
518 assert(a == 2);
519 }
520 };
521 verifyCallback = &verify::op;
522
523 b.call_noreply(m);
524 }
525
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500526 // Test tuple.
527 {
528 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800529 std::tuple<int, double, std::string> a{3, 4.1, "asdf"};
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500530 m.append(1, a, 2);
531 verifyTypeString = "i(ids)i";
532
533 struct verify
534 {
535 static void op(sd_bus_message* m)
536 {
537 int32_t a = 0;
538 double b = 0;
539 const char* c = nullptr;
540
541 sd_bus_message_read(m, "i", &a);
542 assert(a == 1);
543
Andrew Geissler072da3e2018-01-18 07:21:42 -0800544 auto rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT,
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500545 "ids");
546 assert(0 <= rc);
547
548 sd_bus_message_read(m, "ids", &a, &b, &c);
549 assert(a == 3);
550 assert(b == 4.1);
551 assert(0 == strcmp(c, "asdf"));
552
553 sd_bus_message_exit_container(m);
554
555 sd_bus_message_read(m, "i", &a);
556 assert(a == 2);
557 }
558 };
559 verifyCallback = &verify::op;
560
561 b.call_noreply(m);
562 }
563
Patrick Williams75596782016-09-11 21:14:10 -0500564 // Test variant.
565 {
566 auto m = newMethodCall__test(b);
567 sdbusplus::message::variant<int, double> a1{3.1}, a2{4};
568 m.append(1, a1, a2, 2);
569 verifyTypeString = "ivvi";
570
571 struct verify
572 {
573 static void op(sd_bus_message* m)
574 {
575 int32_t a = 0;
576 double b = 0;
577
578 sd_bus_message_read(m, "i", &a);
579 assert(a == 1);
580
581 sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "d");
582 sd_bus_message_read(m, "d", &b);
583 assert(b == 3.1);
584 sd_bus_message_exit_container(m);
585
586 sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "i");
587 sd_bus_message_read(m, "i", &a);
588 assert(a == 4);
589 sd_bus_message_exit_container(m);
590
591 sd_bus_message_read(m, "i", &a);
592 assert(a == 2);
593 }
594 };
595 verifyCallback = &verify::op;
596
597 b.call_noreply(m);
598 }
599
600 // Test map-variant.
601 {
602 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800603 std::map<std::string, sdbusplus::message::variant<int, double>> a1 = {
604 {"asdf", 3}, {"jkl;", 4.1}};
Patrick Williams75596782016-09-11 21:14:10 -0500605 m.append(1, a1, 2);
606 verifyTypeString = "ia{sv}i";
607
608 struct verify
609 {
610 static void op(sd_bus_message* m)
611 {
612 int32_t a = 0;
613 double b = 0;
614 const char* c = nullptr;
615
616 sd_bus_message_read(m, "i", &a);
617 assert(a == 1);
618
619 sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
620 sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv");
621 sd_bus_message_read(m, "s", &c);
622 assert(0 == strcmp("asdf", c));
623 sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "i");
624 sd_bus_message_read(m, "i", &a);
625 assert(a == 3);
626 sd_bus_message_exit_container(m);
627 sd_bus_message_exit_container(m);
628 sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv");
629 sd_bus_message_read(m, "s", &c);
630 assert(0 == strcmp("jkl;", c));
631 sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "d");
632 sd_bus_message_read(m, "d", &b);
633 assert(b == 4.1);
634 sd_bus_message_exit_container(m);
635 sd_bus_message_exit_container(m);
636 sd_bus_message_exit_container(m);
637
638 sd_bus_message_read(m, "i", &a);
639 assert(a == 2);
640 }
641 };
642 verifyCallback = &verify::op;
643
644 b.call_noreply(m);
645 }
646
Patrick Williams1807fa42016-08-01 22:23:30 -0500647 // Shutdown server.
Patrick Williams7802c072016-09-02 15:20:22 -0500648 {
649 auto m = b.new_method_call(SERVICE, "/", INTERFACE, QUIT_METHOD);
650 b.call_noreply(m);
651 }
Patrick Williams1807fa42016-08-01 22:23:30 -0500652}
653
654int main()
655{
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500656
Patrick Williams1807fa42016-08-01 22:23:30 -0500657 // Initialize and start server thread.
658 pthread_t t;
659 {
Patrick Williams5b485792016-08-02 07:35:14 -0500660 auto b = serverInit();
661 pthread_create(&t, NULL, server, b.release());
Patrick Williams1807fa42016-08-01 22:23:30 -0500662 }
663
664 runTests();
665
666 // Wait for server thread to exit.
667 pthread_join(t, NULL);
668
669 return 0;
670}