]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-bus/test-bus-marshal.c
Merge pull request #57 from pwithnall/wip/pwithnall/udev-virtualbox-rules
[thirdparty/systemd.git] / src / libsystemd / sd-bus / test-bus-marshal.c
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
22 #include <stdlib.h>
23 #include <math.h>
24
25 #ifdef HAVE_GLIB
26 #include <gio/gio.h>
27 #endif
28
29 #ifdef HAVE_DBUS
30 #include <dbus/dbus.h>
31 #endif
32
33 #include "log.h"
34 #include "util.h"
35
36 #include "sd-bus.h"
37 #include "bus-message.h"
38 #include "bus-util.h"
39 #include "bus-dump.h"
40 #include "bus-label.h"
41
42 static 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
52 static 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 }
68
69 static void test_bus_label_escape_one(const char *a, const char *b) {
70 _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
71
72 assert_se(t = bus_label_escape(a));
73 assert_se(streq(t, b));
74
75 assert_se(x = bus_label_unescape(t));
76 assert_se(streq(a, x));
77
78 assert_se(y = bus_label_unescape(b));
79 assert_se(streq(a, y));
80 }
81
82 static void test_bus_label_escape(void) {
83 test_bus_label_escape_one("foo123bar", "foo123bar");
84 test_bus_label_escape_one("foo.bar", "foo_2ebar");
85 test_bus_label_escape_one("foo_2ebar", "foo_5f2ebar");
86 test_bus_label_escape_one("", "_");
87 test_bus_label_escape_one("_", "_5f");
88 test_bus_label_escape_one("1", "_31");
89 test_bus_label_escape_one(":1", "_3a1");
90 }
91
92 int main(int argc, char *argv[]) {
93 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *copy = NULL;
94 int r, boolean;
95 const char *x, *x2, *y, *z, *a, *b, *c, *d, *a_signature;
96 uint8_t u, v;
97 void *buffer = NULL;
98 size_t sz;
99 char *h;
100 const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array;
101 char *s;
102 _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL;
103 _cleanup_fclose_ FILE *ms = NULL;
104 size_t first_size = 0, second_size = 0, third_size = 0;
105 _cleanup_bus_unref_ sd_bus *bus = NULL;
106 double dbl;
107 uint64_t u64;
108
109 r = sd_bus_default_system(&bus);
110 if (r < 0)
111 return EXIT_TEST_SKIP;
112
113 r = sd_bus_message_new_method_call(bus, &m, "foobar.waldo", "/", "foobar.waldo", "Piep");
114 assert_se(r >= 0);
115
116 r = sd_bus_message_append(m, "");
117 assert_se(r >= 0);
118
119 r = sd_bus_message_append(m, "s", "a string");
120 assert_se(r >= 0);
121
122 r = sd_bus_message_append(m, "s", NULL);
123 assert_se(r >= 0);
124
125 r = sd_bus_message_append(m, "asg", 2, "string #1", "string #2", "sba(tt)ss");
126 assert_se(r >= 0);
127
128 r = sd_bus_message_append(m, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after");
129 assert_se(r >= 0);
130
131 r = sd_bus_message_append(m, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo");
132 assert_se(r >= 0);
133
134 r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
135 assert_se(r >= 0);
136
137 r = sd_bus_message_open_container(m, 'a', "s");
138 assert_se(r >= 0);
139
140 r = sd_bus_message_append_basic(m, 's', "foobar");
141 assert_se(r >= 0);
142
143 r = sd_bus_message_append_basic(m, 's', "waldo");
144 assert_se(r >= 0);
145
146 r = sd_bus_message_close_container(m);
147 assert_se(r >= 0);
148
149 r = sd_bus_message_append_string_space(m, 5, &s);
150 assert_se(r >= 0);
151 strcpy(s, "hallo");
152
153 r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array));
154 assert_se(r >= 0);
155
156 r = sd_bus_message_append_array(m, 'u', NULL, 0);
157 assert_se(r >= 0);
158
159 r = sd_bus_message_append(m, "a(stdo)", 1, "foo", 815ULL, 47.0, "/");
160 assert_se(r >= 0);
161
162 r = bus_message_seal(m, 4711, 0);
163 assert_se(r >= 0);
164
165 bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
166
167 ms = open_memstream(&first, &first_size);
168 bus_message_dump(m, ms, 0);
169 fflush(ms);
170 assert_se(!ferror(ms));
171
172 r = bus_message_get_blob(m, &buffer, &sz);
173 assert_se(r >= 0);
174
175 h = hexmem(buffer, sz);
176 assert_se(h);
177
178 log_info("message size = %zu, contents =\n%s", sz, h);
179 free(h);
180
181 #ifdef HAVE_GLIB
182 {
183 GDBusMessage *g;
184 char *p;
185
186 #if !defined(GLIB_VERSION_2_36)
187 g_type_init();
188 #endif
189
190 g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL);
191 p = g_dbus_message_print(g, 0);
192 log_info("%s", p);
193 g_free(p);
194 g_object_unref(g);
195 }
196 #endif
197
198 #ifdef HAVE_DBUS
199 {
200 DBusMessage *w;
201 DBusError error;
202
203 dbus_error_init(&error);
204
205 w = dbus_message_demarshal(buffer, sz, &error);
206 if (!w)
207 log_error("%s", error.message);
208 else
209 dbus_message_unref(w);
210 }
211 #endif
212
213 m = sd_bus_message_unref(m);
214
215 r = bus_message_from_malloc(bus, buffer, sz, NULL, 0, NULL, NULL, &m);
216 assert_se(r >= 0);
217
218 bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
219
220 fclose(ms);
221 ms = open_memstream(&second, &second_size);
222 bus_message_dump(m, ms, 0);
223 fflush(ms);
224 assert_se(!ferror(ms));
225 assert_se(first_size == second_size);
226 assert_se(memcmp(first, second, first_size) == 0);
227
228 assert_se(sd_bus_message_rewind(m, true) >= 0);
229
230 r = sd_bus_message_read(m, "ssasg", &x, &x2, 2, &y, &z, &a_signature);
231 assert_se(r > 0);
232 assert_se(streq(x, "a string"));
233 assert_se(streq(x2, ""));
234 assert_se(streq(y, "string #1"));
235 assert_se(streq(z, "string #2"));
236 assert_se(streq(a_signature, "sba(tt)ss"));
237
238 r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d);
239 assert_se(r > 0);
240 assert_se(streq(x, "foobar"));
241 assert_se(streq(y, "foo"));
242 assert_se(streq(z, "bar"));
243 assert_se(streq(a, "waldo"));
244 assert_se(streq(b, "piep"));
245 assert_se(streq(c, "pap"));
246 assert_se(streq(d, "after"));
247
248 r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y);
249 assert_se(r > 0);
250 assert_se(u == 3);
251 assert_se(streq(x, "foo"));
252 assert_se(v == 5);
253 assert_se(streq(y, "waldo"));
254
255 r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
256 assert_se(r > 0);
257 assert_se(boolean);
258 assert_se(streq(x, "aaa"));
259 assert_se(streq(y, "1"));
260 assert_se(streq(a, "bbb"));
261 assert_se(streq(b, "2"));
262 assert_se(streq(c, "ccc"));
263 assert_se(streq(d, "3"));
264
265 assert_se(sd_bus_message_verify_type(m, 'a', "s") > 0);
266
267 r = sd_bus_message_read(m, "as", 2, &x, &y);
268 assert_se(r > 0);
269 assert_se(streq(x, "foobar"));
270 assert_se(streq(y, "waldo"));
271
272 r = sd_bus_message_read_basic(m, 's', &s);
273 assert_se(r > 0);
274 assert_se(streq(s, "hallo"));
275
276 r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz);
277 assert_se(r > 0);
278 assert_se(sz == sizeof(integer_array));
279 assert_se(memcmp(integer_array, return_array, sz) == 0);
280
281 r = sd_bus_message_read_array(m, 'u', (const void**) &return_array, &sz);
282 assert_se(r > 0);
283 assert_se(sz == 0);
284
285 r = sd_bus_message_read(m, "a(stdo)", 1, &x, &u64, &dbl, &y);
286 assert_se(r > 0);
287 assert_se(streq(x, "foo"));
288 assert_se(u64 == 815ULL);
289 assert_se(fabs(dbl - 47.0) < 0.1);
290 assert_se(streq(y, "/"));
291
292 r = sd_bus_message_peek_type(m, NULL, NULL);
293 assert_se(r == 0);
294
295 r = sd_bus_message_new_method_call(bus, &copy, "foobar.waldo", "/", "foobar.waldo", "Piep");
296 assert_se(r >= 0);
297
298 r = sd_bus_message_rewind(m, true);
299 assert_se(r >= 0);
300
301 r = sd_bus_message_copy(copy, m, true);
302 assert_se(r >= 0);
303
304 r = bus_message_seal(copy, 4712, 0);
305 assert_se(r >= 0);
306
307 fclose(ms);
308 ms = open_memstream(&third, &third_size);
309 bus_message_dump(copy, ms, 0);
310 fflush(ms);
311 assert_se(!ferror(ms));
312
313 printf("<%.*s>\n", (int) first_size, first);
314 printf("<%.*s>\n", (int) third_size, third);
315
316 assert_se(first_size == third_size);
317 assert_se(memcmp(first, third, third_size) == 0);
318
319 r = sd_bus_message_rewind(m, true);
320 assert_se(r >= 0);
321
322 assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
323
324 r = sd_bus_message_skip(m, "ssasg");
325 assert_se(r > 0);
326
327 assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
328
329 r = sd_bus_message_skip(m, "sass");
330 assert_se(r >= 0);
331
332 assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
333
334 r = sd_bus_message_skip(m, "a{yv}");
335 assert_se(r >= 0);
336
337 assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
338
339 r = sd_bus_message_read(m, "b", &boolean);
340 assert_se(r > 0);
341 assert_se(boolean);
342
343 r = sd_bus_message_enter_container(m, 0, NULL);
344 assert_se(r > 0);
345
346 r = sd_bus_message_read(m, "(ss)", &x, &y);
347 assert_se(r > 0);
348
349 r = sd_bus_message_read(m, "(ss)", &a, &b);
350 assert_se(r > 0);
351
352 r = sd_bus_message_read(m, "(ss)", &c, &d);
353 assert_se(r > 0);
354
355 r = sd_bus_message_read(m, "(ss)", &x, &y);
356 assert_se(r == 0);
357
358 r = sd_bus_message_exit_container(m);
359 assert_se(r >= 0);
360
361 assert_se(streq(x, "aaa"));
362 assert_se(streq(y, "1"));
363 assert_se(streq(a, "bbb"));
364 assert_se(streq(b, "2"));
365 assert_se(streq(c, "ccc"));
366 assert_se(streq(d, "3"));
367
368 test_bus_label_escape();
369 test_bus_path_encode();
370 test_bus_path_encode_unique();
371
372 return 0;
373 }