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