1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
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.
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.
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/>.
30 #include <dbus/dbus.h>
37 #include "bus-message.h"
40 #include "bus-label.h"
42 static void test_bus_path_encode_unique(void) {
43 _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
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, ""));
52 static void test_bus_path_encode(void) {
53 _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
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"));
59 assert_se(sd_bus_path_encode("xxxx", "waldo", &c) < 0);
60 assert_se(sd_bus_path_encode("/foo/", "waldo", &c) < 0);
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, ""));
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"));
69 static void test_bus_label_escape_one(const char *a, const char *b) {
70 _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
72 assert_se(t = bus_label_escape(a));
73 assert_se(streq(t, b));
75 assert_se(x = bus_label_unescape(t));
76 assert_se(streq(a, x));
78 assert_se(y = bus_label_unescape(b));
79 assert_se(streq(a, y));
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");
92 int main(int argc, char *argv[]) {
93 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *copy = NULL;
95 const char *x, *x2, *y, *z, *a, *b, *c, *d, *a_signature;
100 const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array;
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;
109 r = sd_bus_default_system(&bus);
111 return EXIT_TEST_SKIP;
113 r = sd_bus_message_new_method_call(bus, &m, "foobar.waldo", "/", "foobar.waldo", "Piep");
116 r = sd_bus_message_append(m, "");
119 r = sd_bus_message_append(m, "s", "a string");
122 r = sd_bus_message_append(m, "s", NULL);
125 r = sd_bus_message_append(m, "asg", 2, "string #1", "string #2", "sba(tt)ss");
128 r = sd_bus_message_append(m, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after");
131 r = sd_bus_message_append(m, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo");
134 r = sd_bus_message_append(m, "y(ty)y(yt)y", 8, 777ULL, 7, 9, 77, 7777ULL, 10);
137 r = sd_bus_message_append(m, "()");
140 r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
143 r = sd_bus_message_open_container(m, 'a', "s");
146 r = sd_bus_message_append_basic(m, 's', "foobar");
149 r = sd_bus_message_append_basic(m, 's', "waldo");
152 r = sd_bus_message_close_container(m);
155 r = sd_bus_message_append_string_space(m, 5, &s);
159 r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array));
162 r = sd_bus_message_append_array(m, 'u', NULL, 0);
165 r = sd_bus_message_append(m, "a(stdo)", 1, "foo", 815ULL, 47.0, "/");
168 r = bus_message_seal(m, 4711, 0);
171 bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
173 ms = open_memstream(&first, &first_size);
174 bus_message_dump(m, ms, 0);
176 assert_se(!ferror(ms));
178 r = bus_message_get_blob(m, &buffer, &sz);
181 h = hexmem(buffer, sz);
184 log_info("message size = %zu, contents =\n%s", sz, h);
192 #if !defined(GLIB_VERSION_2_36)
196 g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL);
197 p = g_dbus_message_print(g, 0);
209 dbus_error_init(&error);
211 w = dbus_message_demarshal(buffer, sz, &error);
213 log_error("%s", error.message);
215 dbus_message_unref(w);
219 m = sd_bus_message_unref(m);
221 r = bus_message_from_malloc(bus, buffer, sz, NULL, 0, NULL, &m);
224 bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
227 ms = open_memstream(&second, &second_size);
228 bus_message_dump(m, ms, 0);
230 assert_se(!ferror(ms));
231 assert_se(first_size == second_size);
232 assert_se(memcmp(first, second, first_size) == 0);
234 assert_se(sd_bus_message_rewind(m, true) >= 0);
236 r = sd_bus_message_read(m, "ssasg", &x, &x2, 2, &y, &z, &a_signature);
238 assert_se(streq(x, "a string"));
239 assert_se(streq(x2, ""));
240 assert_se(streq(y, "string #1"));
241 assert_se(streq(z, "string #2"));
242 assert_se(streq(a_signature, "sba(tt)ss"));
244 r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d);
246 assert_se(streq(x, "foobar"));
247 assert_se(streq(y, "foo"));
248 assert_se(streq(z, "bar"));
249 assert_se(streq(a, "waldo"));
250 assert_se(streq(b, "piep"));
251 assert_se(streq(c, "pap"));
252 assert_se(streq(d, "after"));
254 r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y);
257 assert_se(streq(x, "foo"));
259 assert_se(streq(y, "waldo"));
261 r = sd_bus_message_read(m, "y(ty)", &v, &u64, &u);
264 assert_se(u64 == 777);
267 r = sd_bus_message_read(m, "y(yt)", &v, &u, &u64);
271 assert_se(u64 == 7777);
273 r = sd_bus_message_read(m, "y", &v);
277 r = sd_bus_message_read(m, "()");
280 r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
283 assert_se(streq(x, "aaa"));
284 assert_se(streq(y, "1"));
285 assert_se(streq(a, "bbb"));
286 assert_se(streq(b, "2"));
287 assert_se(streq(c, "ccc"));
288 assert_se(streq(d, "3"));
290 assert_se(sd_bus_message_verify_type(m, 'a', "s") > 0);
292 r = sd_bus_message_read(m, "as", 2, &x, &y);
294 assert_se(streq(x, "foobar"));
295 assert_se(streq(y, "waldo"));
297 r = sd_bus_message_read_basic(m, 's', &s);
299 assert_se(streq(s, "hallo"));
301 r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz);
303 assert_se(sz == sizeof(integer_array));
304 assert_se(memcmp(integer_array, return_array, sz) == 0);
306 r = sd_bus_message_read_array(m, 'u', (const void**) &return_array, &sz);
310 r = sd_bus_message_read(m, "a(stdo)", 1, &x, &u64, &dbl, &y);
312 assert_se(streq(x, "foo"));
313 assert_se(u64 == 815ULL);
314 assert_se(fabs(dbl - 47.0) < 0.1);
315 assert_se(streq(y, "/"));
317 r = sd_bus_message_peek_type(m, NULL, NULL);
320 r = sd_bus_message_new_method_call(bus, ©, "foobar.waldo", "/", "foobar.waldo", "Piep");
323 r = sd_bus_message_rewind(m, true);
326 r = sd_bus_message_copy(copy, m, true);
329 r = bus_message_seal(copy, 4712, 0);
333 ms = open_memstream(&third, &third_size);
334 bus_message_dump(copy, ms, 0);
336 assert_se(!ferror(ms));
338 printf("<%.*s>\n", (int) first_size, first);
339 printf("<%.*s>\n", (int) third_size, third);
341 assert_se(first_size == third_size);
342 assert_se(memcmp(first, third, third_size) == 0);
344 r = sd_bus_message_rewind(m, true);
347 assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
349 r = sd_bus_message_skip(m, "ssasg");
352 assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
354 r = sd_bus_message_skip(m, "sass");
357 assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
359 r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y()");
362 assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
364 r = sd_bus_message_read(m, "b", &boolean);
368 r = sd_bus_message_enter_container(m, 0, NULL);
371 r = sd_bus_message_read(m, "(ss)", &x, &y);
374 r = sd_bus_message_read(m, "(ss)", &a, &b);
377 r = sd_bus_message_read(m, "(ss)", &c, &d);
380 r = sd_bus_message_read(m, "(ss)", &x, &y);
383 r = sd_bus_message_exit_container(m);
386 assert_se(streq(x, "aaa"));
387 assert_se(streq(y, "1"));
388 assert_se(streq(a, "bbb"));
389 assert_se(streq(b, "2"));
390 assert_se(streq(c, "ccc"));
391 assert_se(streq(d, "3"));
393 test_bus_label_escape();
394 test_bus_path_encode();
395 test_bus_path_encode_unique();