tests: Add queue test case
[profile/ivi/wayland.git] / tests / queue-test.c
1 /*
2  * Copyright © 2012 Jonas Ådahl
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 <stdlib.h>
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <sys/types.h>
27 #include <sys/wait.h>
28 #include <assert.h>
29
30 #include "wayland-client.h"
31 #include "wayland-server.h"
32 #include "test-runner.h"
33
34 #define SOCKET_NAME "wayland-queue-test"
35
36 #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
37
38 #define client_assert(expr)                                     \
39         do {                                                    \
40                 if (!(expr)) {                                  \
41                         fprintf(stderr, "%s:%d: "               \
42                                 "Assertion `%s' failed.\n",     \
43                                 __FILE__, __LINE__, #expr);     \
44                         exit(EXIT_FAILURE);                     \
45                 }                                               \
46         } while (0)
47
48 struct display {
49         struct wl_display *display;
50         int child_exit_status;
51 };
52
53 static int
54 sigchld_handler(int signal_number, void *data)
55 {
56         struct display *display = data;
57         int status;
58
59         waitpid(-1, &status, 0);
60         display->child_exit_status = WEXITSTATUS(status);
61
62         wl_display_terminate(display->display);
63
64         return 0;
65 }
66
67 static void
68 registry_handle_global(void *data, struct wl_registry *registry,
69                        uint32_t id, const char *interface, uint32_t version)
70 {
71         int *pcounter = data;
72         (*pcounter)++;
73         client_assert(*pcounter == 1);
74         wl_registry_destroy(registry);
75 }
76
77 static const struct wl_registry_listener registry_listener = {
78         registry_handle_global,
79         NULL
80 };
81
82 static void
83 client_alarm_handler(int sig)
84 {
85         exit(EXIT_FAILURE);
86 }
87
88 static void
89 client_continue_handler(int sig)
90 {
91 }
92
93 static int
94 client_main(void)
95 {
96         struct wl_display *display;
97         struct wl_registry *registry;
98         int counter = 0;
99
100         signal(SIGALRM, client_alarm_handler);
101         signal(SIGCONT, client_continue_handler);
102         alarm(20);
103         pause();
104
105         display = wl_display_connect(SOCKET_NAME);
106         client_assert(display);
107
108         registry = wl_display_get_registry(display);
109         wl_registry_add_listener(registry, &registry_listener, &counter);
110         wl_display_roundtrip(display);
111
112         client_assert(counter == 1);
113
114         wl_display_disconnect(display);
115
116         return EXIT_SUCCESS;
117 }
118
119 static void
120 dummy_bind(struct wl_client *client,
121            void *data, uint32_t version, uint32_t id)
122 {
123 }
124
125 TEST(queue_destroy_proxy)
126 {
127         struct display display;
128         struct wl_event_loop *loop;
129         struct wl_event_source *signal_source;
130         const struct wl_interface *dummy_interfaces[] = {
131                 &wl_seat_interface,
132                 &wl_pointer_interface,
133                 &wl_keyboard_interface,
134                 &wl_surface_interface
135         };
136         unsigned int i;
137         pid_t pid;
138         int ret;
139
140         pid = fork();
141         if (pid == -1) {
142                 perror("fork");
143                 exit(EXIT_FAILURE);
144         } else if (pid == 0) {
145                 exit(client_main());
146         }
147
148         display.child_exit_status = EXIT_FAILURE;
149         display.display = wl_display_create();
150         assert(display.display);
151
152         for (i = 0; i < ARRAY_LENGTH(dummy_interfaces); i++)
153                 wl_display_add_global(display.display, dummy_interfaces[i],
154                                       NULL, dummy_bind);
155
156         ret = wl_display_add_socket(display.display, SOCKET_NAME);
157         assert(ret == 0);
158
159         loop = wl_display_get_event_loop(display.display);
160         signal_source = wl_event_loop_add_signal(loop, SIGCHLD, sigchld_handler,
161                                                  &display);
162
163         kill(pid, SIGCONT);
164         wl_display_run(display.display);
165
166         wl_event_source_remove(signal_source);
167         wl_display_destroy(display.display);
168
169         assert(display.child_exit_status == EXIT_SUCCESS);
170 }
171