2 * Copyright © 2012 Intel Corporation
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
29 #include <sys/socket.h>
32 #include <sys/types.h>
35 #include "wayland-private.h"
36 #include "test-runner.h"
38 static const char message[] = "Hello, world";
40 static struct wl_connection *
43 struct wl_connection *connection;
45 assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, s) == 0);
47 connection = wl_connection_create(s[0]);
53 TEST(connection_create)
55 struct wl_connection *connection;
58 connection = setup(s);
59 wl_connection_destroy(connection);
63 TEST(connection_write)
65 struct wl_connection *connection;
69 connection = setup(s);
71 assert(wl_connection_write(connection, message, sizeof message) == 0);
72 assert(wl_connection_flush(connection) == sizeof message);
73 assert(read(s[1], buffer, sizeof buffer) == sizeof message);
74 assert(memcmp(message, buffer, sizeof message) == 0);
76 wl_connection_destroy(connection);
82 struct wl_connection *connection;
86 connection = setup(s);
88 assert(write(s[1], message, sizeof message) == sizeof message);
89 assert(wl_connection_read(connection) == sizeof message);
90 wl_connection_copy(connection, buffer, sizeof message);
91 assert(memcmp(message, buffer, sizeof message) == 0);
92 wl_connection_consume(connection, sizeof message);
94 wl_connection_destroy(connection);
98 TEST(connection_queue)
100 struct wl_connection *connection;
104 connection = setup(s);
106 /* Test that wl_connection_queue() puts data in the output
107 * buffer without flush it. Verify that the data did get in
108 * the buffer by writing another message and making sure that
109 * we receive the two messages on the other fd. */
111 assert(wl_connection_queue(connection, message, sizeof message) == 0);
112 assert(wl_connection_flush(connection) == 0);
113 assert(wl_connection_write(connection, message, sizeof message) == 0);
114 assert(wl_connection_flush(connection) == 2 * sizeof message);
115 assert(read(s[1], buffer, sizeof buffer) == 2 * sizeof message);
116 assert(memcmp(message, buffer, sizeof message) == 0);
117 assert(memcmp(message, buffer + sizeof message, sizeof message) == 0);
119 wl_connection_destroy(connection);
123 struct marshal_data {
124 struct wl_connection *read_connection;
125 struct wl_connection *write_connection;
137 setup_marshal_data(struct marshal_data *data)
139 assert(socketpair(AF_UNIX,
140 SOCK_STREAM | SOCK_CLOEXEC, 0, data->s) == 0);
141 data->read_connection = wl_connection_create(data->s[0]);
142 assert(data->read_connection);
143 data->write_connection = wl_connection_create(data->s[1]);
144 assert(data->write_connection);
148 release_marshal_data(struct marshal_data *data)
150 wl_connection_destroy(data->read_connection);
151 wl_connection_destroy(data->write_connection);
155 marshal(struct marshal_data *data, const char *format, int size, ...)
157 struct wl_closure *closure;
158 static const uint32_t opcode = 4444;
159 static struct wl_object sender = { NULL, NULL, 1234 };
160 struct wl_message message = { "test", format, NULL };
164 closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
168 assert(wl_closure_send(closure, data->write_connection) == 0);
169 wl_closure_destroy(closure);
170 assert(wl_connection_flush(data->write_connection) == size);
171 assert(read(data->s[0], data->buffer, sizeof data->buffer) == size);
173 assert(data->buffer[0] == sender.id);
174 assert(data->buffer[1] == (opcode | (size << 16)));
177 TEST(connection_marshal)
179 struct marshal_data data;
180 struct wl_object object;
181 struct wl_array array;
182 static const char text[] = "curry";
184 setup_marshal_data(&data);
186 marshal(&data, "i", 12, 42);
187 assert(data.buffer[2] == 42);
189 marshal(&data, "u", 12, 55);
190 assert(data.buffer[2] == 55);
192 marshal(&data, "s", 20, "frappo");
193 assert(data.buffer[2] == 7);
194 assert(strcmp((char *) &data.buffer[3], "frappo") == 0);
197 marshal(&data, "o", 12, &object);
198 assert(data.buffer[2] == object.id);
200 marshal(&data, "n", 12, &object);
201 assert(data.buffer[2] == object.id);
203 marshal(&data, "?n", 12, NULL);
204 assert(data.buffer[2] == 0);
206 array.data = (void *) text;
207 array.size = sizeof text;
208 marshal(&data, "a", 20, &array);
209 assert(data.buffer[2] == array.size);
210 assert(memcmp(&data.buffer[3], text, array.size) == 0);
212 release_marshal_data(&data);
216 expected_fail_marshal(int expected_error, const char *format, ...)
218 struct wl_closure *closure;
219 static const uint32_t opcode = 4444;
220 static const struct wl_interface test_interface = {
221 .name = "test_object"
223 static struct wl_object sender = { 0 };
224 struct wl_message message = { "test", format, NULL };
226 sender.interface = &test_interface;
230 va_start(ap, format);
231 closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
234 assert(closure == NULL);
235 assert(errno == expected_error);
238 TEST(connection_marshal_nullables)
240 struct marshal_data data;
241 struct wl_object object;
242 struct wl_array array;
243 const char text[] = "curry";
245 setup_marshal_data(&data);
247 expected_fail_marshal(EINVAL, "o", NULL);
248 expected_fail_marshal(EINVAL, "s", NULL);
249 expected_fail_marshal(EINVAL, "a", NULL);
251 marshal(&data, "?o", 12, NULL);
252 assert(data.buffer[2] == 0);
254 marshal(&data, "?a", 12, NULL);
255 assert(data.buffer[2] == 0);
257 marshal(&data, "?s", 12, NULL);
258 assert(data.buffer[2] == 0);
261 marshal(&data, "?o", 12, &object);
262 assert(data.buffer[2] == object.id);
264 array.data = (void *) text;
265 array.size = sizeof text;
266 marshal(&data, "?a", 20, &array);
267 assert(data.buffer[2] == array.size);
268 assert(memcmp(&data.buffer[3], text, array.size) == 0);
270 marshal(&data, "?s", 20, text);
271 assert(data.buffer[2] == sizeof text);
272 assert(strcmp((char *) &data.buffer[3], text) == 0);
274 release_marshal_data(&data);
278 validate_demarshal_u(struct marshal_data *data,
279 struct wl_object *object, uint32_t u)
281 assert(data->value.u == u);
285 validate_demarshal_i(struct marshal_data *data,
286 struct wl_object *object, int32_t i)
288 assert(data->value.i == i);
292 validate_demarshal_s(struct marshal_data *data,
293 struct wl_object *object, const char *s)
295 if (data->value.s != NULL)
296 assert(strcmp(data->value.s, s) == 0);
302 validate_demarshal_h(struct marshal_data *data,
303 struct wl_object *object, int fd)
305 struct stat buf1, buf2;
307 assert(fd != data->value.h);
309 fstat(data->value.h, &buf2);
310 assert(buf1.st_dev == buf2.st_dev);
311 assert(buf1.st_ino == buf2.st_ino);
313 close(data->value.h);
317 validate_demarshal_f(struct marshal_data *data,
318 struct wl_object *object, wl_fixed_t f)
320 assert(data->value.i == f);
324 demarshal(struct marshal_data *data, const char *format,
325 uint32_t *msg, void (*func)(void))
327 struct wl_message message = { "test", format, NULL };
328 struct wl_closure *closure;
329 struct wl_map objects;
330 struct wl_object object;
333 assert(write(data->s[1], msg, size) == size);
334 assert(wl_connection_read(data->read_connection) == size);
336 wl_map_init(&objects);
338 closure = wl_connection_demarshal(data->read_connection,
339 size, &objects, &message);
341 wl_closure_invoke(closure, &object, func, data);
342 wl_closure_destroy(closure);
345 TEST(connection_demarshal)
347 struct marshal_data data;
350 setup_marshal_data(&data);
353 msg[0] = 400200; /* object id */
354 msg[1] = 12; /* size = 12, opcode = 0 */
355 msg[2] = data.value.u;
356 demarshal(&data, "u", msg, (void *) validate_demarshal_u);
358 data.value.i = -557799;
361 msg[2] = data.value.i;
362 demarshal(&data, "i", msg, (void *) validate_demarshal_i);
364 data.value.s = "superdude";
368 memcpy(&msg[3], data.value.s, msg[2]);
369 demarshal(&data, "s", msg, (void *) validate_demarshal_s);
371 data.value.s = "superdude";
375 memcpy(&msg[3], data.value.s, msg[2]);
376 demarshal(&data, "?s", msg, (void *) validate_demarshal_s);
378 data.value.i = wl_fixed_from_double(-90000.2390);
381 msg[2] = data.value.i;
382 demarshal(&data, "f", msg, (void *) validate_demarshal_f);
388 demarshal(&data, "?s", msg, (void *) validate_demarshal_s);
390 release_marshal_data(&data);
394 marshal_demarshal(struct marshal_data *data,
395 void (*func)(void), int size, const char *format, ...)
397 struct wl_closure *closure;
398 static const int opcode = 4444;
399 static struct wl_object sender = { NULL, NULL, 1234 };
400 struct wl_message message = { "test", format, NULL };
401 struct wl_map objects;
402 struct wl_object object;
404 uint32_t msg[1] = { 1234 };
406 va_start(ap, format);
407 closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
411 assert(wl_closure_send(closure, data->write_connection) == 0);
412 wl_closure_destroy(closure);
413 assert(wl_connection_flush(data->write_connection) == size);
415 assert(wl_connection_read(data->read_connection) == size);
417 wl_map_init(&objects);
419 closure = wl_connection_demarshal(data->read_connection,
420 size, &objects, &message);
421 wl_closure_invoke(closure, &object, func, data);
422 wl_closure_destroy(closure);
425 TEST(connection_marshal_demarshal)
427 struct marshal_data data;
428 char f[] = "/tmp/weston-tests-XXXXXX";
430 setup_marshal_data(&data);
432 data.value.u = 889911;
433 marshal_demarshal(&data, (void *) validate_demarshal_u,
434 12, "u", data.value.u);
437 marshal_demarshal(&data, (void *) validate_demarshal_i,
438 12, "i", data.value.i);
440 data.value.s = "cookie robots";
441 marshal_demarshal(&data, (void *) validate_demarshal_s,
442 28, "s", data.value.s);
444 data.value.s = "cookie robots";
445 marshal_demarshal(&data, (void *) validate_demarshal_s,
446 28, "?s", data.value.s);
448 data.value.h = mkstemp(f);
449 assert(data.value.h >= 0);
450 marshal_demarshal(&data, (void *) validate_demarshal_h,
451 8, "h", data.value.h);
453 data.value.i = wl_fixed_from_double(1234.5678);
454 marshal_demarshal(&data, (void *) validate_demarshal_f,
455 12, "f", data.value.i);
457 data.value.i = wl_fixed_from_double(-90000.2390);
458 marshal_demarshal(&data, (void *) validate_demarshal_f,
459 12, "f", data.value.i);
461 data.value.i = wl_fixed_from_double((1 << 23) - 1 + 0.0941);
462 marshal_demarshal(&data, (void *) validate_demarshal_f,
463 12, "f", data.value.i);
465 release_marshal_data(&data);
468 TEST(connection_marshal_alot)
470 struct marshal_data data;
474 setup_marshal_data(&data);
476 /* We iterate enough to make sure we wrap the circular buffers
477 * for both regular data an fds. */
479 for (i = 0; i < 2000; i++) {
480 strcpy(f, "/tmp/weston-tests-XXXXXX");
481 data.value.h = mkstemp(f);
482 assert(data.value.h >= 0);
483 marshal_demarshal(&data, (void *) validate_demarshal_h,
484 8, "h", data.value.h);
487 release_marshal_data(&data);
491 marshal_helper(const char *format, void *handler, ...)
493 struct wl_closure *closure;
494 static struct wl_object sender = { NULL, NULL, 1234 }, object;
495 static const int opcode = 4444;
496 struct wl_message message = { "test", format, NULL };
500 va_start(ap, handler);
501 closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
506 wl_closure_invoke(closure, &object, handler, &done);
507 wl_closure_destroy(closure);
512 suu_handler(void *data, struct wl_object *object,
513 const char *s, uint32_t u1, uint32_t u2)
517 assert(strcmp(s, "foo") == 0);
525 marshal_helper("suu", suu_handler, "foo", 500, 404040);