chiark / gitweb /
bus: don't rely on static IDs in tests
[elogind.git] / src / libsystemd / sd-bus / test-bus-zero-copy.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 <fcntl.h>
23 #include <sys/mman.h>
24
25 #include "util.h"
26 #include "log.h"
27 #include "memfd-util.h"
28
29 #include "sd-bus.h"
30 #include "bus-message.h"
31 #include "bus-error.h"
32 #include "bus-kernel.h"
33 #include "bus-dump.h"
34
35 #define FIRST_ARRAY 17
36 #define SECOND_ARRAY 33
37
38 #define STRING_SIZE 123
39
40 int main(int argc, char *argv[]) {
41         _cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL;
42         const char *unique;
43         uint8_t *p;
44         sd_bus *a, *b;
45         int r, bus_ref;
46         sd_bus_message *m;
47         int f;
48         uint64_t sz;
49         uint32_t u32;
50         size_t i, l;
51         char *s;
52         _cleanup_close_ int sfd = -1;
53
54         log_set_max_level(LOG_DEBUG);
55
56         assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0);
57
58         bus_ref = bus_kernel_create_bus(name, false, &bus_name);
59         if (bus_ref == -ENOENT)
60                 return EXIT_TEST_SKIP;
61
62         assert_se(bus_ref >= 0);
63
64         address = strappend("kernel:path=", bus_name);
65         assert_se(address);
66
67         r = sd_bus_new(&a);
68         assert_se(r >= 0);
69
70         r = sd_bus_new(&b);
71         assert_se(r >= 0);
72
73         r = sd_bus_set_address(a, address);
74         assert_se(r >= 0);
75
76         r = sd_bus_set_address(b, address);
77         assert_se(r >= 0);
78
79         r = sd_bus_start(a);
80         assert_se(r >= 0);
81
82         r = sd_bus_start(b);
83         assert_se(r >= 0);
84
85         r = sd_bus_get_unique_name(a, &unique);
86         assert_se(r >= 0);
87
88         r = sd_bus_message_new_method_call(b, &m, unique, "/a/path", "an.inter.face", "AMethod");
89         assert_se(r >= 0);
90
91         r = sd_bus_message_open_container(m, 'r', "aysay");
92         assert_se(r >= 0);
93
94         r = sd_bus_message_append_array_space(m, 'y', FIRST_ARRAY, (void**) &p);
95         assert_se(r >= 0);
96
97         p[0] = '<';
98         memset(p+1, 'L', FIRST_ARRAY-2);
99         p[FIRST_ARRAY-1] = '>';
100
101         f = memfd_new_and_map(NULL, STRING_SIZE, (void**) &s);
102         assert_se(f >= 0);
103
104         s[0] = '<';
105         for (i = 1; i < STRING_SIZE-2; i++)
106                 s[i] = '0' + (i % 10);
107         s[STRING_SIZE-2] = '>';
108         s[STRING_SIZE-1] = 0;
109         munmap(s, STRING_SIZE);
110
111         r = memfd_get_size(f, &sz);
112         assert_se(r >= 0);
113         assert_se(sz == STRING_SIZE);
114
115         r = sd_bus_message_append_string_memfd(m, f, 0, (uint64_t) -1);
116         assert_se(r >= 0);
117
118         close(f);
119
120         f = memfd_new_and_map(NULL, SECOND_ARRAY, (void**) &p);
121         assert_se(f >= 0);
122
123         p[0] = '<';
124         memset(p+1, 'P', SECOND_ARRAY-2);
125         p[SECOND_ARRAY-1] = '>';
126         munmap(p, SECOND_ARRAY);
127
128         r = memfd_get_size(f, &sz);
129         assert_se(r >= 0);
130         assert_se(sz == SECOND_ARRAY);
131
132         r = sd_bus_message_append_array_memfd(m, 'y', f, 0, (uint64_t) -1);
133         assert_se(r >= 0);
134
135         close(f);
136
137         r = sd_bus_message_close_container(m);
138         assert_se(r >= 0);
139
140         r = sd_bus_message_append(m, "u", 4711);
141         assert_se(r >= 0);
142
143         assert_se((sfd = memfd_new_and_map(NULL, 6, (void**) &p)) >= 0);
144         memcpy(p, "abcd\0", 6);
145         munmap(p, 6);
146         assert_se(sd_bus_message_append_string_memfd(m, sfd, 1, 4) >= 0);
147
148         r = bus_message_seal(m, 55, 99*USEC_PER_SEC);
149         assert_se(r >= 0);
150
151         bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
152
153         r = sd_bus_send(b, m, NULL);
154         assert_se(r >= 0);
155
156         sd_bus_message_unref(m);
157
158         r = sd_bus_process(a, &m);
159         assert_se(r > 0);
160
161         bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
162         sd_bus_message_rewind(m, true);
163
164         r = sd_bus_message_enter_container(m, 'r', "aysay");
165         assert_se(r > 0);
166
167         r = sd_bus_message_read_array(m, 'y', (const void**) &p, &l);
168         assert_se(r > 0);
169         assert_se(l == FIRST_ARRAY);
170
171         assert_se(p[0] == '<');
172         for (i = 1; i < l-1; i++)
173                 assert_se(p[i] == 'L');
174         assert_se(p[l-1] == '>');
175
176         r = sd_bus_message_read(m, "s", &s);
177         assert_se(r > 0);
178
179         assert_se(s[0] == '<');
180         for (i = 1; i < STRING_SIZE-2; i++)
181                 assert_se(s[i] == (char) ('0' + (i % 10)));
182         assert_se(s[STRING_SIZE-2] == '>');
183         assert_se(s[STRING_SIZE-1] == 0);
184
185         r = sd_bus_message_read_array(m, 'y', (const void**) &p, &l);
186         assert_se(r > 0);
187         assert_se(l == SECOND_ARRAY);
188
189         assert_se(p[0] == '<');
190         for (i = 1; i < l-1; i++)
191                 assert_se(p[i] == 'P');
192         assert_se(p[l-1] == '>');
193
194         r = sd_bus_message_exit_container(m);
195         assert_se(r > 0);
196
197         r = sd_bus_message_read(m, "u", &u32);
198         assert_se(r > 0);
199         assert_se(u32 == 4711);
200
201         r = sd_bus_message_read(m, "s", &s);
202         assert_se(r > 0);
203         assert_se(streq_ptr(s, "bcd"));
204
205         sd_bus_message_unref(m);
206
207         sd_bus_unref(a);
208         sd_bus_unref(b);
209
210         return 0;
211 }