blob: 34ed4547e675785718b027ec3e089961b30d31a4 [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
William A. Kennington III48697812018-06-19 18:35:38 -07008// Make sure even in non-debug mode we use asserts
9#define TEST_ASSERT(n) \
10 do \
11 { \
12 if (!(n)) \
13 { \
14 fprintf(stderr, "%s:%d %s: Assertion `%s` failed\n", __FILE__, \
15 __LINE__, __func__, #n); \
16 abort(); \
17 } \
18 } while (0)
19
Patrick Williams1807fa42016-08-01 22:23:30 -050020// Global to share the dbus type string between client and server.
21static std::string verifyTypeString;
22
Andrew Geissler072da3e2018-01-18 07:21:42 -080023using verifyCallback_t = void (*)(sd_bus_message*);
Patrick Williams07e1d6f2016-09-08 15:54:09 -050024verifyCallback_t verifyCallback = nullptr;
25
Patrick Williams24fb2962016-11-04 17:08:59 -050026static constexpr auto SERVICE = "sdbusplus.test.message.append";
Patrick Williams1807fa42016-08-01 22:23:30 -050027static constexpr auto INTERFACE = SERVICE;
28static constexpr auto TEST_METHOD = "test";
29static constexpr auto QUIT_METHOD = "quit";
30
31// Open up the sdbus and claim SERVICE name.
Patrick Williams5b485792016-08-02 07:35:14 -050032auto serverInit()
Patrick Williams1807fa42016-08-01 22:23:30 -050033{
Patrick Williams5b485792016-08-02 07:35:14 -050034 auto b = sdbusplus::bus::new_default();
35 b.request_name(SERVICE);
36
37 return std::move(b);
Patrick Williams1807fa42016-08-01 22:23:30 -050038}
39
40// Thread to run the dbus server.
41void* server(void* b)
42{
William A. Kennington IIIb5645502018-06-19 18:36:41 -070043 auto bus = sdbusplus::bus::bus(reinterpret_cast<sdbusplus::bus::busp_t>(b),
44 std::false_type());
Patrick Williams1807fa42016-08-01 22:23:30 -050045
Andrew Geissler072da3e2018-01-18 07:21:42 -080046 while (1)
Patrick Williams1807fa42016-08-01 22:23:30 -050047 {
48 // Wait for messages.
Patrick Williams13b97c52016-09-09 09:36:55 -050049 auto m = bus.process().release();
Patrick Williams1807fa42016-08-01 22:23:30 -050050
Andrew Geissler072da3e2018-01-18 07:21:42 -080051 if (m == nullptr)
Patrick Williams1807fa42016-08-01 22:23:30 -050052 {
Patrick Williams5b485792016-08-02 07:35:14 -050053 bus.wait();
Patrick Williams1807fa42016-08-01 22:23:30 -050054 continue;
55 }
56
57 if (sd_bus_message_is_method_call(m, INTERFACE, TEST_METHOD))
58 {
59 // Verify the message type matches what the test expects.
William A. Kennington III48697812018-06-19 18:35:38 -070060 TEST_ASSERT(verifyTypeString ==
61 sd_bus_message_get_signature(m, true));
Patrick Williams07e1d6f2016-09-08 15:54:09 -050062 if (verifyCallback)
63 {
64 verifyCallback(m);
65 verifyCallback = nullptr;
66 }
67 else
68 {
Andrew Geissler072da3e2018-01-18 07:21:42 -080069 std::cout << "Warning: No verification for " << verifyTypeString
70 << std::endl;
Patrick Williams07e1d6f2016-09-08 15:54:09 -050071 }
Patrick Williams1807fa42016-08-01 22:23:30 -050072 // Reply to client.
73 sd_bus_reply_method_return(m, nullptr);
74 }
75 else if (sd_bus_message_is_method_call(m, INTERFACE, QUIT_METHOD))
76 {
77 // Reply and exit.
78 sd_bus_reply_method_return(m, nullptr);
William A. Kennington IIIb5645502018-06-19 18:36:41 -070079 sd_bus_message_unref(m);
Patrick Williams1807fa42016-08-01 22:23:30 -050080 break;
81 }
William A. Kennington IIIb5645502018-06-19 18:36:41 -070082
83 sd_bus_message_unref(m);
Patrick Williams1807fa42016-08-01 22:23:30 -050084 }
Patrick Williams696e3152016-11-04 17:03:39 -050085
86 return nullptr;
Patrick Williams1807fa42016-08-01 22:23:30 -050087}
88
Patrick Williams7802c072016-09-02 15:20:22 -050089auto newMethodCall__test(sdbusplus::bus::bus& b)
Patrick Williams1807fa42016-08-01 22:23:30 -050090{
91 // Allocate a method-call message for INTERFACE,TEST_METHOD.
Patrick Williams7802c072016-09-02 15:20:22 -050092 return b.new_method_call(SERVICE, "/", INTERFACE, TEST_METHOD);
Patrick Williams1807fa42016-08-01 22:23:30 -050093}
94
95void runTests()
96{
97 using namespace std::literals;
98
Patrick Williams5b485792016-08-02 07:35:14 -050099 auto b = sdbusplus::bus::new_default();
Patrick Williams1807fa42016-08-01 22:23:30 -0500100
101 // Test r-value int.
102 {
Patrick Williams7802c072016-09-02 15:20:22 -0500103 auto m = newMethodCall__test(b);
104 m.append(1);
Patrick Williams1807fa42016-08-01 22:23:30 -0500105 verifyTypeString = "i";
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500106
107 struct verify
108 {
109 static void op(sd_bus_message* m)
110 {
111 int32_t i = 0;
112 sd_bus_message_read_basic(m, 'i', &i);
William A. Kennington III48697812018-06-19 18:35:38 -0700113 TEST_ASSERT(i == 1);
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500114 }
115 };
116 verifyCallback = &verify::op;
117
Patrick Williams5b485792016-08-02 07:35:14 -0500118 b.call_noreply(m);
Patrick Williams1807fa42016-08-01 22:23:30 -0500119 }
Patrick Williams1807fa42016-08-01 22:23:30 -0500120 // Test l-value int.
121 {
Patrick Williams7802c072016-09-02 15:20:22 -0500122 auto m = newMethodCall__test(b);
Patrick Williams1807fa42016-08-01 22:23:30 -0500123 int a = 1;
Patrick Williams7802c072016-09-02 15:20:22 -0500124 m.append(a, a);
Patrick Williams1807fa42016-08-01 22:23:30 -0500125 verifyTypeString = "ii";
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500126
127 struct verify
128 {
129 static void op(sd_bus_message* m)
130 {
131 int32_t a = 0, b = 0;
132 sd_bus_message_read(m, "ii", &a, &b);
William A. Kennington III48697812018-06-19 18:35:38 -0700133 TEST_ASSERT(a == 1);
134 TEST_ASSERT(b == 1);
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500135 }
136 };
137 verifyCallback = &verify::op;
138
Patrick Williams5b485792016-08-02 07:35:14 -0500139 b.call_noreply(m);
Patrick Williams1807fa42016-08-01 22:23:30 -0500140 }
141
142 // Test multiple ints.
143 {
Patrick Williams7802c072016-09-02 15:20:22 -0500144 auto m = newMethodCall__test(b);
145 m.append(1, 2, 3, 4, 5);
Patrick Williams1807fa42016-08-01 22:23:30 -0500146 verifyTypeString = "iiiii";
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500147
148 struct verify
149 {
150 static void op(sd_bus_message* m)
151 {
152 int32_t a = 0, b = 0, c = 0, d = 0, e = 0;
153 sd_bus_message_read(m, "iiiii", &a, &b, &c, &d, &e);
William A. Kennington III48697812018-06-19 18:35:38 -0700154 TEST_ASSERT(a == 1);
155 TEST_ASSERT(b == 2);
156 TEST_ASSERT(c == 3);
157 TEST_ASSERT(d == 4);
158 TEST_ASSERT(e == 5);
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500159 }
160 };
161 verifyCallback = &verify::op;
162
Patrick Williams5b485792016-08-02 07:35:14 -0500163 b.call_noreply(m);
Patrick Williams1807fa42016-08-01 22:23:30 -0500164 }
165
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500166 // Test double and bool.
167 {
168 auto m = newMethodCall__test(b);
169 bool t = true;
Patrick Williamsb760a992016-11-28 11:26:55 -0600170 bool f = false;
171 bool f2 = false;
172 m.append(t, true, f, std::move(f2), false, 1.1);
173 verifyTypeString = "bbbbbd";
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500174
175 struct verify
176 {
177 static void op(sd_bus_message* m)
178 {
Patrick Williamsb760a992016-11-28 11:26:55 -0600179 bool t1, t2, f1, f2, f3;
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500180 double d;
Patrick Williamsb760a992016-11-28 11:26:55 -0600181 sd_bus_message_read(m, "bbbbbd", &t1, &t2, &f1, &f2, &f3, &d);
William A. Kennington III48697812018-06-19 18:35:38 -0700182 TEST_ASSERT(t1);
183 TEST_ASSERT(t2);
184 TEST_ASSERT(!f1);
185 TEST_ASSERT(!f2);
186 TEST_ASSERT(!f3);
187 TEST_ASSERT(d == 1.1);
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500188 }
189 };
190 verifyCallback = &verify::op;
191
192 b.call_noreply(m);
193 }
194
Patrick Williams1807fa42016-08-01 22:23:30 -0500195 // Test r-value string.
196 {
Patrick Williams7802c072016-09-02 15:20:22 -0500197 auto m = newMethodCall__test(b);
198 m.append("asdf"s);
Patrick Williams1807fa42016-08-01 22:23:30 -0500199 verifyTypeString = "s";
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500200
201 struct verify
202 {
203 static void op(sd_bus_message* m)
204 {
205 const char* s = nullptr;
206 sd_bus_message_read_basic(m, 's', &s);
William A. Kennington III48697812018-06-19 18:35:38 -0700207 TEST_ASSERT(0 == strcmp("asdf", s));
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500208 }
209 };
210 verifyCallback = &verify::op;
211
Patrick Williams5b485792016-08-02 07:35:14 -0500212 b.call_noreply(m);
Patrick Williams1807fa42016-08-01 22:23:30 -0500213 }
214
Patrick Williams16e17532017-02-15 10:23:22 -0600215 // Test const string owned by const struct. openbmc/openbmc#1025
216 {
217 struct
218 {
219 const char* foo;
220
221 void insert(sdbusplus::message::message& m)
222 {
223 m.append(foo);
224 }
225 } s;
226
227 auto m = newMethodCall__test(b);
228 s.foo = "1234";
229 s.insert(m);
230
231 verifyTypeString = "s";
232
233 struct verify
234 {
235 static void op(sd_bus_message* m)
236 {
237 const char* s = nullptr;
238 sd_bus_message_read_basic(m, 's', &s);
William A. Kennington III48697812018-06-19 18:35:38 -0700239 TEST_ASSERT(0 == strcmp("1234", s));
Patrick Williams16e17532017-02-15 10:23:22 -0600240 }
241 };
242 verifyCallback = &verify::op;
243
244 b.call_noreply(m);
245 }
246
Patrick Williams1807fa42016-08-01 22:23:30 -0500247 // Test multiple strings, various forms.
248 {
Patrick Williams7802c072016-09-02 15:20:22 -0500249 auto m = newMethodCall__test(b);
Patrick Williams1807fa42016-08-01 22:23:30 -0500250 auto str = "jkl;"s;
251 auto str2 = "JKL:"s;
Patrick Williams16e17532017-02-15 10:23:22 -0600252 const char* str3 = "1234";
253 const char* const str4 = "5678";
254 const auto str5 = "!@#$";
Andrew Geissler072da3e2018-01-18 07:21:42 -0800255 m.append(1, "asdf", "ASDF"s, str, std::move(str2), str3, str4, str5, 5);
Patrick Williams16e17532017-02-15 10:23:22 -0600256 verifyTypeString = "isssssssi";
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500257
258 struct verify
259 {
260 static void op(sd_bus_message* m)
261 {
262 int32_t a = 0, b = 0;
263 const char *s0 = nullptr, *s1 = nullptr, *s2 = nullptr,
Patrick Williams16e17532017-02-15 10:23:22 -0600264 *s3 = nullptr, *s4 = nullptr, *s5 = nullptr,
265 *s6 = nullptr;
Andrew Geissler072da3e2018-01-18 07:21:42 -0800266 sd_bus_message_read(m, "isssssssi", &a, &s0, &s1, &s2, &s3, &s4,
267 &s5, &s6, &b);
William A. Kennington III48697812018-06-19 18:35:38 -0700268 TEST_ASSERT(a == 1);
269 TEST_ASSERT(b == 5);
270 TEST_ASSERT(0 == strcmp("asdf", s0));
271 TEST_ASSERT(0 == strcmp("ASDF", s1));
272 TEST_ASSERT(0 == strcmp("jkl;", s2));
273 TEST_ASSERT(0 == strcmp("JKL:", s3));
274 TEST_ASSERT(0 == strcmp("1234", s4));
275 TEST_ASSERT(0 == strcmp("5678", s5));
276 TEST_ASSERT(0 == strcmp("!@#$", s6));
277 TEST_ASSERT(b == 5);
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500278 }
279 };
280 verifyCallback = &verify::op;
281
Patrick Williams5b485792016-08-02 07:35:14 -0500282 b.call_noreply(m);
Patrick Williams1807fa42016-08-01 22:23:30 -0500283 }
284
Patrick Williamsfd3c4622017-01-06 16:11:47 -0600285 // Test object_path and signature.
286 {
287 auto m = newMethodCall__test(b);
288 auto o = sdbusplus::message::object_path("/asdf");
289 auto s = sdbusplus::message::signature("iii");
290 m.append(1, o, s, 4);
291 verifyTypeString = "iogi";
292
293 struct verify
294 {
295 static void op(sd_bus_message* m)
296 {
297 int32_t a = 0, b = 0;
298 const char *s0 = nullptr, *s1 = nullptr;
299 sd_bus_message_read(m, "iogi", &a, &s0, &s1, &b);
William A. Kennington III48697812018-06-19 18:35:38 -0700300 TEST_ASSERT(a == 1);
301 TEST_ASSERT(b == 4);
302 TEST_ASSERT(0 == strcmp("/asdf", s0));
303 TEST_ASSERT(0 == strcmp("iii", s1));
Patrick Williamsfd3c4622017-01-06 16:11:47 -0600304 }
305 };
306 verifyCallback = &verify::op;
307
308 b.call_noreply(m);
309 }
310
Patrick Williams930460c2016-07-20 17:52:55 -0500311 // Test vector.
312 {
313 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800314 std::vector<std::string> s{"1", "2", "3"};
Patrick Williams930460c2016-07-20 17:52:55 -0500315 m.append(1, s, 2);
316 verifyTypeString = "iasi";
317
318 struct verify
319 {
320 static void op(sd_bus_message* m)
321 {
322 int32_t a = 0;
323 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700324 TEST_ASSERT(a == 1);
Patrick Williams930460c2016-07-20 17:52:55 -0500325
Andrew Geissler072da3e2018-01-18 07:21:42 -0800326 auto rc =
327 sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
William A. Kennington III48697812018-06-19 18:35:38 -0700328 TEST_ASSERT(0 <= rc);
Patrick Williams930460c2016-07-20 17:52:55 -0500329
330 const char* s = nullptr;
331 sd_bus_message_read_basic(m, 's', &s);
William A. Kennington III48697812018-06-19 18:35:38 -0700332 TEST_ASSERT(0 == strcmp("1", s));
Patrick Williams930460c2016-07-20 17:52:55 -0500333 sd_bus_message_read_basic(m, 's', &s);
William A. Kennington III48697812018-06-19 18:35:38 -0700334 TEST_ASSERT(0 == strcmp("2", s));
Patrick Williams930460c2016-07-20 17:52:55 -0500335 sd_bus_message_read_basic(m, 's', &s);
William A. Kennington III48697812018-06-19 18:35:38 -0700336 TEST_ASSERT(0 == strcmp("3", s));
337 TEST_ASSERT(1 == sd_bus_message_at_end(m, false));
Patrick Williams930460c2016-07-20 17:52:55 -0500338
339 sd_bus_message_exit_container(m);
340
341 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700342 TEST_ASSERT(a == 2);
Patrick Williams930460c2016-07-20 17:52:55 -0500343 }
344 };
345 verifyCallback = &verify::op;
346
Patrick Williams930460c2016-07-20 17:52:55 -0500347 b.call_noreply(m);
348 }
349
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500350 // Test map.
351 {
352 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800353 std::map<std::string, int> s = {{"asdf", 3}, {"jkl;", 4}};
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500354 m.append(1, s, 2);
355 verifyTypeString = "ia{si}i";
356
357 struct verify
358 {
359 static void op(sd_bus_message* m)
360 {
361 int32_t a = 0;
362 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700363 TEST_ASSERT(a == 1);
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500364
Andrew Geissler072da3e2018-01-18 07:21:42 -0800365 auto rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY,
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500366 "{si}");
William A. Kennington III48697812018-06-19 18:35:38 -0700367 TEST_ASSERT(0 <= rc);
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500368
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");
William A. Kennington III48697812018-06-19 18:35:38 -0700371 TEST_ASSERT(0 <= rc);
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500372
373 const char* s = nullptr;
374 sd_bus_message_read_basic(m, 's', &s);
William A. Kennington III48697812018-06-19 18:35:38 -0700375 TEST_ASSERT(0 == strcmp("asdf", s));
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500376 sd_bus_message_read_basic(m, 'i', &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700377 TEST_ASSERT(a == 3);
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500378
William A. Kennington III48697812018-06-19 18:35:38 -0700379 TEST_ASSERT(1 == sd_bus_message_at_end(m, false));
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500380 sd_bus_message_exit_container(m);
381
Andrew Geissler072da3e2018-01-18 07:21:42 -0800382 rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY,
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500383 "si");
William A. Kennington III48697812018-06-19 18:35:38 -0700384 TEST_ASSERT(0 <= rc);
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500385
386 sd_bus_message_read_basic(m, 's', &s);
William A. Kennington III48697812018-06-19 18:35:38 -0700387 TEST_ASSERT(0 == strcmp("jkl;", s));
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500388 sd_bus_message_read_basic(m, 'i', &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700389 TEST_ASSERT(a == 4);
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500390
William A. Kennington III48697812018-06-19 18:35:38 -0700391 TEST_ASSERT(1 == sd_bus_message_at_end(m, false));
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500392 sd_bus_message_exit_container(m);
393
William A. Kennington III48697812018-06-19 18:35:38 -0700394 TEST_ASSERT(1 == sd_bus_message_at_end(m, false));
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500395 sd_bus_message_exit_container(m);
396
397 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700398 TEST_ASSERT(a == 2);
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500399 }
400 };
401 verifyCallback = &verify::op;
402
403 b.call_noreply(m);
404 }
405
Ed Tanous28dc36d2018-02-21 12:22:54 -0800406 // Test unordered_map.
407 {
408 auto m = newMethodCall__test(b);
409 std::unordered_map<std::string, int> s = {{"asdf", 3}, {"jkl;", 4}};
410 m.append(1, s, 2);
411 verifyTypeString = "ia{si}i";
412
413 struct verify
414 {
415 static void op(sd_bus_message* m)
416 {
417 int32_t a = 0;
418 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700419 TEST_ASSERT(a == 1);
Ed Tanous28dc36d2018-02-21 12:22:54 -0800420
421 auto rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY,
422 "{si}");
William A. Kennington III48697812018-06-19 18:35:38 -0700423 TEST_ASSERT(0 <= rc);
Ed Tanous28dc36d2018-02-21 12:22:54 -0800424
425 rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY,
426 "si");
William A. Kennington III48697812018-06-19 18:35:38 -0700427 TEST_ASSERT(0 <= rc);
Ed Tanous28dc36d2018-02-21 12:22:54 -0800428
429 const char* s = nullptr;
430 sd_bus_message_read_basic(m, 's', &s);
431 sd_bus_message_read_basic(m, 'i', &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700432 TEST_ASSERT((0 == strcmp("asdf", s) && a == 3) ||
433 (a = 4 && 0 == strcmp("jkl;", s)));
Ed Tanous28dc36d2018-02-21 12:22:54 -0800434
William A. Kennington III48697812018-06-19 18:35:38 -0700435 TEST_ASSERT(1 == sd_bus_message_at_end(m, false));
Ed Tanous28dc36d2018-02-21 12:22:54 -0800436 sd_bus_message_exit_container(m);
437
438 rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY,
439 "si");
William A. Kennington III48697812018-06-19 18:35:38 -0700440 TEST_ASSERT(0 <= rc);
Ed Tanous28dc36d2018-02-21 12:22:54 -0800441
442 sd_bus_message_read_basic(m, 's', &s);
443 sd_bus_message_read_basic(m, 'i', &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700444 TEST_ASSERT((0 == strcmp("asdf", s) && a == 3) ||
445 (a = 4 && 0 == strcmp("jkl;", s)));
Ed Tanous28dc36d2018-02-21 12:22:54 -0800446
William A. Kennington III48697812018-06-19 18:35:38 -0700447 TEST_ASSERT(1 == sd_bus_message_at_end(m, false));
Ed Tanous28dc36d2018-02-21 12:22:54 -0800448 sd_bus_message_exit_container(m);
449
William A. Kennington III48697812018-06-19 18:35:38 -0700450 TEST_ASSERT(1 == sd_bus_message_at_end(m, false));
Ed Tanous28dc36d2018-02-21 12:22:54 -0800451 sd_bus_message_exit_container(m);
452
453 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700454 TEST_ASSERT(a == 2);
Ed Tanous28dc36d2018-02-21 12:22:54 -0800455 }
456 };
457 verifyCallback = &verify::op;
458
459 b.call_noreply(m);
460 }
461
462 // Test set.
463 {
464 auto m = newMethodCall__test(b);
465 std::set<std::string> s = {{"asdf"}, {"jkl;"}};
466 m.append(1, s, 2);
467 verifyTypeString = "iasi";
468
469 struct verify
470 {
471 static void op(sd_bus_message* m)
472 {
473 int32_t a = 0;
474 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700475 TEST_ASSERT(a == 1);
Ed Tanous28dc36d2018-02-21 12:22:54 -0800476
477 auto rc =
478 sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
William A. Kennington III48697812018-06-19 18:35:38 -0700479 TEST_ASSERT(0 <= rc);
Ed Tanous28dc36d2018-02-21 12:22:54 -0800480
481 const char* s = nullptr;
482 sd_bus_message_read_basic(m, 's', &s);
William A. Kennington III48697812018-06-19 18:35:38 -0700483 TEST_ASSERT(0 == strcmp("asdf", s));
Ed Tanous28dc36d2018-02-21 12:22:54 -0800484
485 sd_bus_message_read_basic(m, 's', &s);
William A. Kennington III48697812018-06-19 18:35:38 -0700486 TEST_ASSERT(0 == strcmp("jkl;", s));
Ed Tanous28dc36d2018-02-21 12:22:54 -0800487
William A. Kennington III48697812018-06-19 18:35:38 -0700488 TEST_ASSERT(1 == sd_bus_message_at_end(m, false));
Ed Tanous28dc36d2018-02-21 12:22:54 -0800489 sd_bus_message_exit_container(m);
490
491 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700492 TEST_ASSERT(a == 2);
Ed Tanous28dc36d2018-02-21 12:22:54 -0800493 }
494 };
495 verifyCallback = &verify::op;
496
497 b.call_noreply(m);
498 }
499
500 // Test array.
501 {
502 auto m = newMethodCall__test(b);
503 std::array<std::string, 3> s{"1", "2", "3"};
504 m.append(1, s, 2);
505 verifyTypeString = "iasi";
506
507 struct verify
508 {
509 static void op(sd_bus_message* m)
510 {
511 int32_t a = 0;
512 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700513 TEST_ASSERT(a == 1);
Ed Tanous28dc36d2018-02-21 12:22:54 -0800514
515 auto rc =
516 sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
William A. Kennington III48697812018-06-19 18:35:38 -0700517 TEST_ASSERT(0 <= rc);
Ed Tanous28dc36d2018-02-21 12:22:54 -0800518
519 const char* s = nullptr;
520 sd_bus_message_read_basic(m, 's', &s);
William A. Kennington III48697812018-06-19 18:35:38 -0700521 TEST_ASSERT(0 == strcmp("1", s));
Ed Tanous28dc36d2018-02-21 12:22:54 -0800522 sd_bus_message_read_basic(m, 's', &s);
William A. Kennington III48697812018-06-19 18:35:38 -0700523 TEST_ASSERT(0 == strcmp("2", s));
Ed Tanous28dc36d2018-02-21 12:22:54 -0800524 sd_bus_message_read_basic(m, 's', &s);
William A. Kennington III48697812018-06-19 18:35:38 -0700525 TEST_ASSERT(0 == strcmp("3", s));
526 TEST_ASSERT(1 == sd_bus_message_at_end(m, false));
Ed Tanous28dc36d2018-02-21 12:22:54 -0800527
528 sd_bus_message_exit_container(m);
529
530 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700531 TEST_ASSERT(a == 2);
Ed Tanous28dc36d2018-02-21 12:22:54 -0800532 }
533 };
534 verifyCallback = &verify::op;
535
536 b.call_noreply(m);
537 }
538
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500539 // Test tuple.
540 {
541 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800542 std::tuple<int, double, std::string> a{3, 4.1, "asdf"};
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500543 m.append(1, a, 2);
544 verifyTypeString = "i(ids)i";
545
546 struct verify
547 {
548 static void op(sd_bus_message* m)
549 {
550 int32_t a = 0;
551 double b = 0;
552 const char* c = nullptr;
553
554 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700555 TEST_ASSERT(a == 1);
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500556
Andrew Geissler072da3e2018-01-18 07:21:42 -0800557 auto rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT,
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500558 "ids");
William A. Kennington III48697812018-06-19 18:35:38 -0700559 TEST_ASSERT(0 <= rc);
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500560
561 sd_bus_message_read(m, "ids", &a, &b, &c);
William A. Kennington III48697812018-06-19 18:35:38 -0700562 TEST_ASSERT(a == 3);
563 TEST_ASSERT(b == 4.1);
564 TEST_ASSERT(0 == strcmp(c, "asdf"));
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500565
566 sd_bus_message_exit_container(m);
567
568 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700569 TEST_ASSERT(a == 2);
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500570 }
571 };
572 verifyCallback = &verify::op;
573
574 b.call_noreply(m);
575 }
576
Patrick Williams75596782016-09-11 21:14:10 -0500577 // Test variant.
578 {
579 auto m = newMethodCall__test(b);
580 sdbusplus::message::variant<int, double> a1{3.1}, a2{4};
581 m.append(1, a1, a2, 2);
582 verifyTypeString = "ivvi";
583
584 struct verify
585 {
586 static void op(sd_bus_message* m)
587 {
588 int32_t a = 0;
589 double b = 0;
590
591 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700592 TEST_ASSERT(a == 1);
Patrick Williams75596782016-09-11 21:14:10 -0500593
594 sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "d");
595 sd_bus_message_read(m, "d", &b);
William A. Kennington III48697812018-06-19 18:35:38 -0700596 TEST_ASSERT(b == 3.1);
Patrick Williams75596782016-09-11 21:14:10 -0500597 sd_bus_message_exit_container(m);
598
599 sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "i");
600 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700601 TEST_ASSERT(a == 4);
Patrick Williams75596782016-09-11 21:14:10 -0500602 sd_bus_message_exit_container(m);
603
604 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700605 TEST_ASSERT(a == 2);
Patrick Williams75596782016-09-11 21:14:10 -0500606 }
607 };
608 verifyCallback = &verify::op;
609
610 b.call_noreply(m);
611 }
612
613 // Test map-variant.
614 {
615 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800616 std::map<std::string, sdbusplus::message::variant<int, double>> a1 = {
617 {"asdf", 3}, {"jkl;", 4.1}};
Patrick Williams75596782016-09-11 21:14:10 -0500618 m.append(1, a1, 2);
619 verifyTypeString = "ia{sv}i";
620
621 struct verify
622 {
623 static void op(sd_bus_message* m)
624 {
625 int32_t a = 0;
626 double b = 0;
627 const char* c = nullptr;
628
629 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700630 TEST_ASSERT(a == 1);
Patrick Williams75596782016-09-11 21:14:10 -0500631
632 sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
633 sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv");
634 sd_bus_message_read(m, "s", &c);
William A. Kennington III48697812018-06-19 18:35:38 -0700635 TEST_ASSERT(0 == strcmp("asdf", c));
Patrick Williams75596782016-09-11 21:14:10 -0500636 sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "i");
637 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700638 TEST_ASSERT(a == 3);
Patrick Williams75596782016-09-11 21:14:10 -0500639 sd_bus_message_exit_container(m);
640 sd_bus_message_exit_container(m);
641 sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv");
642 sd_bus_message_read(m, "s", &c);
William A. Kennington III48697812018-06-19 18:35:38 -0700643 TEST_ASSERT(0 == strcmp("jkl;", c));
Patrick Williams75596782016-09-11 21:14:10 -0500644 sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "d");
645 sd_bus_message_read(m, "d", &b);
William A. Kennington III48697812018-06-19 18:35:38 -0700646 TEST_ASSERT(b == 4.1);
Patrick Williams75596782016-09-11 21:14:10 -0500647 sd_bus_message_exit_container(m);
648 sd_bus_message_exit_container(m);
649 sd_bus_message_exit_container(m);
650
651 sd_bus_message_read(m, "i", &a);
William A. Kennington III48697812018-06-19 18:35:38 -0700652 TEST_ASSERT(a == 2);
Patrick Williams75596782016-09-11 21:14:10 -0500653 }
654 };
655 verifyCallback = &verify::op;
656
657 b.call_noreply(m);
658 }
659
Patrick Williams1807fa42016-08-01 22:23:30 -0500660 // Shutdown server.
Patrick Williams7802c072016-09-02 15:20:22 -0500661 {
662 auto m = b.new_method_call(SERVICE, "/", INTERFACE, QUIT_METHOD);
663 b.call_noreply(m);
664 }
Patrick Williams1807fa42016-08-01 22:23:30 -0500665}
666
667int main()
668{
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500669
Patrick Williams1807fa42016-08-01 22:23:30 -0500670 // Initialize and start server thread.
671 pthread_t t;
672 {
Patrick Williams5b485792016-08-02 07:35:14 -0500673 auto b = serverInit();
674 pthread_create(&t, NULL, server, b.release());
Patrick Williams1807fa42016-08-01 22:23:30 -0500675 }
676
677 runTests();
678
679 // Wait for server thread to exit.
680 pthread_join(t, NULL);
681
682 return 0;
683}