chiark / gitweb /
d438a231a635426cfffaf812fd0ae76d5169cc38
[elogind.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 <assert.h>
23 #include <stdlib.h>
24 #include <byteswap.h>
25
26 #ifdef HAVE_GLIB
27 #include <gio/gio.h>
28 #endif
29
30 #ifdef HAVE_DBUS
31 #include <dbus/dbus.h>
32 #endif
33
34 #include "log.h"
35 #include "util.h"
36
37 #include "sd-bus.h"
38 #include "bus-message.h"
39 #include "bus-util.h"
40 #include "bus-dump.h"
41
42 static void test_bus_label_escape_one(const char *a, const char *b) {
43         _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
44
45         assert_se(t = sd_bus_label_escape(a));
46         assert_se(streq(t, b));
47
48         assert_se(x = sd_bus_label_unescape(t));
49         assert_se(streq(a, x));
50
51         assert_se(y = sd_bus_label_unescape(b));
52         assert_se(streq(a, y));
53 }
54
55 static void test_bus_label_escape(void) {
56         test_bus_label_escape_one("foo123bar", "foo123bar");
57         test_bus_label_escape_one("foo.bar", "foo_2ebar");
58         test_bus_label_escape_one("foo_2ebar", "foo_5f2ebar");
59         test_bus_label_escape_one("", "_");
60         test_bus_label_escape_one("_", "_5f");
61         test_bus_label_escape_one("1", "_31");
62         test_bus_label_escape_one(":1", "_3a1");
63 }
64
65 int main(int argc, char *argv[]) {
66         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *copy = NULL;
67         int r, boolean;
68         const char *x, *x2, *y, *z, *a, *b, *c, *d, *a_signature;
69         uint8_t u, v;
70         void *buffer = NULL;
71         size_t sz;
72         char *h;
73         const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array;
74         char *s;
75         _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL;
76         _cleanup_fclose_ FILE *ms = NULL;
77         size_t first_size = 0, second_size = 0, third_size = 0;
78
79         r = sd_bus_message_new_method_call(NULL, &m, "foobar.waldo", "/", "foobar.waldo", "Piep");
80         assert_se(r >= 0);
81
82         r = sd_bus_message_append(m, "");
83         assert_se(r >= 0);
84
85         r = sd_bus_message_append(m, "s", "a string");
86         assert_se(r >= 0);
87
88         r = sd_bus_message_append(m, "s", NULL);
89         assert_se(r >= 0);
90
91         r = sd_bus_message_append(m, "asg", 2, "string #1", "string #2", "sba(tt)ss");
92         assert_se(r >= 0);
93
94         r = sd_bus_message_append(m, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after");
95         assert_se(r >= 0);
96
97         r = sd_bus_message_append(m, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo");
98         assert_se(r >= 0);
99
100         r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
101         assert_se(r >= 0);
102
103         r = sd_bus_message_open_container(m, 'a', "s");
104         assert_se(r >= 0);
105
106         r = sd_bus_message_append_basic(m, 's', "foobar");
107         assert_se(r >= 0);
108
109         r = sd_bus_message_append_basic(m, 's', "waldo");
110         assert_se(r >= 0);
111
112         r = sd_bus_message_close_container(m);
113         assert_se(r >= 0);
114
115         r = sd_bus_message_append_string_space(m, 5, &s);
116         assert_se(r >= 0);
117         strcpy(s, "hallo");
118
119         r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array));
120         assert_se(r >= 0);
121
122         r = sd_bus_message_append_array(m, 'u', NULL, 0);
123         assert_se(r >= 0);
124
125         r = bus_message_seal(m, 4711, 0);
126         assert_se(r >= 0);
127
128         bus_message_dump(m, stdout, true);
129
130         ms = open_memstream(&first, &first_size);
131         bus_message_dump(m, ms, false);
132         fflush(ms);
133         assert_se(!ferror(ms));
134
135         r = bus_message_get_blob(m, &buffer, &sz);
136         assert_se(r >= 0);
137
138         h = hexmem(buffer, sz);
139         assert_se(h);
140
141         log_info("message size = %lu, contents =\n%s", (unsigned long) sz, h);
142         free(h);
143
144 #ifdef HAVE_GLIB
145         {
146                 GDBusMessage *g;
147                 char *p;
148
149 #if !defined(GLIB_VERSION_2_36)
150                 g_type_init();
151 #endif
152
153                 g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL);
154                 p = g_dbus_message_print(g, 0);
155                 log_info("%s", p);
156                 g_free(p);
157                 g_object_unref(g);
158         }
159 #endif
160
161 #ifdef HAVE_DBUS
162         {
163                 DBusMessage *w;
164                 DBusError error;
165
166                 dbus_error_init(&error);
167
168                 w = dbus_message_demarshal(buffer, sz, &error);
169                 if (!w)
170                         log_error("%s", error.message);
171                 else
172                         dbus_message_unref(w);
173         }
174 #endif
175
176         m = sd_bus_message_unref(m);
177
178         r = bus_message_from_malloc(NULL, buffer, sz, NULL, 0, NULL, NULL, &m);
179         assert_se(r >= 0);
180
181         bus_message_dump(m, stdout, true);
182
183         fclose(ms);
184         ms = open_memstream(&second, &second_size);
185         bus_message_dump(m, ms, false);
186         fflush(ms);
187         assert_se(!ferror(ms));
188         assert_se(first_size == second_size);
189         assert_se(memcmp(first, second, first_size) == 0);
190
191         assert_se(sd_bus_message_rewind(m, true) >= 0);
192
193         r = sd_bus_message_read(m, "ssasg", &x, &x2, 2, &y, &z, &a_signature);
194         assert_se(r > 0);
195         assert_se(streq(x, "a string"));
196         assert_se(streq(x2, ""));
197         assert_se(streq(y, "string #1"));
198         assert_se(streq(z, "string #2"));
199         assert_se(streq(a_signature, "sba(tt)ss"));
200
201         r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d);
202         assert_se(r > 0);
203         assert_se(streq(x, "foobar"));
204         assert_se(streq(y, "foo"));
205         assert_se(streq(z, "bar"));
206         assert_se(streq(a, "waldo"));
207         assert_se(streq(b, "piep"));
208         assert_se(streq(c, "pap"));
209         assert_se(streq(d, "after"));
210
211         r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y);
212         assert_se(r > 0);
213         assert_se(u == 3);
214         assert_se(streq(x, "foo"));
215         assert_se(v == 5);
216         assert_se(streq(y, "waldo"));
217
218         r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
219         assert_se(r > 0);
220         assert_se(boolean);
221         assert_se(streq(x, "aaa"));
222         assert_se(streq(y, "1"));
223         assert_se(streq(a, "bbb"));
224         assert_se(streq(b, "2"));
225         assert_se(streq(c, "ccc"));
226         assert_se(streq(d, "3"));
227
228         assert_se(sd_bus_message_verify_type(m, 'a', "s") > 0);
229
230         r = sd_bus_message_read(m, "as", 2, &x, &y);
231         assert_se(r > 0);
232         assert_se(streq(x, "foobar"));
233         assert_se(streq(y, "waldo"));
234
235         r = sd_bus_message_read_basic(m, 's', &s);
236         assert_se(r > 0);
237         assert_se(streq(s, "hallo"));
238
239         r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz);
240         assert_se(r > 0);
241         assert_se(sz == sizeof(integer_array));
242         assert_se(memcmp(integer_array, return_array, sz) == 0);
243
244         r = sd_bus_message_read_array(m, 'u', (const void**) &return_array, &sz);
245         assert_se(r > 0);
246         assert_se(sz == 0);
247
248         r = sd_bus_message_peek_type(m, NULL, NULL);
249         assert_se(r == 0);
250
251         r = sd_bus_message_new_method_call(NULL, &copy, "foobar.waldo", "/", "foobar.waldo", "Piep");
252         assert_se(r >= 0);
253
254         r = sd_bus_message_rewind(m, true);
255         assert_se(r >= 0);
256
257         r = sd_bus_message_copy(copy, m, true);
258         assert_se(r >= 0);
259
260         r = bus_message_seal(copy, 4712, 0);
261         assert_se(r >= 0);
262
263         fclose(ms);
264         ms = open_memstream(&third, &third_size);
265         bus_message_dump(copy, ms, false);
266         fflush(ms);
267         assert_se(!ferror(ms));
268
269         printf("<%.*s>\n", (int) first_size, first);
270         printf("<%.*s>\n", (int) third_size, third);
271
272         assert_se(first_size == third_size);
273         assert_se(memcmp(first, third, third_size) == 0);
274
275         r = sd_bus_message_rewind(m, true);
276         assert_se(r >= 0);
277
278         assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
279
280         r = sd_bus_message_skip(m, "ssasg");
281         assert_se(r > 0);
282
283         assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
284
285         r = sd_bus_message_skip(m, "sass");
286         assert_se(r >= 0);
287
288         assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
289
290         r = sd_bus_message_skip(m, "a{yv}");
291         assert_se(r >= 0);
292
293         assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
294
295         r = sd_bus_message_read(m, "b", &boolean);
296         assert_se(r > 0);
297         assert_se(boolean);
298
299         r = sd_bus_message_enter_container(m, 0, NULL);
300         assert_se(r > 0);
301
302         r = sd_bus_message_read(m, "(ss)", &x, &y);
303         assert_se(r > 0);
304
305         r = sd_bus_message_read(m, "(ss)", &a, &b);
306         assert_se(r > 0);
307
308         r = sd_bus_message_read(m, "(ss)", &c, &d);
309         assert_se(r > 0);
310
311         r = sd_bus_message_read(m, "(ss)", &x, &y);
312         assert_se(r == 0);
313
314         r = sd_bus_message_exit_container(m);
315         assert_se(r >= 0);
316
317         assert_se(streq(x, "aaa"));
318         assert_se(streq(y, "1"));
319         assert_se(streq(a, "bbb"));
320         assert_se(streq(b, "2"));
321         assert_se(streq(c, "ccc"));
322         assert_se(streq(d, "3"));
323
324         test_bus_label_escape();
325
326         return 0;
327 }