xref: /third_party/libuv/test/test-ref.c (revision e66f31c5)
1/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to
5 * deal in the Software without restriction, including without limitation the
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 * IN THE SOFTWARE.
20 */
21
22#include "uv.h"
23#include "task.h"
24
25#include <stdlib.h>
26#include <string.h>
27
28
29static uv_write_t write_req;
30static uv_shutdown_t shutdown_req;
31static uv_connect_t connect_req;
32
33static char buffer[32767];
34
35static int req_cb_called;
36static int connect_cb_called;
37static int write_cb_called;
38static int shutdown_cb_called;
39static int close_cb_called;
40
41
42static void close_cb(uv_handle_t* handle) {
43  close_cb_called++;
44}
45
46
47static void do_close(void* handle) {
48  close_cb_called = 0;
49  uv_close((uv_handle_t*)handle, close_cb);
50  ASSERT_OK(close_cb_called);
51  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
52  ASSERT_EQ(1, close_cb_called);
53}
54
55
56static void fail_cb(void) {
57  FATAL("fail_cb should not have been called");
58}
59
60
61static void fail_cb2(void) {
62  ASSERT(0 && "fail_cb2 should not have been called");
63}
64
65
66static void req_cb(uv_handle_t* req, int status) {
67  req_cb_called++;
68}
69
70
71static void shutdown_cb(uv_shutdown_t* req, int status) {
72  ASSERT_PTR_EQ(req, &shutdown_req);
73  shutdown_cb_called++;
74}
75
76
77static void write_cb(uv_write_t* req, int status) {
78  ASSERT_PTR_EQ(req, &write_req);
79  uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
80  write_cb_called++;
81}
82
83
84static void connect_and_write(uv_connect_t* req, int status) {
85  uv_buf_t buf = uv_buf_init(buffer, sizeof buffer);
86  ASSERT_PTR_EQ(req, &connect_req);
87  ASSERT_OK(status);
88  uv_write(&write_req, req->handle, &buf, 1, write_cb);
89  connect_cb_called++;
90}
91
92
93
94static void connect_and_shutdown(uv_connect_t* req, int status) {
95  ASSERT_PTR_EQ(req, &connect_req);
96  ASSERT_OK(status);
97  uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
98  connect_cb_called++;
99}
100
101
102TEST_IMPL(ref) {
103  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
104  MAKE_VALGRIND_HAPPY(uv_default_loop());
105  return 0;
106}
107
108
109TEST_IMPL(idle_ref) {
110  uv_idle_t h;
111  uv_idle_init(uv_default_loop(), &h);
112  uv_idle_start(&h, (uv_idle_cb) fail_cb2);
113  uv_unref((uv_handle_t*)&h);
114  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
115  do_close(&h);
116  MAKE_VALGRIND_HAPPY(uv_default_loop());
117  return 0;
118}
119
120
121TEST_IMPL(async_ref) {
122  uv_async_t h;
123  uv_async_init(uv_default_loop(), &h, NULL);
124  uv_unref((uv_handle_t*)&h);
125  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
126  do_close(&h);
127  MAKE_VALGRIND_HAPPY(uv_default_loop());
128  return 0;
129}
130
131
132TEST_IMPL(prepare_ref) {
133  uv_prepare_t h;
134  uv_prepare_init(uv_default_loop(), &h);
135  uv_prepare_start(&h, (uv_prepare_cb) fail_cb2);
136  uv_unref((uv_handle_t*)&h);
137  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
138  do_close(&h);
139  MAKE_VALGRIND_HAPPY(uv_default_loop());
140  return 0;
141}
142
143
144TEST_IMPL(check_ref) {
145  uv_check_t h;
146  uv_check_init(uv_default_loop(), &h);
147  uv_check_start(&h, (uv_check_cb) fail_cb2);
148  uv_unref((uv_handle_t*)&h);
149  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
150  do_close(&h);
151  MAKE_VALGRIND_HAPPY(uv_default_loop());
152  return 0;
153}
154
155
156static void prepare_cb(uv_prepare_t* h) {
157  ASSERT_NOT_NULL(h);
158  uv_unref((uv_handle_t*)h);
159}
160
161
162TEST_IMPL(unref_in_prepare_cb) {
163  uv_prepare_t h;
164  uv_prepare_init(uv_default_loop(), &h);
165  uv_prepare_start(&h, prepare_cb);
166  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
167  do_close(&h);
168  MAKE_VALGRIND_HAPPY(uv_default_loop());
169  return 0;
170}
171
172
173TEST_IMPL(timer_ref) {
174  uv_timer_t h;
175  uv_timer_init(uv_default_loop(), &h);
176  uv_unref((uv_handle_t*)&h);
177  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
178  do_close(&h);
179  MAKE_VALGRIND_HAPPY(uv_default_loop());
180  return 0;
181}
182
183
184TEST_IMPL(timer_ref2) {
185  uv_timer_t h;
186  uv_timer_init(uv_default_loop(), &h);
187  uv_timer_start(&h, (uv_timer_cb)fail_cb, 42, 42);
188  uv_unref((uv_handle_t*)&h);
189  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
190  do_close(&h);
191  MAKE_VALGRIND_HAPPY(uv_default_loop());
192  return 0;
193}
194
195
196TEST_IMPL(fs_event_ref) {
197#if defined(NO_FS_EVENTS)
198  RETURN_SKIP(NO_FS_EVENTS);
199#endif
200  uv_fs_event_t h;
201  uv_fs_event_init(uv_default_loop(), &h);
202  uv_fs_event_start(&h, (uv_fs_event_cb)fail_cb, ".", 0);
203  uv_unref((uv_handle_t*)&h);
204  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
205  do_close(&h);
206  MAKE_VALGRIND_HAPPY(uv_default_loop());
207  return 0;
208}
209
210
211TEST_IMPL(fs_poll_ref) {
212  uv_fs_poll_t h;
213  uv_fs_poll_init(uv_default_loop(), &h);
214  uv_fs_poll_start(&h, NULL, ".", 999);
215  uv_unref((uv_handle_t*)&h);
216  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
217  do_close(&h);
218  MAKE_VALGRIND_HAPPY(uv_default_loop());
219  return 0;
220}
221
222
223TEST_IMPL(tcp_ref) {
224  uv_tcp_t h;
225  uv_tcp_init(uv_default_loop(), &h);
226  uv_unref((uv_handle_t*)&h);
227  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
228  do_close(&h);
229  MAKE_VALGRIND_HAPPY(uv_default_loop());
230  return 0;
231}
232
233
234TEST_IMPL(tcp_ref2) {
235  uv_tcp_t h;
236  uv_tcp_init(uv_default_loop(), &h);
237  uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
238  uv_unref((uv_handle_t*)&h);
239  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
240  do_close(&h);
241  MAKE_VALGRIND_HAPPY(uv_default_loop());
242  return 0;
243}
244
245
246TEST_IMPL(tcp_ref2b) {
247  uv_tcp_t h;
248  uv_tcp_init(uv_default_loop(), &h);
249  uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
250  uv_unref((uv_handle_t*)&h);
251  uv_close((uv_handle_t*)&h, close_cb);
252  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
253  ASSERT_EQ(1, close_cb_called);
254  MAKE_VALGRIND_HAPPY(uv_default_loop());
255  return 0;
256}
257
258
259TEST_IMPL(tcp_ref3) {
260  struct sockaddr_in addr;
261  uv_tcp_t h;
262  ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
263  uv_tcp_init(uv_default_loop(), &h);
264  uv_tcp_connect(&connect_req,
265                 &h,
266                 (const struct sockaddr*) &addr,
267                 connect_and_shutdown);
268  uv_unref((uv_handle_t*)&h);
269  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
270  ASSERT_EQ(1, connect_cb_called);
271  ASSERT_EQ(1, shutdown_cb_called);
272  do_close(&h);
273  MAKE_VALGRIND_HAPPY(uv_default_loop());
274  return 0;
275}
276
277
278TEST_IMPL(tcp_ref4) {
279  struct sockaddr_in addr;
280  uv_tcp_t h;
281  ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
282  uv_tcp_init(uv_default_loop(), &h);
283  uv_tcp_connect(&connect_req,
284                 &h,
285                 (const struct sockaddr*) &addr,
286                 connect_and_write);
287  uv_unref((uv_handle_t*)&h);
288  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
289  ASSERT_EQ(1, connect_cb_called);
290  ASSERT_EQ(1, write_cb_called);
291  ASSERT_EQ(1, shutdown_cb_called);
292  do_close(&h);
293  MAKE_VALGRIND_HAPPY(uv_default_loop());
294  return 0;
295}
296
297
298TEST_IMPL(udp_ref) {
299  uv_udp_t h;
300  uv_udp_init(uv_default_loop(), &h);
301  uv_unref((uv_handle_t*)&h);
302  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
303  do_close(&h);
304  MAKE_VALGRIND_HAPPY(uv_default_loop());
305  return 0;
306}
307
308
309TEST_IMPL(udp_ref2) {
310  struct sockaddr_in addr;
311  uv_udp_t h;
312  ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
313  uv_udp_init(uv_default_loop(), &h);
314  uv_udp_bind(&h, (const struct sockaddr*) &addr, 0);
315  uv_udp_recv_start(&h, (uv_alloc_cb)fail_cb, (uv_udp_recv_cb)fail_cb);
316  uv_unref((uv_handle_t*)&h);
317  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
318  do_close(&h);
319  MAKE_VALGRIND_HAPPY(uv_default_loop());
320  return 0;
321}
322
323
324TEST_IMPL(udp_ref3) {
325  struct sockaddr_in addr;
326  uv_buf_t buf = uv_buf_init("PING", 4);
327  uv_udp_send_t req;
328  uv_udp_t h;
329
330  ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
331  uv_udp_init(uv_default_loop(), &h);
332  uv_udp_send(&req,
333              &h,
334              &buf,
335              1,
336              (const struct sockaddr*) &addr,
337              (uv_udp_send_cb) req_cb);
338  uv_unref((uv_handle_t*)&h);
339  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
340  ASSERT_EQ(1, req_cb_called);
341  do_close(&h);
342
343  MAKE_VALGRIND_HAPPY(uv_default_loop());
344  return 0;
345}
346
347
348TEST_IMPL(pipe_ref) {
349  uv_pipe_t h;
350  uv_pipe_init(uv_default_loop(), &h, 0);
351  uv_unref((uv_handle_t*)&h);
352  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
353  do_close(&h);
354  MAKE_VALGRIND_HAPPY(uv_default_loop());
355  return 0;
356}
357
358
359TEST_IMPL(pipe_ref2) {
360  uv_pipe_t h;
361  uv_pipe_init(uv_default_loop(), &h, 0);
362  uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
363  uv_unref((uv_handle_t*)&h);
364  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
365  do_close(&h);
366  MAKE_VALGRIND_HAPPY(uv_default_loop());
367  return 0;
368}
369
370
371TEST_IMPL(pipe_ref3) {
372  uv_pipe_t h;
373  uv_pipe_init(uv_default_loop(), &h, 0);
374  uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_and_shutdown);
375  uv_unref((uv_handle_t*)&h);
376  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
377  ASSERT_EQ(1, connect_cb_called);
378  ASSERT_EQ(1, shutdown_cb_called);
379  do_close(&h);
380  MAKE_VALGRIND_HAPPY(uv_default_loop());
381  return 0;
382}
383
384
385TEST_IMPL(pipe_ref4) {
386  uv_pipe_t h;
387  uv_pipe_init(uv_default_loop(), &h, 0);
388  uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_and_write);
389  uv_unref((uv_handle_t*)&h);
390  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
391  ASSERT_EQ(1, connect_cb_called);
392  ASSERT_EQ(1, write_cb_called);
393  ASSERT_EQ(1, shutdown_cb_called);
394  do_close(&h);
395  MAKE_VALGRIND_HAPPY(uv_default_loop());
396  return 0;
397}
398
399
400TEST_IMPL(process_ref) {
401  /* spawn_helper4 blocks indefinitely. */
402  char *argv[] = { NULL, "spawn_helper4", NULL };
403  uv_process_options_t options;
404  size_t exepath_size;
405  char exepath[256];
406  uv_process_t h;
407  int r;
408
409  memset(&options, 0, sizeof(options));
410  exepath_size = sizeof(exepath);
411
412  r = uv_exepath(exepath, &exepath_size);
413  ASSERT_OK(r);
414
415  argv[0] = exepath;
416  options.file = exepath;
417  options.args = argv;
418  options.exit_cb = NULL;
419
420  r = uv_spawn(uv_default_loop(), &h, &options);
421  ASSERT_OK(r);
422
423  uv_unref((uv_handle_t*)&h);
424  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
425
426  r = uv_process_kill(&h, /* SIGTERM */ 15);
427  ASSERT_OK(r);
428
429  do_close(&h);
430
431  MAKE_VALGRIND_HAPPY(uv_default_loop());
432  return 0;
433}
434
435
436TEST_IMPL(has_ref) {
437  uv_idle_t h;
438  uv_idle_init(uv_default_loop(), &h);
439  uv_ref((uv_handle_t*)&h);
440  ASSERT_EQ(1, uv_has_ref((uv_handle_t*)&h));
441  uv_unref((uv_handle_t*)&h);
442  ASSERT_OK(uv_has_ref((uv_handle_t*)&h));
443  MAKE_VALGRIND_HAPPY(uv_default_loop());
444  return 0;
445}
446