]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-bus/test-bus-marshal.c
bus: let's simplify things by getting rid of unnecessary bus parameters
[thirdparty/systemd.git] / src / libsystemd-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;
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, "as", 2, "string #1", "string #2");
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);
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, "ssas", &x, &x2, 2, &y, &z);
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
197 r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d);
198 assert_se(r > 0);
199 assert_se(streq(x, "foobar"));
200 assert_se(streq(y, "foo"));
201 assert_se(streq(z, "bar"));
202 assert_se(streq(a, "waldo"));
203 assert_se(streq(b, "piep"));
204 assert_se(streq(c, "pap"));
205 assert_se(streq(d, "after"));
206
207 r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y);
208 assert_se(r > 0);
209 assert_se(u == 3);
210 assert_se(streq(x, "foo"));
211 assert_se(v == 5);
212 assert_se(streq(y, "waldo"));
213
214 r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
215 assert_se(r > 0);
216 assert_se(boolean);
217 assert_se(streq(x, "aaa"));
218 assert_se(streq(y, "1"));
219 assert_se(streq(a, "bbb"));
220 assert_se(streq(b, "2"));
221 assert_se(streq(c, "ccc"));
222 assert_se(streq(d, "3"));
223
224 assert_se(sd_bus_message_verify_type(m, 'a', "s") > 0);
225
226 r = sd_bus_message_read(m, "as", 2, &x, &y);
227 assert_se(r > 0);
228 assert_se(streq(x, "foobar"));
229 assert_se(streq(y, "waldo"));
230
231 r = sd_bus_message_read_basic(m, 's', &s);
232 assert_se(r > 0);
233 assert_se(streq(s, "hallo"));
234
235 r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz);
236 assert_se(r > 0);
237 assert_se(sz == sizeof(integer_array));
238 assert_se(memcmp(integer_array, return_array, sz) == 0);
239
240 r = sd_bus_message_read_array(m, 'u', (const void**) &return_array, &sz);
241 assert_se(r > 0);
242 assert_se(sz == 0);
243
244 r = sd_bus_message_peek_type(m, NULL, NULL);
245 assert_se(r == 0);
246
247 r = sd_bus_message_new_method_call(NULL, "foobar.waldo", "/", "foobar.waldo", "Piep", &copy);
248 assert_se(r >= 0);
249
250 r = sd_bus_message_rewind(m, true);
251 assert_se(r >= 0);
252
253 r = sd_bus_message_copy(copy, m, true);
254 assert_se(r >= 0);
255
256 r = bus_message_seal(copy, 4712);
257 assert_se(r >= 0);
258
259 fclose(ms);
260 ms = open_memstream(&third, &third_size);
261 bus_message_dump(copy, ms, false);
262 fflush(ms);
263 assert_se(!ferror(ms));
264
265 printf("<%.*s>", (int) first_size, first);
266 printf("<%.*s>", (int) third_size, third);
267
268 assert_se(first_size == third_size);
269 assert_se(memcmp(first, third, third_size) == 0);
270
271 r = sd_bus_message_rewind(m, true);
272 assert_se(r >= 0);
273
274 assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
275
276 r = sd_bus_message_skip(m, "ssas");
277 assert_se(r > 0);
278
279 assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
280
281 r = sd_bus_message_skip(m, "sass");
282 assert_se(r >= 0);
283
284 assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
285
286 r = sd_bus_message_skip(m, "a{yv}");
287 assert_se(r >= 0);
288
289 assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
290
291 r = sd_bus_message_read(m, "b", &boolean);
292 assert_se(r > 0);
293 assert_se(boolean);
294
295 r = sd_bus_message_enter_container(m, 0, NULL);
296 assert_se(r > 0);
297
298 r = sd_bus_message_read(m, "(ss)", &x, &y);
299 assert_se(r > 0);
300
301 r = sd_bus_message_read(m, "(ss)", &a, &b);
302 assert_se(r > 0);
303
304 r = sd_bus_message_read(m, "(ss)", &c, &d);
305 assert_se(r > 0);
306
307 r = sd_bus_message_read(m, "(ss)", &x, &y);
308 assert_se(r == 0);
309
310 r = sd_bus_message_exit_container(m);
311 assert_se(r >= 0);
312
313 assert_se(streq(x, "aaa"));
314 assert_se(streq(y, "1"));
315 assert_se(streq(a, "bbb"));
316 assert_se(streq(b, "2"));
317 assert_se(streq(c, "ccc"));
318 assert_se(streq(d, "3"));
319
320 test_bus_label_escape();
321
322 return 0;
323 }