configure.ac: Bump version to 1.0.1
[profile/ivi/wayland.git] / tests / connection-test.c
1 /*
2  * Copyright © 2012 Intel Corporation
3  *
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.
13  *
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
20  * OF THIS SOFTWARE.
21  */
22
23 #include <math.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <stdarg.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <sys/socket.h>
30 #include <unistd.h>
31 #include <errno.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34
35 #include "wayland-private.h"
36 #include "test-runner.h"
37
38 static const char message[] = "Hello, world";
39
40 static struct wl_connection *
41 setup(int *s)
42 {
43         struct wl_connection *connection;
44
45         assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, s) == 0);
46
47         connection = wl_connection_create(s[0]);
48         assert(connection);
49
50         return connection;
51 }
52
53 TEST(connection_create)
54 {
55         struct wl_connection *connection;
56         int s[2];
57
58         connection = setup(s);
59         wl_connection_destroy(connection);
60         close(s[1]);
61 }
62
63 TEST(connection_write)
64 {
65         struct wl_connection *connection;
66         int s[2];
67         char buffer[64];
68
69         connection = setup(s);
70
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);
75
76         wl_connection_destroy(connection);
77         close(s[1]);
78 }
79
80 TEST(connection_data)
81 {
82         struct wl_connection *connection;
83         int s[2];
84         char buffer[64];
85
86         connection = setup(s);
87
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);
93
94         wl_connection_destroy(connection);
95         close(s[1]);
96 }
97
98 TEST(connection_queue)
99 {
100         struct wl_connection *connection;
101         int s[2];
102         char buffer[64];
103
104         connection = setup(s);
105
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. */
110
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);
118
119         wl_connection_destroy(connection);
120         close(s[1]);
121 }
122
123 struct marshal_data {
124         struct wl_connection *read_connection;
125         struct wl_connection *write_connection;
126         int s[2];
127         uint32_t buffer[10];
128         union {
129                 uint32_t u;
130                 int32_t i;
131                 const char *s;
132                 int h;
133         } value;
134 };
135
136 static void
137 setup_marshal_data(struct marshal_data *data)
138 {
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);
145 }
146
147 static void
148 release_marshal_data(struct marshal_data *data)
149 {
150         wl_connection_destroy(data->read_connection);
151         wl_connection_destroy(data->write_connection);
152 }
153
154 static void
155 marshal(struct marshal_data *data, const char *format, int size, ...)
156 {
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 };
161         va_list ap;
162
163         va_start(ap, size);
164         closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
165         va_end(ap);
166
167         assert(closure);
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);
172
173         assert(data->buffer[0] == sender.id);
174         assert(data->buffer[1] == (opcode | (size << 16)));
175 }
176
177 TEST(connection_marshal)
178 {
179         struct marshal_data data;
180         struct wl_object object;
181         struct wl_array array;
182         static const char text[] = "curry";
183
184         setup_marshal_data(&data);
185
186         marshal(&data, "i", 12, 42);
187         assert(data.buffer[2] == 42);
188
189         marshal(&data, "u", 12, 55);
190         assert(data.buffer[2] == 55);
191
192         marshal(&data, "s", 20, "frappo");
193         assert(data.buffer[2] == 7);
194         assert(strcmp((char *) &data.buffer[3], "frappo") == 0);
195
196         object.id = 557799;
197         marshal(&data, "o", 12, &object);
198         assert(data.buffer[2] == object.id);
199
200         marshal(&data, "n", 12, &object);
201         assert(data.buffer[2] == object.id);
202
203         marshal(&data, "?n", 12, NULL);
204         assert(data.buffer[2] == 0);
205
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);
211
212         release_marshal_data(&data);
213 }
214
215 static void
216 expected_fail_marshal(int expected_error, const char *format, ...)
217 {
218         struct wl_closure *closure;
219         static const uint32_t opcode = 4444;
220         static const struct wl_interface test_interface = { 
221                 .name = "test_object"
222         };
223         static struct wl_object sender = { 0 };
224         struct wl_message message = { "test", format, NULL };
225
226         sender.interface = &test_interface;
227         sender.id = 1234;
228         va_list ap;
229
230         va_start(ap, format);
231         closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
232         va_end(ap);
233
234         assert(closure == NULL);
235         assert(errno == expected_error);
236 }
237
238 TEST(connection_marshal_nullables)
239 {
240         struct marshal_data data;
241         struct wl_object object;
242         struct wl_array array;
243         const char text[] = "curry";
244
245         setup_marshal_data(&data);
246
247         expected_fail_marshal(EINVAL, "o", NULL);
248         expected_fail_marshal(EINVAL, "s", NULL);
249         expected_fail_marshal(EINVAL, "a", NULL);
250
251         marshal(&data, "?o", 12, NULL);
252         assert(data.buffer[2] == 0);
253
254         marshal(&data, "?a", 12, NULL);
255         assert(data.buffer[2] == 0);
256
257         marshal(&data, "?s", 12, NULL);
258         assert(data.buffer[2] == 0);
259
260         object.id = 55293;
261         marshal(&data, "?o", 12, &object);
262         assert(data.buffer[2] == object.id);
263
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);
269
270         marshal(&data, "?s", 20, text);
271         assert(data.buffer[2] == sizeof text);
272         assert(strcmp((char *) &data.buffer[3], text) == 0);
273
274         release_marshal_data(&data);
275 }
276
277 static void
278 validate_demarshal_u(struct marshal_data *data,
279                      struct wl_object *object, uint32_t u)
280 {
281         assert(data->value.u == u);
282 }
283
284 static void
285 validate_demarshal_i(struct marshal_data *data,
286                      struct wl_object *object, int32_t i)
287 {
288         assert(data->value.i == i);
289 }
290
291 static void
292 validate_demarshal_s(struct marshal_data *data,
293                      struct wl_object *object, const char *s)
294 {
295         if (data->value.s != NULL)
296                 assert(strcmp(data->value.s, s) == 0);
297         else
298                 assert(s == NULL);
299 }
300
301 static void
302 validate_demarshal_h(struct marshal_data *data,
303                      struct wl_object *object, int fd)
304 {
305         struct stat buf1, buf2;
306
307         assert(fd != data->value.h);
308         fstat(fd, &buf1);
309         fstat(data->value.h, &buf2);
310         assert(buf1.st_dev == buf2.st_dev);
311         assert(buf1.st_ino == buf2.st_ino);
312         close(fd);
313         close(data->value.h);
314 }
315
316 static void
317 validate_demarshal_f(struct marshal_data *data,
318                      struct wl_object *object, wl_fixed_t f)
319 {
320         assert(data->value.i == f);
321 }
322
323 static void
324 demarshal(struct marshal_data *data, const char *format,
325           uint32_t *msg, void (*func)(void))
326 {
327         struct wl_message message = { "test", format, NULL };
328         struct wl_closure *closure;
329         struct wl_map objects;
330         struct wl_object object;
331         int size = msg[1];
332
333         assert(write(data->s[1], msg, size) == size);
334         assert(wl_connection_read(data->read_connection) == size);
335
336         wl_map_init(&objects);
337         object.id = msg[0];
338         closure = wl_connection_demarshal(data->read_connection,
339                                           size, &objects, &message);
340         assert(closure);
341         wl_closure_invoke(closure, &object, func, data);
342         wl_closure_destroy(closure);
343 }
344
345 TEST(connection_demarshal)
346 {
347         struct marshal_data data;
348         uint32_t msg[10];
349
350         setup_marshal_data(&data);
351
352         data.value.u = 8000;
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);
357
358         data.value.i = -557799;
359         msg[0] = 400200;
360         msg[1] = 12;
361         msg[2] = data.value.i;
362         demarshal(&data, "i", msg, (void *) validate_demarshal_i);
363
364         data.value.s = "superdude";
365         msg[0] = 400200;
366         msg[1] = 24;
367         msg[2] = 10;
368         memcpy(&msg[3], data.value.s, msg[2]);
369         demarshal(&data, "s", msg, (void *) validate_demarshal_s);
370
371         data.value.s = "superdude";
372         msg[0] = 400200;
373         msg[1] = 24;
374         msg[2] = 10;
375         memcpy(&msg[3], data.value.s, msg[2]);
376         demarshal(&data, "?s", msg, (void *) validate_demarshal_s);
377
378         data.value.i = wl_fixed_from_double(-90000.2390);
379         msg[0] = 400200;
380         msg[1] = 12;
381         msg[2] = data.value.i;
382         demarshal(&data, "f", msg, (void *) validate_demarshal_f);
383
384         data.value.s = NULL;
385         msg[0] = 400200;
386         msg[1] = 12;
387         msg[2] = 0;
388         demarshal(&data, "?s", msg, (void *) validate_demarshal_s);     
389
390         release_marshal_data(&data);
391 }
392
393 static void
394 marshal_demarshal(struct marshal_data *data, 
395                   void (*func)(void), int size, const char *format, ...)
396 {
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;
403         va_list ap;
404         uint32_t msg[1] = { 1234 };
405
406         va_start(ap, format);
407         closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
408         va_end(ap);
409
410         assert(closure);
411         assert(wl_closure_send(closure, data->write_connection) == 0);
412         wl_closure_destroy(closure);
413         assert(wl_connection_flush(data->write_connection) == size);
414
415         assert(wl_connection_read(data->read_connection) == size);
416
417         wl_map_init(&objects);
418         object.id = msg[0];
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);
423 }
424
425 TEST(connection_marshal_demarshal)
426 {
427         struct marshal_data data;
428         char f[] = "/tmp/weston-tests-XXXXXX";
429
430         setup_marshal_data(&data);
431
432         data.value.u = 889911;
433         marshal_demarshal(&data, (void *) validate_demarshal_u,
434                           12, "u", data.value.u);
435
436         data.value.i = -13;
437         marshal_demarshal(&data, (void *) validate_demarshal_i,
438                           12, "i", data.value.i);
439
440         data.value.s = "cookie robots";
441         marshal_demarshal(&data, (void *) validate_demarshal_s,
442                           28, "s", data.value.s);
443
444         data.value.s = "cookie robots";
445         marshal_demarshal(&data, (void *) validate_demarshal_s,
446                           28, "?s", data.value.s);
447
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);
452
453         data.value.i = wl_fixed_from_double(1234.5678);
454         marshal_demarshal(&data, (void *) validate_demarshal_f,
455                           12, "f", data.value.i);
456
457         data.value.i = wl_fixed_from_double(-90000.2390);
458         marshal_demarshal(&data, (void *) validate_demarshal_f,
459                           12, "f", data.value.i);
460
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);
464
465         release_marshal_data(&data);
466 }
467
468 TEST(connection_marshal_alot)
469 {
470         struct marshal_data data;
471         char f[64];
472         int i;
473
474         setup_marshal_data(&data);
475         
476         /* We iterate enough to make sure we wrap the circular buffers
477          * for both regular data an fds. */
478
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);
485         }
486
487         release_marshal_data(&data);
488 }
489
490 static void
491 marshal_helper(const char *format, void *handler, ...)
492 {
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 };
497         va_list ap;
498         int done;
499
500         va_start(ap, handler);
501         closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
502         va_end(ap);
503
504         assert(closure);
505         done = 0;
506         wl_closure_invoke(closure, &object, handler, &done);
507         wl_closure_destroy(closure);
508         assert(done);
509 }
510
511 static void
512 suu_handler(void *data, struct wl_object *object,
513             const char *s, uint32_t u1, uint32_t u2)
514 {
515         int *done = data;
516
517         assert(strcmp(s, "foo") == 0);
518         assert(u1 = 500);
519         assert(u2 = 404040);
520         *done = 1;
521 }
522
523 TEST(invoke_closure)
524 {
525         marshal_helper("suu", suu_handler, "foo", 500, 404040);
526 }