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