chiark / gitweb /
sd-bus: drop redundant code
[elogind.git] / src / libelogind / 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, "y(ty)y(yt)y", 8, 777ULL, 7, 9, 77, 7777ULL, 10);
135         assert_se(r >= 0);
136
137         r = sd_bus_message_append(m, "()");
138         assert_se(r >= 0);
139
140         r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
141         assert_se(r >= 0);
142
143         r = sd_bus_message_open_container(m, 'a', "s");
144         assert_se(r >= 0);
145
146         r = sd_bus_message_append_basic(m, 's', "foobar");
147         assert_se(r >= 0);
148
149         r = sd_bus_message_append_basic(m, 's', "waldo");
150         assert_se(r >= 0);
151
152         r = sd_bus_message_close_container(m);
153         assert_se(r >= 0);
154
155         r = sd_bus_message_append_string_space(m, 5, &s);
156         assert_se(r >= 0);
157         strcpy(s, "hallo");
158
159         r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array));
160         assert_se(r >= 0);
161
162         r = sd_bus_message_append_array(m, 'u', NULL, 0);
163         assert_se(r >= 0);
164
165         r = sd_bus_message_append(m, "a(stdo)", 1, "foo", 815ULL, 47.0, "/");
166         assert_se(r >= 0);
167
168         r = bus_message_seal(m, 4711, 0);
169         assert_se(r >= 0);
170
171         bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
172
173         ms = open_memstream(&first, &first_size);
174         bus_message_dump(m, ms, 0);
175         fflush(ms);
176         assert_se(!ferror(ms));
177
178         r = bus_message_get_blob(m, &buffer, &sz);
179         assert_se(r >= 0);
180
181         h = hexmem(buffer, sz);
182         assert_se(h);
183
184         log_info("message size = %zu, contents =\n%s", sz, h);
185         free(h);
186
187 #ifdef HAVE_GLIB
188         {
189                 GDBusMessage *g;
190                 char *p;
191
192 #if !defined(GLIB_VERSION_2_36)
193                 g_type_init();
194 #endif
195
196                 g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL);
197                 p = g_dbus_message_print(g, 0);
198                 log_info("%s", p);
199                 g_free(p);
200                 g_object_unref(g);
201         }
202 #endif
203
204 #ifdef HAVE_DBUS
205         {
206                 DBusMessage *w;
207                 DBusError error;
208
209                 dbus_error_init(&error);
210
211                 w = dbus_message_demarshal(buffer, sz, &error);
212                 if (!w)
213                         log_error("%s", error.message);
214                 else
215                         dbus_message_unref(w);
216         }
217 #endif
218
219         m = sd_bus_message_unref(m);
220
221         r = bus_message_from_malloc(bus, buffer, sz, NULL, 0, NULL, &m);
222         assert_se(r >= 0);
223
224         bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
225
226         fclose(ms);
227         ms = open_memstream(&second, &second_size);
228         bus_message_dump(m, ms, 0);
229         fflush(ms);
230         assert_se(!ferror(ms));
231         assert_se(first_size == second_size);
232         assert_se(memcmp(first, second, first_size) == 0);
233
234         assert_se(sd_bus_message_rewind(m, true) >= 0);
235
236         r = sd_bus_message_read(m, "ssasg", &x, &x2, 2, &y, &z, &a_signature);
237         assert_se(r > 0);
238         assert_se(streq(x, "a string"));
239         assert_se(streq(x2, ""));
240         assert_se(streq(y, "string #1"));
241         assert_se(streq(z, "string #2"));
242         assert_se(streq(a_signature, "sba(tt)ss"));
243
244         r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d);
245         assert_se(r > 0);
246         assert_se(streq(x, "foobar"));
247         assert_se(streq(y, "foo"));
248         assert_se(streq(z, "bar"));
249         assert_se(streq(a, "waldo"));
250         assert_se(streq(b, "piep"));
251         assert_se(streq(c, "pap"));
252         assert_se(streq(d, "after"));
253
254         r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y);
255         assert_se(r > 0);
256         assert_se(u == 3);
257         assert_se(streq(x, "foo"));
258         assert_se(v == 5);
259         assert_se(streq(y, "waldo"));
260
261         r = sd_bus_message_read(m, "y(ty)", &v, &u64, &u);
262         assert_se(r > 0);
263         assert_se(v == 8);
264         assert_se(u64 == 777);
265         assert_se(u == 7);
266
267         r = sd_bus_message_read(m, "y(yt)", &v, &u, &u64);
268         assert_se(r > 0);
269         assert_se(v == 9);
270         assert_se(u == 77);
271         assert_se(u64 == 7777);
272
273         r = sd_bus_message_read(m, "y", &v);
274         assert_se(r > 0);
275         assert_se(v == 10);
276
277         r = sd_bus_message_read(m, "()");
278         assert_se(r > 0);
279
280         r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
281         assert_se(r > 0);
282         assert_se(boolean);
283         assert_se(streq(x, "aaa"));
284         assert_se(streq(y, "1"));
285         assert_se(streq(a, "bbb"));
286         assert_se(streq(b, "2"));
287         assert_se(streq(c, "ccc"));
288         assert_se(streq(d, "3"));
289
290         assert_se(sd_bus_message_verify_type(m, 'a', "s") > 0);
291
292         r = sd_bus_message_read(m, "as", 2, &x, &y);
293         assert_se(r > 0);
294         assert_se(streq(x, "foobar"));
295         assert_se(streq(y, "waldo"));
296
297         r = sd_bus_message_read_basic(m, 's', &s);
298         assert_se(r > 0);
299         assert_se(streq(s, "hallo"));
300
301         r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz);
302         assert_se(r > 0);
303         assert_se(sz == sizeof(integer_array));
304         assert_se(memcmp(integer_array, return_array, sz) == 0);
305
306         r = sd_bus_message_read_array(m, 'u', (const void**) &return_array, &sz);
307         assert_se(r > 0);
308         assert_se(sz == 0);
309
310         r = sd_bus_message_read(m, "a(stdo)", 1, &x, &u64, &dbl, &y);
311         assert_se(r > 0);
312         assert_se(streq(x, "foo"));
313         assert_se(u64 == 815ULL);
314         assert_se(fabs(dbl - 47.0) < 0.1);
315         assert_se(streq(y, "/"));
316
317         r = sd_bus_message_peek_type(m, NULL, NULL);
318         assert_se(r == 0);
319
320         r = sd_bus_message_new_method_call(bus, &copy, "foobar.waldo", "/", "foobar.waldo", "Piep");
321         assert_se(r >= 0);
322
323         r = sd_bus_message_rewind(m, true);
324         assert_se(r >= 0);
325
326         r = sd_bus_message_copy(copy, m, true);
327         assert_se(r >= 0);
328
329         r = bus_message_seal(copy, 4712, 0);
330         assert_se(r >= 0);
331
332         fclose(ms);
333         ms = open_memstream(&third, &third_size);
334         bus_message_dump(copy, ms, 0);
335         fflush(ms);
336         assert_se(!ferror(ms));
337
338         printf("<%.*s>\n", (int) first_size, first);
339         printf("<%.*s>\n", (int) third_size, third);
340
341         assert_se(first_size == third_size);
342         assert_se(memcmp(first, third, third_size) == 0);
343
344         r = sd_bus_message_rewind(m, true);
345         assert_se(r >= 0);
346
347         assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
348
349         r = sd_bus_message_skip(m, "ssasg");
350         assert_se(r > 0);
351
352         assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
353
354         r = sd_bus_message_skip(m, "sass");
355         assert_se(r >= 0);
356
357         assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
358
359         r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y()");
360         assert_se(r >= 0);
361
362         assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
363
364         r = sd_bus_message_read(m, "b", &boolean);
365         assert_se(r > 0);
366         assert_se(boolean);
367
368         r = sd_bus_message_enter_container(m, 0, NULL);
369         assert_se(r > 0);
370
371         r = sd_bus_message_read(m, "(ss)", &x, &y);
372         assert_se(r > 0);
373
374         r = sd_bus_message_read(m, "(ss)", &a, &b);
375         assert_se(r > 0);
376
377         r = sd_bus_message_read(m, "(ss)", &c, &d);
378         assert_se(r > 0);
379
380         r = sd_bus_message_read(m, "(ss)", &x, &y);
381         assert_se(r == 0);
382
383         r = sd_bus_message_exit_container(m);
384         assert_se(r >= 0);
385
386         assert_se(streq(x, "aaa"));
387         assert_se(streq(y, "1"));
388         assert_se(streq(a, "bbb"));
389         assert_se(streq(b, "2"));
390         assert_se(streq(c, "ccc"));
391         assert_se(streq(d, "3"));
392
393         test_bus_label_escape();
394         test_bus_path_encode();
395         test_bus_path_encode_unique();
396
397         return 0;
398 }