chiark / gitweb /
bus: when allocating a memfd for usage in a bus connection, name the memfd after...
[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, "foobar.waldo", "/", "foobar.waldo", "Piep", &m);
80         assert_se(r >= 0);
81
82         r = sd_bus_message_append(m, "s", "a string");
83         assert_se(r >= 0);
84
85         r = sd_bus_message_append(m, "s", NULL);
86         assert_se(r >= 0);
87
88         r = sd_bus_message_append(m, "asg", 2, "string #1", "string #2", "sba(tt)ss");
89         assert_se(r >= 0);
90
91         r = sd_bus_message_append(m, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after");
92         assert_se(r >= 0);
93
94         r = sd_bus_message_append(m, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo");
95         assert_se(r >= 0);
96
97         r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
98         assert_se(r >= 0);
99
100         r = sd_bus_message_open_container(m, 'a', "s");
101         assert_se(r >= 0);
102
103         r = sd_bus_message_append_basic(m, 's', "foobar");
104         assert_se(r >= 0);
105
106         r = sd_bus_message_append_basic(m, 's', "waldo");
107         assert_se(r >= 0);
108
109         r = sd_bus_message_close_container(m);
110         assert_se(r >= 0);
111
112         r = sd_bus_message_append_string_space(m, 5, &s);
113         assert_se(r >= 0);
114         strcpy(s, "hallo");
115
116         r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array));
117         assert_se(r >= 0);
118
119         r = sd_bus_message_append_array(m, 'u', NULL, 0);
120         assert_se(r >= 0);
121
122         r = bus_message_seal(m, 4711, 0);
123         assert_se(r >= 0);
124
125         bus_message_dump(m, stdout, true);
126
127         ms = open_memstream(&first, &first_size);
128         bus_message_dump(m, ms, false);
129         fflush(ms);
130         assert_se(!ferror(ms));
131
132         r = bus_message_get_blob(m, &buffer, &sz);
133         assert_se(r >= 0);
134
135         h = hexmem(buffer, sz);
136         assert_se(h);
137
138         log_info("message size = %lu, contents =\n%s", (unsigned long) sz, h);
139         free(h);
140
141 #ifdef HAVE_GLIB
142         {
143                 GDBusMessage *g;
144                 char *p;
145
146 #if !defined(GLIB_VERSION_2_36)
147                 g_type_init();
148 #endif
149
150                 g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL);
151                 p = g_dbus_message_print(g, 0);
152                 log_info("%s", p);
153                 g_free(p);
154                 g_object_unref(g);
155         }
156 #endif
157
158 #ifdef HAVE_DBUS
159         {
160                 DBusMessage *w;
161                 DBusError error;
162
163                 dbus_error_init(&error);
164
165                 w = dbus_message_demarshal(buffer, sz, &error);
166                 if (!w)
167                         log_error("%s", error.message);
168                 else
169                         dbus_message_unref(w);
170         }
171 #endif
172
173         m = sd_bus_message_unref(m);
174
175         r = bus_message_from_malloc(NULL, buffer, sz, NULL, 0, NULL, NULL, &m);
176         assert_se(r >= 0);
177
178         bus_message_dump(m, stdout, true);
179
180         fclose(ms);
181         ms = open_memstream(&second, &second_size);
182         bus_message_dump(m, ms, false);
183         fflush(ms);
184         assert_se(!ferror(ms));
185         assert_se(first_size == second_size);
186         assert_se(memcmp(first, second, first_size) == 0);
187
188         assert_se(sd_bus_message_rewind(m, true) >= 0);
189
190         r = sd_bus_message_read(m, "ssasg", &x, &x2, 2, &y, &z, &a_signature);
191         assert_se(r > 0);
192         assert_se(streq(x, "a string"));
193         assert_se(streq(x2, ""));
194         assert_se(streq(y, "string #1"));
195         assert_se(streq(z, "string #2"));
196         assert_se(streq(a_signature, "sba(tt)ss"));
197
198         r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d);
199         assert_se(r > 0);
200         assert_se(streq(x, "foobar"));
201         assert_se(streq(y, "foo"));
202         assert_se(streq(z, "bar"));
203         assert_se(streq(a, "waldo"));
204         assert_se(streq(b, "piep"));
205         assert_se(streq(c, "pap"));
206         assert_se(streq(d, "after"));
207
208         r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y);
209         assert_se(r > 0);
210         assert_se(u == 3);
211         assert_se(streq(x, "foo"));
212         assert_se(v == 5);
213         assert_se(streq(y, "waldo"));
214
215         r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
216         assert_se(r > 0);
217         assert_se(boolean);
218         assert_se(streq(x, "aaa"));
219         assert_se(streq(y, "1"));
220         assert_se(streq(a, "bbb"));
221         assert_se(streq(b, "2"));
222         assert_se(streq(c, "ccc"));
223         assert_se(streq(d, "3"));
224
225         assert_se(sd_bus_message_verify_type(m, 'a', "s") > 0);
226
227         r = sd_bus_message_read(m, "as", 2, &x, &y);
228         assert_se(r > 0);
229         assert_se(streq(x, "foobar"));
230         assert_se(streq(y, "waldo"));
231
232         r = sd_bus_message_read_basic(m, 's', &s);
233         assert_se(r > 0);
234         assert_se(streq(s, "hallo"));
235
236         r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz);
237         assert_se(r > 0);
238         assert_se(sz == sizeof(integer_array));
239         assert_se(memcmp(integer_array, return_array, sz) == 0);
240
241         r = sd_bus_message_read_array(m, 'u', (const void**) &return_array, &sz);
242         assert_se(r > 0);
243         assert_se(sz == 0);
244
245         r = sd_bus_message_peek_type(m, NULL, NULL);
246         assert_se(r == 0);
247
248         r = sd_bus_message_new_method_call(NULL, "foobar.waldo", "/", "foobar.waldo", "Piep", &copy);
249         assert_se(r >= 0);
250
251         r = sd_bus_message_rewind(m, true);
252         assert_se(r >= 0);
253
254         r = sd_bus_message_copy(copy, m, true);
255         assert_se(r >= 0);
256
257         r = bus_message_seal(copy, 4712, 0);
258         assert_se(r >= 0);
259
260         fclose(ms);
261         ms = open_memstream(&third, &third_size);
262         bus_message_dump(copy, ms, false);
263         fflush(ms);
264         assert_se(!ferror(ms));
265
266         printf("<%.*s>\n", (int) first_size, first);
267         printf("<%.*s>\n", (int) third_size, third);
268
269         assert_se(first_size == third_size);
270         assert_se(memcmp(first, third, third_size) == 0);
271
272         r = sd_bus_message_rewind(m, true);
273         assert_se(r >= 0);
274
275         assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
276
277         r = sd_bus_message_skip(m, "ssasg");
278         assert_se(r > 0);
279
280         assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
281
282         r = sd_bus_message_skip(m, "sass");
283         assert_se(r >= 0);
284
285         assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
286
287         r = sd_bus_message_skip(m, "a{yv}");
288         assert_se(r >= 0);
289
290         assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
291
292         r = sd_bus_message_read(m, "b", &boolean);
293         assert_se(r > 0);
294         assert_se(boolean);
295
296         r = sd_bus_message_enter_container(m, 0, NULL);
297         assert_se(r > 0);
298
299         r = sd_bus_message_read(m, "(ss)", &x, &y);
300         assert_se(r > 0);
301
302         r = sd_bus_message_read(m, "(ss)", &a, &b);
303         assert_se(r > 0);
304
305         r = sd_bus_message_read(m, "(ss)", &c, &d);
306         assert_se(r > 0);
307
308         r = sd_bus_message_read(m, "(ss)", &x, &y);
309         assert_se(r == 0);
310
311         r = sd_bus_message_exit_container(m);
312         assert_se(r >= 0);
313
314         assert_se(streq(x, "aaa"));
315         assert_se(streq(y, "1"));
316         assert_se(streq(a, "bbb"));
317         assert_se(streq(b, "2"));
318         assert_se(streq(c, "ccc"));
319         assert_se(streq(d, "3"));
320
321         test_bus_label_escape();
322
323         return 0;
324 }