]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/test-bus-marshal.c
TODO: update
[thirdparty/systemd.git] / src / libsystemd / 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 }