1 /*
2 * Copyright © 2012 Collabora, Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26 #include <stdlib.h>
27 #include <assert.h>
28 #include <sys/types.h>
29 #include <signal.h>
30 #include <unistd.h>
31
32 #include "test-runner.h"
33 #include "wayland-util.h"
34 #include "wayland-private.h"
35
36 #include "test-compositor.h"
37
38 extern int fd_leak_check_enabled;
39
TEST(empty)40 TEST(empty)
41 {
42 }
43
TEST(exit_success)44 TEST(exit_success)
45 {
46 exit(EXIT_SUCCESS);
47 }
48
FAIL_TEST(exit_failure)49 FAIL_TEST(exit_failure)
50 {
51 exit(EXIT_FAILURE);
52 }
53
FAIL_TEST(fail_abort)54 FAIL_TEST(fail_abort)
55 {
56 test_disable_coredumps();
57 abort();
58 }
59
FAIL_TEST(fail_wl_abort)60 FAIL_TEST(fail_wl_abort)
61 {
62 test_disable_coredumps();
63 wl_abort("Abort the program\n");
64 }
65
FAIL_TEST(fail_kill)66 FAIL_TEST(fail_kill)
67 {
68 kill(getpid(), SIGTERM);
69 }
70
FAIL_TEST(fail_segv)71 FAIL_TEST(fail_segv)
72 {
73 char * volatile *null = 0;
74
75 test_disable_coredumps();
76 *null = "Goodbye, world";
77 }
78
FAIL_TEST(sanity_assert)79 FAIL_TEST(sanity_assert)
80 {
81 test_disable_coredumps();
82 /* must fail */
83 assert(0);
84 }
85
FAIL_TEST(sanity_fd_leak)86 FAIL_TEST(sanity_fd_leak)
87 {
88 int fd[2];
89
90 assert(fd_leak_check_enabled);
91
92 /* leak 2 file descriptors */
93 if (pipe(fd) < 0)
94 exit(EXIT_SUCCESS); /* failed to fail */
95
96 test_disable_coredumps();
97 }
98
FAIL_TEST(sanity_fd_leak_exec)99 FAIL_TEST(sanity_fd_leak_exec)
100 {
101 int fd[2];
102 int nr_fds = count_open_fds();
103
104 /* leak 2 file descriptors */
105 if (pipe(fd) < 0)
106 exit(EXIT_SUCCESS); /* failed to fail */
107
108 test_disable_coredumps();
109 exec_fd_leak_check(nr_fds);
110 }
111
TEST(sanity_fd_exec)112 TEST(sanity_fd_exec)
113 {
114 int fd[2];
115 int nr_fds = count_open_fds();
116
117 /* create 2 file descriptors, that should pass over exec */
118 assert(pipe(fd) >= 0);
119
120 exec_fd_leak_check(nr_fds + 2);
121 }
122
123 static void
sanity_fd_no_leak(void)124 sanity_fd_no_leak(void)
125 {
126 int fd[2];
127
128 assert(fd_leak_check_enabled);
129
130 /* leak 2 file descriptors */
131 if (pipe(fd) < 0)
132 exit(EXIT_SUCCESS); /* failed to fail */
133
134 close(fd[0]);
135 close(fd[1]);
136 }
137
138 static void
sanity_client_no_leak(void)139 sanity_client_no_leak(void)
140 {
141 struct wl_display *display = wl_display_connect(NULL);
142 assert(display);
143
144 wl_display_disconnect(display);
145 }
146
TEST(tc_client_no_fd_leaks)147 TEST(tc_client_no_fd_leaks)
148 {
149 struct display *d = display_create();
150
151 /* Client which does not consume the WAYLAND_DISPLAY socket. */
152 client_create_noarg(d, sanity_fd_no_leak);
153 display_run(d);
154
155 /* Client which does consume the WAYLAND_DISPLAY socket. */
156 client_create_noarg(d, sanity_client_no_leak);
157 display_run(d);
158
159 display_destroy(d);
160 }
161
FAIL_TEST(tc_client_fd_leaks)162 FAIL_TEST(tc_client_fd_leaks)
163 {
164 struct display *d = display_create();
165
166 client_create_noarg(d, sanity_fd_leak);
167 display_run(d);
168
169 test_disable_coredumps();
170 display_destroy(d);
171 }
172
FAIL_TEST(tc_client_fd_leaks_exec)173 FAIL_TEST(tc_client_fd_leaks_exec)
174 {
175 struct display *d = display_create();
176
177 client_create_noarg(d, sanity_fd_leak);
178 display_run(d);
179
180 test_disable_coredumps();
181 display_destroy(d);
182 }
183
FAIL_TEST(timeout_tst)184 FAIL_TEST(timeout_tst)
185 {
186 test_set_timeout(1);
187 test_disable_coredumps();
188 /* test should reach timeout */
189 test_sleep(2);
190 }
191
TEST(timeout2_tst)192 TEST(timeout2_tst)
193 {
194 /* the test should end before reaching timeout,
195 * thus it should pass */
196 test_set_timeout(1);
197 /* 200 000 microsec = 0.2 sec */
198 test_usleep(200000);
199 }
200
FAIL_TEST(timeout_reset_tst)201 FAIL_TEST(timeout_reset_tst)
202 {
203 test_set_timeout(5);
204 test_set_timeout(10);
205 test_set_timeout(1);
206
207 test_disable_coredumps();
208 /* test should fail on timeout */
209 test_sleep(2);
210 }
211
TEST(timeout_turnoff)212 TEST(timeout_turnoff)
213 {
214 test_set_timeout(1);
215 test_set_timeout(0);
216
217 test_usleep(2);
218 }
219
220 /* test timeouts with test-compositor */
FAIL_TEST(tc_timeout_tst)221 FAIL_TEST(tc_timeout_tst)
222 {
223 struct display *d = display_create();
224 client_create_noarg(d, timeout_tst);
225 display_run(d);
226 test_disable_coredumps();
227 display_destroy(d);
228 }
229
FAIL_TEST(tc_timeout2_tst)230 FAIL_TEST(tc_timeout2_tst)
231 {
232 struct display *d = display_create();
233 client_create_noarg(d, timeout_reset_tst);
234 display_run(d);
235 test_disable_coredumps();
236 display_destroy(d);
237 }
238
TEST(tc_timeout3_tst)239 TEST(tc_timeout3_tst)
240 {
241 struct display *d = display_create();
242
243 client_create_noarg(d, timeout2_tst);
244 display_run(d);
245
246 client_create_noarg(d, timeout_turnoff);
247 display_run(d);
248
249 display_destroy(d);
250 }
251