]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/test-bus-marshal.c
tree-wide: sort includes
[thirdparty/systemd.git] / src / libsystemd / sd-bus / test-bus-marshal.c
CommitLineData
de1c301e
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
6cd37a5e 22#include <math.h>
cf0fbc49 23#include <stdlib.h>
de1c301e
LP
24
25#ifdef HAVE_GLIB
26#include <gio/gio.h>
27#endif
28
22703094 29#ifdef HAVE_DBUS
718db961 30#include <dbus/dbus.h>
22703094 31#endif
de1c301e 32
de1c301e 33#include "sd-bus.h"
07630cea 34
b5efdb8a 35#include "alloc-util.h"
2b5c5383 36#include "bus-dump.h"
a6278b88 37#include "bus-label.h"
07630cea
LP
38#include "bus-message.h"
39#include "bus-util.h"
3ffd4af2 40#include "fd-util.h"
e4e73a63 41#include "hexdecoct.h"
cf0fbc49 42#include "log.h"
07630cea 43#include "util.h"
a6278b88 44
98a4c30b
DH
45static void test_bus_path_encode_unique(void) {
46 _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
47
48 assert_se(bus_path_encode_unique(NULL, "/foo/bar", "some.sender", "a.suffix", &a) >= 0 && streq_ptr(a, "/foo/bar/some_2esender/a_2esuffix"));
49 assert_se(bus_path_decode_unique(a, "/foo/bar", &b, &c) > 0 && streq_ptr(b, "some.sender") && streq_ptr(c, "a.suffix"));
50 assert_se(bus_path_decode_unique(a, "/bar/foo", &d, &d) == 0 && !d);
51 assert_se(bus_path_decode_unique("/foo/bar/onlyOneSuffix", "/foo/bar", &d, &d) == 0 && !d);
52 assert_se(bus_path_decode_unique("/foo/bar/_/_", "/foo/bar", &d, &e) > 0 && streq_ptr(d, "") && streq_ptr(e, ""));
53}
54
a6278b88
LP
55static void test_bus_path_encode(void) {
56 _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
57
58 assert_se(sd_bus_path_encode("/foo/bar", "waldo", &a) >= 0 && streq(a, "/foo/bar/waldo"));
59 assert_se(sd_bus_path_decode(a, "/waldo", &b) == 0 && b == NULL);
60 assert_se(sd_bus_path_decode(a, "/foo/bar", &b) > 0 && streq(b, "waldo"));
61
62 assert_se(sd_bus_path_encode("xxxx", "waldo", &c) < 0);
63 assert_se(sd_bus_path_encode("/foo/", "waldo", &c) < 0);
64
65 assert_se(sd_bus_path_encode("/foo/bar", "", &c) >= 0 && streq(c, "/foo/bar/_"));
66 assert_se(sd_bus_path_decode(c, "/foo/bar", &d) > 0 && streq(d, ""));
67
68 assert_se(sd_bus_path_encode("/foo/bar", "foo.bar", &e) >= 0 && streq(e, "/foo/bar/foo_2ebar"));
69 assert_se(sd_bus_path_decode(e, "/foo/bar", &f) > 0 && streq(f, "foo.bar"));
70}
de1c301e 71
dfb815c3
DH
72static void test_bus_path_encode_many(void) {
73 _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
74
75 assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%", NULL) == 0);
76 assert_se(sd_bus_path_decode_many("/prefix/bar", "/prefix/%bar", NULL) == 1);
77 assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%/suffix", NULL) == 0);
78 assert_se(sd_bus_path_decode_many("/prefix/foobar/suffix", "/prefix/%/suffix", &a) == 1 && streq_ptr(a, "foobar"));
79 assert_se(sd_bus_path_decode_many("/prefix/one_foo_two/mid/three_bar_four/suffix", "/prefix/one_%_two/mid/three_%_four/suffix", &b, &c) == 1 && streq_ptr(b, "foo") && streq_ptr(c, "bar"));
80 assert_se(sd_bus_path_decode_many("/prefix/one_foo_two/mid/three_bar_four/suffix", "/prefix/one_%_two/mid/three_%_four/suffix", NULL, &d) == 1 && streq_ptr(d, "bar"));
81
82 assert_se(sd_bus_path_decode_many("/foo/bar", "/foo/bar/%", NULL) == 0);
83 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/bar%", NULL) == 0);
84 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/bar", NULL) == 0);
85 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%bar", NULL) == 0);
86 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/bar/suffix") == 1);
87 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%%/suffix", NULL, NULL) == 0); /* multiple '%' are treated verbatim */
88 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffi", NULL) == 0);
89 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffix", &e) == 1 && streq_ptr(e, "bar"));
90 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/%", NULL, NULL) == 1);
91 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%/%", NULL, NULL, NULL) == 1);
92 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "%/%/%", NULL, NULL, NULL) == 0);
93 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%", NULL, NULL) == 0);
94 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%/", NULL, NULL) == 0);
95 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/", NULL) == 0);
96 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%", NULL) == 0);
97 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "%", NULL) == 0);
98
99 assert_se(sd_bus_path_encode_many(&f, "/prefix/one_%_two/mid/three_%_four/suffix", "foo", "bar") >= 0 && streq_ptr(f, "/prefix/one_foo_two/mid/three_bar_four/suffix"));
100}
101
28383ba1
LP
102static void test_bus_label_escape_one(const char *a, const char *b) {
103 _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
104
a6278b88 105 assert_se(t = bus_label_escape(a));
28383ba1
LP
106 assert_se(streq(t, b));
107
a6278b88 108 assert_se(x = bus_label_unescape(t));
28383ba1
LP
109 assert_se(streq(a, x));
110
a6278b88 111 assert_se(y = bus_label_unescape(b));
28383ba1
LP
112 assert_se(streq(a, y));
113}
114
115static void test_bus_label_escape(void) {
116 test_bus_label_escape_one("foo123bar", "foo123bar");
117 test_bus_label_escape_one("foo.bar", "foo_2ebar");
118 test_bus_label_escape_one("foo_2ebar", "foo_5f2ebar");
119 test_bus_label_escape_one("", "_");
120 test_bus_label_escape_one("_", "_5f");
121 test_bus_label_escape_one("1", "_31");
122 test_bus_label_escape_one(":1", "_3a1");
123}
124
de1c301e 125int main(int argc, char *argv[]) {
c430fee6 126 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *copy = NULL;
9a17484d 127 int r, boolean;
d44fdf49 128 const char *x, *x2, *y, *z, *a, *b, *c, *d, *a_signature;
de1c301e
LP
129 uint8_t u, v;
130 void *buffer = NULL;
131 size_t sz;
132 char *h;
b3af9646 133 const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array;
f8e013f8 134 char *s;
c430fee6
LP
135 _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL;
136 _cleanup_fclose_ FILE *ms = NULL;
137 size_t first_size = 0, second_size = 0, third_size = 0;
2a0958d2 138 _cleanup_bus_unref_ sd_bus *bus = NULL;
6cd37a5e
LP
139 double dbl;
140 uint64_t u64;
de1c301e 141
2a0958d2
LP
142 r = sd_bus_default_system(&bus);
143 if (r < 0)
144 return EXIT_TEST_SKIP;
145
146 r = sd_bus_message_new_method_call(bus, &m, "foobar.waldo", "/", "foobar.waldo", "Piep");
de1c301e
LP
147 assert_se(r >= 0);
148
effbc8e4
ZJS
149 r = sd_bus_message_append(m, "");
150 assert_se(r >= 0);
151
de1c301e
LP
152 r = sd_bus_message_append(m, "s", "a string");
153 assert_se(r >= 0);
154
b8beb278 155 r = sd_bus_message_append(m, "s", NULL);
15912917 156 assert_se(r >= 0);
b8beb278 157
d44fdf49 158 r = sd_bus_message_append(m, "asg", 2, "string #1", "string #2", "sba(tt)ss");
de1c301e
LP
159 assert_se(r >= 0);
160
161 r = sd_bus_message_append(m, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after");
162 assert_se(r >= 0);
163
164 r = sd_bus_message_append(m, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo");
165 assert_se(r >= 0);
166
4f1d7741 167 r = sd_bus_message_append(m, "y(ty)y(yt)y", 8, 777ULL, 7, 9, 77, 7777ULL, 10);
443a5598
DH
168 assert_se(r >= 0);
169
a388569f
DH
170 r = sd_bus_message_append(m, "()");
171 assert_se(r >= 0);
172
de1c301e
LP
173 r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
174 assert_se(r >= 0);
175
176 r = sd_bus_message_open_container(m, 'a', "s");
177 assert_se(r >= 0);
178
179 r = sd_bus_message_append_basic(m, 's', "foobar");
180 assert_se(r >= 0);
181
182 r = sd_bus_message_append_basic(m, 's', "waldo");
183 assert_se(r >= 0);
184
185 r = sd_bus_message_close_container(m);
186 assert_se(r >= 0);
187
f8e013f8
LP
188 r = sd_bus_message_append_string_space(m, 5, &s);
189 assert_se(r >= 0);
190 strcpy(s, "hallo");
191
b3af9646
LP
192 r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array));
193 assert_se(r >= 0);
194
5e86fd7b
LP
195 r = sd_bus_message_append_array(m, 'u', NULL, 0);
196 assert_se(r >= 0);
197
6cd37a5e
LP
198 r = sd_bus_message_append(m, "a(stdo)", 1, "foo", 815ULL, 47.0, "/");
199 assert_se(r >= 0);
200
3df7a7e6 201 r = bus_message_seal(m, 4711, 0);
de1c301e
LP
202 assert_se(r >= 0);
203
d55192ad 204 bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
c430fee6
LP
205
206 ms = open_memstream(&first, &first_size);
d55192ad 207 bus_message_dump(m, ms, 0);
c430fee6
LP
208 fflush(ms);
209 assert_se(!ferror(ms));
de1c301e
LP
210
211 r = bus_message_get_blob(m, &buffer, &sz);
212 assert_se(r >= 0);
213
214 h = hexmem(buffer, sz);
215 assert_se(h);
216
de0671ee 217 log_info("message size = %zu, contents =\n%s", sz, h);
de1c301e
LP
218 free(h);
219
220#ifdef HAVE_GLIB
221 {
222 GDBusMessage *g;
223 char *p;
224
34f856cb 225#if !defined(GLIB_VERSION_2_36)
de1c301e 226 g_type_init();
34f856cb 227#endif
de1c301e
LP
228
229 g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL);
230 p = g_dbus_message_print(g, 0);
231 log_info("%s", p);
232 g_free(p);
233 g_object_unref(g);
234 }
235#endif
236
22703094 237#ifdef HAVE_DBUS
de1c301e
LP
238 {
239 DBusMessage *w;
240 DBusError error;
241
242 dbus_error_init(&error);
243
244 w = dbus_message_demarshal(buffer, sz, &error);
c1b9d935 245 if (!w)
de1c301e 246 log_error("%s", error.message);
c1b9d935 247 else
de1c301e
LP
248 dbus_message_unref(w);
249 }
22703094 250#endif
de1c301e 251
80a46c73
LP
252 m = sd_bus_message_unref(m);
253
aa0d0ed6 254 r = bus_message_from_malloc(bus, buffer, sz, NULL, 0, NULL, &m);
80a46c73
LP
255 assert_se(r >= 0);
256
d55192ad 257 bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
c430fee6
LP
258
259 fclose(ms);
260 ms = open_memstream(&second, &second_size);
d55192ad 261 bus_message_dump(m, ms, 0);
c430fee6
LP
262 fflush(ms);
263 assert_se(!ferror(ms));
264 assert_se(first_size == second_size);
265 assert_se(memcmp(first, second, first_size) == 0);
de1c301e 266
9a17484d
LP
267 assert_se(sd_bus_message_rewind(m, true) >= 0);
268
d44fdf49 269 r = sd_bus_message_read(m, "ssasg", &x, &x2, 2, &y, &z, &a_signature);
9a17484d
LP
270 assert_se(r > 0);
271 assert_se(streq(x, "a string"));
15912917 272 assert_se(streq(x2, ""));
9a17484d
LP
273 assert_se(streq(y, "string #1"));
274 assert_se(streq(z, "string #2"));
d44fdf49 275 assert_se(streq(a_signature, "sba(tt)ss"));
9a17484d
LP
276
277 r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d);
278 assert_se(r > 0);
279 assert_se(streq(x, "foobar"));
280 assert_se(streq(y, "foo"));
281 assert_se(streq(z, "bar"));
282 assert_se(streq(a, "waldo"));
283 assert_se(streq(b, "piep"));
284 assert_se(streq(c, "pap"));
285 assert_se(streq(d, "after"));
286
287 r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y);
288 assert_se(r > 0);
289 assert_se(u == 3);
290 assert_se(streq(x, "foo"));
291 assert_se(v == 5);
292 assert_se(streq(y, "waldo"));
293
443a5598
DH
294 r = sd_bus_message_read(m, "y(ty)", &v, &u64, &u);
295 assert_se(r > 0);
296 assert_se(v == 8);
297 assert_se(u64 == 777);
298 assert_se(u == 7);
299
300 r = sd_bus_message_read(m, "y(yt)", &v, &u, &u64);
301 assert_se(r > 0);
302 assert_se(v == 9);
303 assert_se(u == 77);
304 assert_se(u64 == 7777);
305
306 r = sd_bus_message_read(m, "y", &v);
307 assert_se(r > 0);
308 assert_se(v == 10);
309
a388569f
DH
310 r = sd_bus_message_read(m, "()");
311 assert_se(r > 0);
312
9a17484d
LP
313 r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
314 assert_se(r > 0);
315 assert_se(boolean);
316 assert_se(streq(x, "aaa"));
317 assert_se(streq(y, "1"));
318 assert_se(streq(a, "bbb"));
319 assert_se(streq(b, "2"));
320 assert_se(streq(c, "ccc"));
321 assert_se(streq(d, "3"));
322
c430fee6
LP
323 assert_se(sd_bus_message_verify_type(m, 'a', "s") > 0);
324
9a17484d
LP
325 r = sd_bus_message_read(m, "as", 2, &x, &y);
326 assert_se(r > 0);
327 assert_se(streq(x, "foobar"));
328 assert_se(streq(y, "waldo"));
329
f8e013f8
LP
330 r = sd_bus_message_read_basic(m, 's', &s);
331 assert_se(r > 0);
332 assert_se(streq(s, "hallo"));
333
b3af9646
LP
334 r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz);
335 assert_se(r > 0);
336 assert_se(sz == sizeof(integer_array));
337 assert_se(memcmp(integer_array, return_array, sz) == 0);
338
5e86fd7b
LP
339 r = sd_bus_message_read_array(m, 'u', (const void**) &return_array, &sz);
340 assert_se(r > 0);
341 assert_se(sz == 0);
342
6cd37a5e
LP
343 r = sd_bus_message_read(m, "a(stdo)", 1, &x, &u64, &dbl, &y);
344 assert_se(r > 0);
345 assert_se(streq(x, "foo"));
346 assert_se(u64 == 815ULL);
347 assert_se(fabs(dbl - 47.0) < 0.1);
348 assert_se(streq(y, "/"));
349
9a17484d
LP
350 r = sd_bus_message_peek_type(m, NULL, NULL);
351 assert_se(r == 0);
de1c301e 352
2a0958d2 353 r = sd_bus_message_new_method_call(bus, &copy, "foobar.waldo", "/", "foobar.waldo", "Piep");
c430fee6
LP
354 assert_se(r >= 0);
355
356 r = sd_bus_message_rewind(m, true);
357 assert_se(r >= 0);
358
359 r = sd_bus_message_copy(copy, m, true);
360 assert_se(r >= 0);
361
3df7a7e6 362 r = bus_message_seal(copy, 4712, 0);
c430fee6
LP
363 assert_se(r >= 0);
364
365 fclose(ms);
366 ms = open_memstream(&third, &third_size);
d55192ad 367 bus_message_dump(copy, ms, 0);
c430fee6
LP
368 fflush(ms);
369 assert_se(!ferror(ms));
370
9b55cd56
ZJS
371 printf("<%.*s>\n", (int) first_size, first);
372 printf("<%.*s>\n", (int) third_size, third);
c430fee6
LP
373
374 assert_se(first_size == third_size);
375 assert_se(memcmp(first, third, third_size) == 0);
376
9b07511d
LP
377 r = sd_bus_message_rewind(m, true);
378 assert_se(r >= 0);
379
380 assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
381
d44fdf49 382 r = sd_bus_message_skip(m, "ssasg");
9b07511d
LP
383 assert_se(r > 0);
384
385 assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
386
387 r = sd_bus_message_skip(m, "sass");
388 assert_se(r >= 0);
389
390 assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
391
a388569f 392 r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y()");
9b07511d
LP
393 assert_se(r >= 0);
394
395 assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
396
275b39fe 397 r = sd_bus_message_read(m, "b", &boolean);
9b07511d
LP
398 assert_se(r > 0);
399 assert_se(boolean);
275b39fe
LP
400
401 r = sd_bus_message_enter_container(m, 0, NULL);
402 assert_se(r > 0);
403
404 r = sd_bus_message_read(m, "(ss)", &x, &y);
405 assert_se(r > 0);
406
407 r = sd_bus_message_read(m, "(ss)", &a, &b);
408 assert_se(r > 0);
409
410 r = sd_bus_message_read(m, "(ss)", &c, &d);
411 assert_se(r > 0);
412
413 r = sd_bus_message_read(m, "(ss)", &x, &y);
414 assert_se(r == 0);
415
416 r = sd_bus_message_exit_container(m);
417 assert_se(r >= 0);
418
9b07511d
LP
419 assert_se(streq(x, "aaa"));
420 assert_se(streq(y, "1"));
421 assert_se(streq(a, "bbb"));
422 assert_se(streq(b, "2"));
423 assert_se(streq(c, "ccc"));
424 assert_se(streq(d, "3"));
425
28383ba1 426 test_bus_label_escape();
a6278b88 427 test_bus_path_encode();
98a4c30b 428 test_bus_path_encode_unique();
dfb815c3 429 test_bus_path_encode_many();
28383ba1 430
de1c301e
LP
431 return 0;
432}