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