protocol: Add explicit nullable types
[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 int
41 update_func(struct wl_connection *connection, uint32_t mask, void *data)
42 {
43         uint32_t *m = data;
44
45         *m = mask;
46
47         return 0;
48 }
49
50 static struct wl_connection *
51 setup(int *s, uint32_t *mask)
52 {
53         struct wl_connection *connection;
54
55         assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, s) == 0);
56
57         connection = wl_connection_create(s[0], update_func, mask);
58         assert(connection);
59         assert(*mask == WL_CONNECTION_READABLE);
60
61         return connection;
62 }
63
64 TEST(connection_create)
65 {
66         struct wl_connection *connection;
67         int s[2];
68         uint32_t mask;
69
70         connection = setup(s, &mask);
71         wl_connection_destroy(connection);
72         close(s[1]);
73 }
74
75 TEST(connection_write)
76 {
77         struct wl_connection *connection;
78         int s[2];
79         uint32_t mask;
80         char buffer[64];
81
82         connection = setup(s, &mask);
83
84         assert(wl_connection_write(connection, message, sizeof message) == 0);
85         assert(mask == (WL_CONNECTION_WRITABLE | WL_CONNECTION_READABLE));
86         assert(wl_connection_data(connection, WL_CONNECTION_WRITABLE) == 0);
87         assert(mask == WL_CONNECTION_READABLE);
88         assert(read(s[1], buffer, sizeof buffer) == sizeof message);
89         assert(memcmp(message, buffer, sizeof message) == 0);
90
91         wl_connection_destroy(connection);
92         close(s[1]);
93 }
94
95 TEST(connection_data)
96 {
97         struct wl_connection *connection;
98         int s[2];
99         uint32_t mask;
100         char buffer[64];
101
102         connection = setup(s, &mask);
103
104         assert(write(s[1], message, sizeof message) == sizeof message);
105         assert(mask == WL_CONNECTION_READABLE);
106         assert(wl_connection_data(connection, WL_CONNECTION_READABLE) == 
107                sizeof message);
108         wl_connection_copy(connection, buffer, sizeof message);
109         assert(memcmp(message, buffer, sizeof message) == 0);
110         wl_connection_consume(connection, sizeof message);
111
112         wl_connection_destroy(connection);
113         close(s[1]);
114 }
115
116 TEST(connection_queue)
117 {
118         struct wl_connection *connection;
119         int s[2];
120         uint32_t mask;
121         char buffer[64];
122
123         connection = setup(s, &mask);
124
125         /* Test that wl_connection_queue() puts data in the output
126          * buffer without asking for WL_CONNECTION_WRITABLE.  Verify
127          * that the data did get in the buffer by writing another
128          * message and making sure that we receive the two messages on
129          * the other fd. */
130
131         assert(wl_connection_queue(connection, message, sizeof message) == 0);
132         assert(mask == WL_CONNECTION_READABLE);
133         assert(wl_connection_write(connection, message, sizeof message) == 0);
134         assert(mask == (WL_CONNECTION_WRITABLE | WL_CONNECTION_READABLE));
135         assert(wl_connection_data(connection, WL_CONNECTION_WRITABLE) == 0);
136         assert(mask == WL_CONNECTION_READABLE);
137         assert(read(s[1], buffer, sizeof buffer) == 2 * sizeof message);
138         assert(memcmp(message, buffer, sizeof message) == 0);
139         assert(memcmp(message, buffer + sizeof message, sizeof message) == 0);
140
141         wl_connection_destroy(connection);
142         close(s[1]);
143 }
144
145 struct marshal_data {
146         struct wl_connection *read_connection;
147         struct wl_connection *write_connection;
148         int s[2];
149         uint32_t read_mask;
150         uint32_t write_mask;
151         uint32_t buffer[10];
152         union {
153                 uint32_t u;
154                 int32_t i;
155                 const char *s;
156                 int h;
157         } value;
158 };
159
160 static void
161 setup_marshal_data(struct marshal_data *data)
162 {
163         assert(socketpair(AF_UNIX,
164                           SOCK_STREAM | SOCK_CLOEXEC, 0, data->s) == 0);
165
166         data->read_connection =
167                 wl_connection_create(data->s[0],
168                                      update_func, &data->read_mask);
169         assert(data->read_connection);
170         assert(data->read_mask == WL_CONNECTION_READABLE);
171
172         data->write_connection =
173                 wl_connection_create(data->s[1],
174                                      update_func, &data->write_mask);
175         assert(data->write_connection);
176         assert(data->write_mask == WL_CONNECTION_READABLE);
177 }
178
179 static void
180 release_marshal_data(struct marshal_data *data)
181 {
182         wl_connection_destroy(data->read_connection);
183         wl_connection_destroy(data->write_connection);
184 }
185
186 static void
187 marshal(struct marshal_data *data, const char *format, int size, ...)
188 {
189         struct wl_closure *closure;
190         static const uint32_t opcode = 4444;
191         static struct wl_object sender = { NULL, NULL, 1234 };
192         struct wl_message message = { "test", format, NULL };
193         va_list ap;
194
195         va_start(ap, size);
196         closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
197         va_end(ap);
198
199         assert(closure);
200         assert(wl_closure_send(closure, data->write_connection) == 0);
201         wl_closure_destroy(closure);
202         assert(data->write_mask ==
203                (WL_CONNECTION_WRITABLE | WL_CONNECTION_READABLE));
204         assert(wl_connection_data(data->write_connection,
205                                   WL_CONNECTION_WRITABLE) == 0);
206         assert(data->write_mask == WL_CONNECTION_READABLE);
207         assert(read(data->s[0], data->buffer, sizeof data->buffer) == size);
208
209         assert(data->buffer[0] == sender.id);
210         assert(data->buffer[1] == (opcode | (size << 16)));
211 }
212
213 TEST(connection_marshal)
214 {
215         struct marshal_data data;
216         struct wl_object object;
217         struct wl_array array;
218         static const char text[] = "curry";
219
220         setup_marshal_data(&data);
221
222         marshal(&data, "i", 12, 42);
223         assert(data.buffer[2] == 42);
224
225         marshal(&data, "u", 12, 55);
226         assert(data.buffer[2] == 55);
227
228         marshal(&data, "s", 20, "frappo");
229         assert(data.buffer[2] == 7);
230         assert(strcmp((char *) &data.buffer[3], "frappo") == 0);
231
232         object.id = 557799;
233         marshal(&data, "o", 12, &object);
234         assert(data.buffer[2] == object.id);
235
236         marshal(&data, "n", 12, &object);
237         assert(data.buffer[2] == object.id);
238
239         marshal(&data, "n", 12, NULL);
240         assert(data.buffer[2] == 0);
241
242         array.data = (void *) text;
243         array.size = sizeof text;
244         marshal(&data, "a", 20, &array);
245         assert(data.buffer[2] == array.size);
246         assert(memcmp(&data.buffer[3], text, array.size) == 0);
247
248         release_marshal_data(&data);
249 }
250
251 static void
252 expected_fail_marshal(int expected_error, const char *format, ...)
253 {
254         struct wl_closure *closure;
255         static const uint32_t opcode = 4444;
256         static const struct wl_interface test_interface = { 
257                 .name = "test_object"
258         };
259         static struct wl_object sender = { 0 };
260         struct wl_message message = { "test", format, NULL };
261
262         sender.interface = &test_interface;
263         sender.id = 1234;
264         va_list ap;
265
266         va_start(ap, format);
267         closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
268         va_end(ap);
269
270         assert(closure == NULL);
271         assert(errno == expected_error);
272 }
273
274 TEST(connection_marshal_nullables)
275 {
276         struct marshal_data data;
277         struct wl_object object;
278         struct wl_array array;
279         const char text[] = "curry";
280
281         setup_marshal_data(&data);
282
283         expected_fail_marshal(EINVAL, "o", NULL);
284         expected_fail_marshal(EINVAL, "s", NULL);
285         expected_fail_marshal(EINVAL, "a", NULL);
286
287         marshal(&data, "?o", 12, NULL);
288         assert(data.buffer[2] == 0);
289
290         marshal(&data, "?a", 12, NULL);
291         assert(data.buffer[2] == 0);
292
293         marshal(&data, "?s", 12, NULL);
294         assert(data.buffer[2] == 0);
295
296         object.id = 55293;
297         marshal(&data, "?o", 12, &object);
298         assert(data.buffer[2] == object.id);
299
300         array.data = (void *) text;
301         array.size = sizeof text;
302         marshal(&data, "?a", 20, &array);
303         assert(data.buffer[2] == array.size);
304         assert(memcmp(&data.buffer[3], text, array.size) == 0);
305
306         marshal(&data, "?s", 20, text);
307         assert(data.buffer[2] == sizeof text);
308         assert(strcmp((char *) &data.buffer[3], text) == 0);
309
310         release_marshal_data(&data);
311 }
312
313 static void
314 validate_demarshal_u(struct marshal_data *data,
315                      struct wl_object *object, uint32_t u)
316 {
317         assert(data->value.u == u);
318 }
319
320 static void
321 validate_demarshal_i(struct marshal_data *data,
322                      struct wl_object *object, int32_t i)
323 {
324         assert(data->value.i == i);
325 }
326
327 static void
328 validate_demarshal_s(struct marshal_data *data,
329                      struct wl_object *object, const char *s)
330 {
331         if (data->value.s != NULL)
332                 assert(strcmp(data->value.s, s) == 0);
333         else
334                 assert(s == NULL);
335 }
336
337 static void
338 validate_demarshal_h(struct marshal_data *data,
339                      struct wl_object *object, int fd)
340 {
341         struct stat buf1, buf2;
342
343         assert(fd != data->value.h);
344         fstat(fd, &buf1);
345         fstat(data->value.h, &buf2);
346         assert(buf1.st_dev == buf2.st_dev);
347         assert(buf1.st_ino == buf2.st_ino);
348         close(fd);
349         close(data->value.h);
350 }
351
352 static void
353 validate_demarshal_f(struct marshal_data *data,
354                      struct wl_object *object, wl_fixed_t f)
355 {
356         assert(data->value.i == f);
357 }
358
359 static void
360 demarshal(struct marshal_data *data, const char *format,
361           uint32_t *msg, void (*func)(void))
362 {
363         struct wl_message message = { "test", format, NULL };
364         struct wl_closure *closure;
365         struct wl_map objects;
366         struct wl_object object;
367         int size = msg[1];
368
369         assert(write(data->s[1], msg, size) == size);
370         assert(wl_connection_data(data->read_connection,
371                                   WL_CONNECTION_READABLE) == size);
372
373         wl_map_init(&objects);
374         object.id = msg[0];
375         closure = wl_connection_demarshal(data->read_connection,
376                                           size, &objects, &message);
377         assert(closure);
378         wl_closure_invoke(closure, &object, func, data);
379         wl_closure_destroy(closure);
380 }
381
382 TEST(connection_demarshal)
383 {
384         struct marshal_data data;
385         uint32_t msg[10];
386
387         setup_marshal_data(&data);
388
389         data.value.u = 8000;
390         msg[0] = 400200;        /* object id */
391         msg[1] = 12;            /* size = 12, opcode = 0 */
392         msg[2] = data.value.u;
393         demarshal(&data, "u", msg, (void *) validate_demarshal_u);
394
395         data.value.i = -557799;
396         msg[0] = 400200;
397         msg[1] = 12;
398         msg[2] = data.value.i;
399         demarshal(&data, "i", msg, (void *) validate_demarshal_i);
400
401         data.value.s = "superdude";
402         msg[0] = 400200;
403         msg[1] = 24;
404         msg[2] = 10;
405         memcpy(&msg[3], data.value.s, msg[2]);
406         demarshal(&data, "s", msg, (void *) validate_demarshal_s);
407
408         data.value.s = "superdude";
409         msg[0] = 400200;
410         msg[1] = 24;
411         msg[2] = 10;
412         memcpy(&msg[3], data.value.s, msg[2]);
413         demarshal(&data, "?s", msg, (void *) validate_demarshal_s);
414
415         data.value.i = wl_fixed_from_double(-90000.2390);
416         msg[0] = 400200;
417         msg[1] = 12;
418         msg[2] = data.value.i;
419         demarshal(&data, "f", msg, (void *) validate_demarshal_f);
420
421         data.value.s = NULL;
422         msg[0] = 400200;
423         msg[1] = 12;
424         msg[2] = 0;
425         demarshal(&data, "?s", msg, (void *) validate_demarshal_s);     
426
427         release_marshal_data(&data);
428 }
429
430 static void
431 marshal_demarshal(struct marshal_data *data, 
432                   void (*func)(void), int size, const char *format, ...)
433 {
434         struct wl_closure *closure;
435         static const int opcode = 4444;
436         static struct wl_object sender = { NULL, NULL, 1234 };
437         struct wl_message message = { "test", format, NULL };
438         struct wl_map objects;
439         struct wl_object object;
440         va_list ap;
441         uint32_t msg[1] = { 1234 };
442
443         va_start(ap, format);
444         closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
445         va_end(ap);
446
447         assert(closure);
448         assert(wl_closure_send(closure, data->write_connection) == 0);
449         wl_closure_destroy(closure);
450         assert(data->write_mask ==
451                (WL_CONNECTION_WRITABLE | WL_CONNECTION_READABLE));
452         assert(wl_connection_data(data->write_connection,
453                                   WL_CONNECTION_WRITABLE) == 0);
454         assert(data->write_mask == WL_CONNECTION_READABLE);
455
456         assert(wl_connection_data(data->read_connection,
457                                   WL_CONNECTION_READABLE) == size);
458
459         wl_map_init(&objects);
460         object.id = msg[0];
461         closure = wl_connection_demarshal(data->read_connection,
462                                           size, &objects, &message);
463         wl_closure_invoke(closure, &object, func, data);
464         wl_closure_destroy(closure);
465 }
466
467 TEST(connection_marshal_demarshal)
468 {
469         struct marshal_data data;
470         char f[] = "/tmp/weston-tests-XXXXXX";
471
472         setup_marshal_data(&data);
473
474         data.value.u = 889911;
475         marshal_demarshal(&data, (void *) validate_demarshal_u,
476                           12, "u", data.value.u);
477
478         data.value.i = -13;
479         marshal_demarshal(&data, (void *) validate_demarshal_i,
480                           12, "i", data.value.i);
481
482         data.value.s = "cookie robots";
483         marshal_demarshal(&data, (void *) validate_demarshal_s,
484                           28, "s", data.value.s);
485
486         data.value.s = "cookie robots";
487         marshal_demarshal(&data, (void *) validate_demarshal_s,
488                           28, "?s", data.value.s);
489
490         data.value.h = mkstemp(f);
491         assert(data.value.h >= 0);
492         marshal_demarshal(&data, (void *) validate_demarshal_h,
493                           8, "h", data.value.h);
494
495         data.value.i = wl_fixed_from_double(1234.5678);
496         marshal_demarshal(&data, (void *) validate_demarshal_f,
497                           12, "f", data.value.i);
498
499         data.value.i = wl_fixed_from_double(-90000.2390);
500         marshal_demarshal(&data, (void *) validate_demarshal_f,
501                           12, "f", data.value.i);
502
503         data.value.i = wl_fixed_from_double((1 << 23) - 1 + 0.0941);
504         marshal_demarshal(&data, (void *) validate_demarshal_f,
505                           12, "f", data.value.i);
506
507         release_marshal_data(&data);
508 }
509
510 TEST(connection_marshal_alot)
511 {
512         struct marshal_data data;
513         char f[64];
514         int i;
515
516         setup_marshal_data(&data);
517         
518         /* We iterate enough to make sure we wrap the circular buffers
519          * for both regular data an fds. */
520
521         for (i = 0; i < 2000; i++) {
522                 strcpy(f, "/tmp/weston-tests-XXXXXX");
523                 data.value.h = mkstemp(f);
524                 assert(data.value.h >= 0);
525                 marshal_demarshal(&data, (void *) validate_demarshal_h,
526                                   8, "h", data.value.h);
527         }
528
529         release_marshal_data(&data);
530 }
531
532 static void
533 marshal_helper(const char *format, void *handler, ...)
534 {
535         struct wl_closure *closure;
536         static struct wl_object sender = { NULL, NULL, 1234 }, object;
537         static const int opcode = 4444;
538         struct wl_message message = { "test", format, NULL };
539         va_list ap;
540         int done;
541
542         va_start(ap, handler);
543         closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
544         va_end(ap);
545
546         assert(closure);
547         done = 0;
548         wl_closure_invoke(closure, &object, handler, &done);
549         wl_closure_destroy(closure);
550         assert(done);
551 }
552
553 static void
554 suu_handler(void *data, struct wl_object *object,
555             const char *s, uint32_t u1, uint32_t u2)
556 {
557         int *done = data;
558
559         assert(strcmp(s, "foo") == 0);
560         assert(u1 = 500);
561         assert(u2 = 404040);
562         *done = 1;
563 }
564
565 TEST(invoke_closure)
566 {
567         marshal_helper("suu", suu_handler, "foo", 500, 404040);
568 }