diff options
Diffstat (limited to 'deps/uv/test')
-rw-r--r-- | deps/uv/test/benchmark-list.h | 1 | ||||
-rw-r--r-- | deps/uv/test/dns-server.c | 340 | ||||
-rw-r--r-- | deps/uv/test/task.h | 2 | ||||
-rw-r--r-- | deps/uv/test/test-fs-copyfile.c | 3 | ||||
-rw-r--r-- | deps/uv/test/test-fs-event.c | 52 | ||||
-rw-r--r-- | deps/uv/test/test-fs-open-flags.c | 38 | ||||
-rw-r--r-- | deps/uv/test/test-fs-readdir.c | 3 | ||||
-rw-r--r-- | deps/uv/test/test-fs.c | 8 | ||||
-rw-r--r-- | deps/uv/test/test-ip-name.c | 65 | ||||
-rw-r--r-- | deps/uv/test/test-ip6-addr.c | 6 | ||||
-rw-r--r-- | deps/uv/test/test-list.h | 14 | ||||
-rw-r--r-- | deps/uv/test/test-ping-pong.c | 3 | ||||
-rw-r--r-- | deps/uv/test/test-pipe-connect-error.c | 3 | ||||
-rw-r--r-- | deps/uv/test/test-readable-on-eof.c (renamed from deps/uv/test/test-not-readable-on-eof.c) | 60 | ||||
-rw-r--r-- | deps/uv/test/test-tcp-connect-timeout.c | 2 | ||||
-rw-r--r-- | deps/uv/test/test-thread-equal.c | 6 | ||||
-rw-r--r-- | deps/uv/test/test-tty-escape-sequence-processing.c | 16 | ||||
-rw-r--r-- | deps/uv/test/test-udp-connect.c | 2 | ||||
-rw-r--r-- | deps/uv/test/test-udp-connect6.c | 200 |
19 files changed, 406 insertions, 418 deletions
diff --git a/deps/uv/test/benchmark-list.h b/deps/uv/test/benchmark-list.h index 29e44c30f0..71e4eab9a5 100644 --- a/deps/uv/test/benchmark-list.h +++ b/deps/uv/test/benchmark-list.h @@ -81,7 +81,6 @@ HELPER_DECLARE (tcp_pump_server) HELPER_DECLARE (pipe_pump_server) HELPER_DECLARE (tcp4_echo_server) HELPER_DECLARE (pipe_echo_server) -HELPER_DECLARE (dns_server) TASK_LIST_START BENCHMARK_ENTRY (sizes) diff --git a/deps/uv/test/dns-server.c b/deps/uv/test/dns-server.c deleted file mode 100644 index f8ca87f227..0000000000 --- a/deps/uv/test/dns-server.c +++ /dev/null @@ -1,340 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - - -typedef struct { - uv_write_t req; - uv_buf_t buf; -} write_req_t; - - -/* used to track multiple DNS requests received */ -typedef struct { - char* prevbuf_ptr; - int prevbuf_pos; - int prevbuf_rem; -} dnsstate; - - -/* modify handle to append dnsstate */ -typedef struct { - uv_tcp_t handle; - dnsstate state; -} dnshandle; - - -static uv_loop_t* loop; - - -static uv_tcp_t server; - - -static void after_write(uv_write_t* req, int status); -static void after_read(uv_stream_t*, ssize_t nread, const uv_buf_t* buf); -static void on_close(uv_handle_t* peer); -static void on_connection(uv_stream_t*, int status); - -#define WRITE_BUF_LEN (64*1024) -#define DNSREC_LEN (4) - -#define LEN_OFFSET 0 -#define QUERYID_OFFSET 2 - -static unsigned char DNSRsp[] = { - 0, 43, 0, 0, 0x81, 0x80, 0, 1, 0, 1, 0, 0, 0, 0 -}; - -static unsigned char qrecord[] = { - 5, 'e', 'c', 'h', 'o', 's', 3, 's', 'r', 'v', 0, 0, 1, 0, 1 -}; - -static unsigned char arecord[] = { - 0xc0, 0x0c, 0, 1, 0, 1, 0, 0, 5, 0xbd, 0, 4, 10, 0, 1, 1 -}; - - -static void after_write(uv_write_t* req, int status) { - write_req_t* wr; - - if (status) { - fprintf(stderr, "uv_write error: %s\n", uv_strerror(status)); - ASSERT(0); - } - - wr = (write_req_t*) req; - - /* Free the read/write buffer and the request */ - free(wr->buf.base); - free(wr); -} - - -static void after_shutdown(uv_shutdown_t* req, int status) { - uv_close((uv_handle_t*) req->handle, on_close); - free(req); -} - - -static void addrsp(write_req_t* wr, char* hdr) { - char * dnsrsp; - short int rsplen; - short int* reclen; - - rsplen = sizeof(DNSRsp) + sizeof(qrecord) + sizeof(arecord); - - ASSERT (rsplen + wr->buf.len < WRITE_BUF_LEN); - - dnsrsp = wr->buf.base + wr->buf.len; - - /* copy stock response */ - memcpy(dnsrsp, DNSRsp, sizeof(DNSRsp)); - memcpy(dnsrsp + sizeof(DNSRsp), qrecord, sizeof(qrecord)); - memcpy(dnsrsp + sizeof(DNSRsp) + sizeof(qrecord), arecord, sizeof(arecord)); - - /* overwrite with network order length and id from request header */ - reclen = (short int*)dnsrsp; - *reclen = htons(rsplen-2); - dnsrsp[QUERYID_OFFSET] = hdr[QUERYID_OFFSET]; - dnsrsp[QUERYID_OFFSET+1] = hdr[QUERYID_OFFSET+1]; - - wr->buf.len += rsplen; -} - -static void process_req(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - write_req_t* wr; - dnshandle* dns = (dnshandle*)handle; - char hdrbuf[DNSREC_LEN]; - int hdrbuf_remaining = DNSREC_LEN; - int rec_remaining = 0; - int readbuf_remaining; - char* dnsreq; - char* hdrstart; - int usingprev = 0; - - wr = (write_req_t*) malloc(sizeof *wr); - wr->buf.base = (char*)malloc(WRITE_BUF_LEN); - wr->buf.len = 0; - - if (dns->state.prevbuf_ptr != NULL) { - dnsreq = dns->state.prevbuf_ptr + dns->state.prevbuf_pos; - readbuf_remaining = dns->state.prevbuf_rem; - usingprev = 1; - } else { - dnsreq = buf->base; - readbuf_remaining = nread; - } - hdrstart = dnsreq; - - while (dnsreq != NULL) { - /* something to process */ - while (readbuf_remaining > 0) { - /* something to process in current buffer */ - if (hdrbuf_remaining > 0) { - /* process len and id */ - if (readbuf_remaining < hdrbuf_remaining) { - /* too little to get request header. save for next buffer */ - memcpy(&hdrbuf[DNSREC_LEN - hdrbuf_remaining], - dnsreq, - readbuf_remaining); - hdrbuf_remaining = DNSREC_LEN - readbuf_remaining; - break; - } else { - /* save header */ - memcpy(&hdrbuf[DNSREC_LEN - hdrbuf_remaining], - dnsreq, - hdrbuf_remaining); - dnsreq += hdrbuf_remaining; - readbuf_remaining -= hdrbuf_remaining; - hdrbuf_remaining = 0; - - /* get record length */ - rec_remaining = (unsigned) hdrbuf[0] * 256 + (unsigned) hdrbuf[1]; - rec_remaining -= (DNSREC_LEN - 2); - } - } - - if (rec_remaining <= readbuf_remaining) { - /* prepare reply */ - addrsp(wr, hdrbuf); - - /* move to next record */ - dnsreq += rec_remaining; - hdrstart = dnsreq; - readbuf_remaining -= rec_remaining; - rec_remaining = 0; - hdrbuf_remaining = DNSREC_LEN; - } else { - /* otherwise this buffer is done. */ - rec_remaining -= readbuf_remaining; - break; - } - } - - /* If we had to use bytes from prev buffer, start processing the current - * one. - */ - if (usingprev == 1) { - /* free previous buffer */ - free(dns->state.prevbuf_ptr); - dnsreq = buf->base; - readbuf_remaining = nread; - usingprev = 0; - } else { - dnsreq = NULL; - } - } - - /* send write buffer */ - if (wr->buf.len > 0) { - if (uv_write((uv_write_t*) &wr->req, handle, &wr->buf, 1, after_write)) { - FATAL("uv_write failed"); - } - } - - if (readbuf_remaining > 0) { - /* save start of record position, so we can continue on next read */ - dns->state.prevbuf_ptr = buf->base; - dns->state.prevbuf_pos = hdrstart - buf->base; - dns->state.prevbuf_rem = nread - dns->state.prevbuf_pos; - } else { - /* nothing left in this buffer */ - dns->state.prevbuf_ptr = NULL; - dns->state.prevbuf_pos = 0; - dns->state.prevbuf_rem = 0; - free(buf->base); - } -} - -static void after_read(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - uv_shutdown_t* req; - - if (nread < 0) { - /* Error or EOF */ - ASSERT(nread == UV_EOF); - - if (buf->base) { - free(buf->base); - } - - req = malloc(sizeof *req); - uv_shutdown(req, handle, after_shutdown); - - return; - } - - if (nread == 0) { - /* Everything OK, but nothing read. */ - free(buf->base); - return; - } - /* process requests and send responses */ - process_req(handle, nread, buf); -} - - -static void on_close(uv_handle_t* peer) { - free(peer); -} - - -static void buf_alloc(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - buf->base = malloc(suggested_size); - buf->len = suggested_size; -} - - -static void on_connection(uv_stream_t* server, int status) { - dnshandle* handle; - int r; - - ASSERT(status == 0); - - handle = (dnshandle*) malloc(sizeof *handle); - ASSERT_NOT_NULL(handle); - - /* initialize read buffer state */ - handle->state.prevbuf_ptr = 0; - handle->state.prevbuf_pos = 0; - handle->state.prevbuf_rem = 0; - - r = uv_tcp_init(loop, (uv_tcp_t*)handle); - ASSERT(r == 0); - - r = uv_accept(server, (uv_stream_t*)handle); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*)handle, buf_alloc, after_read); - ASSERT(r == 0); -} - - -static int dns_start(int port) { - struct sockaddr_in addr; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", port, &addr)); - - r = uv_tcp_init(loop, &server); - if (r) { - /* TODO: Error codes */ - fprintf(stderr, "Socket creation error\n"); - return 1; - } - - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); - if (r) { - /* TODO: Error codes */ - fprintf(stderr, "Bind error\n"); - return 1; - } - - r = uv_listen((uv_stream_t*)&server, 128, on_connection); - if (r) { - /* TODO: Error codes */ - fprintf(stderr, "Listen error\n"); - return 1; - } - - return 0; -} - - -HELPER_IMPL(dns_server) { - loop = uv_default_loop(); - - if (dns_start(TEST_PORT_2)) - return 1; - - uv_run(loop, UV_RUN_DEFAULT); - return 0; -} diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h index a02c8931b5..925f1b1c0a 100644 --- a/deps/uv/test/task.h +++ b/deps/uv/test/task.h @@ -277,7 +277,7 @@ const char* fmt(double d); /* Reserved test exit codes. */ enum test_status { TEST_OK = 0, - TEST_SKIP + TEST_SKIP = 7 }; #define RETURN_OK() \ diff --git a/deps/uv/test/test-fs-copyfile.c b/deps/uv/test/test-fs-copyfile.c index fa00fe4ee8..c785a4b51f 100644 --- a/deps/uv/test/test-fs-copyfile.c +++ b/deps/uv/test/test-fs-copyfile.c @@ -96,9 +96,6 @@ static void touch_file(const char* name, unsigned int size) { TEST_IMPL(fs_copyfile) { -#if defined(__ASAN__) - RETURN_SKIP("Test does not currently work in ASAN"); -#endif const char src[] = "test_file_src"; uv_loop_t* loop; uv_fs_t req; diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c index ec163868f4..cbe6319078 100644 --- a/deps/uv/test/test-fs-event.c +++ b/deps/uv/test/test-fs-event.c @@ -380,7 +380,7 @@ static void timer_cb_file(uv_timer_t* handle) { static void timer_cb_touch(uv_timer_t* timer) { uv_close((uv_handle_t*)timer, NULL); - touch_file("watch_file"); + touch_file((char*) timer->data); timer_cb_touch_called++; } @@ -674,9 +674,6 @@ TEST_IMPL(fs_event_watch_file_twice) { #if defined(NO_FS_EVENTS) RETURN_SKIP(NO_FS_EVENTS); #endif -#if defined(__ASAN__) - RETURN_SKIP("Test does not currently work in ASAN"); -#endif const char path[] = "test/fixtures/empty_file"; uv_fs_event_t watchers[2]; uv_timer_t timer; @@ -730,6 +727,7 @@ TEST_IMPL(fs_event_watch_file_current_dir) { r = uv_timer_init(loop, &timer); ASSERT(r == 0); + timer.data = "watch_file"; r = uv_timer_start(&timer, timer_cb_touch, 1100, 0); ASSERT(r == 0); @@ -1174,3 +1172,49 @@ TEST_IMPL(fs_event_watch_invalid_path) { MAKE_VALGRIND_HAPPY(); return 0; } + +static int fs_event_cb_stop_calls; + +static void fs_event_cb_stop(uv_fs_event_t* handle, const char* path, + int events, int status) { + uv_fs_event_stop(handle); + fs_event_cb_stop_calls++; +} + +TEST_IMPL(fs_event_stop_in_cb) { + uv_fs_event_t fs; + uv_timer_t timer; + char path[] = "fs_event_stop_in_cb.txt"; + +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + + remove(path); + create_file(path); + + ASSERT_EQ(0, uv_fs_event_init(uv_default_loop(), &fs)); + ASSERT_EQ(0, uv_fs_event_start(&fs, fs_event_cb_stop, path, 0)); + + /* Note: timer_cb_touch() closes the handle. */ + timer.data = path; + ASSERT_EQ(0, uv_timer_init(uv_default_loop(), &timer)); + ASSERT_EQ(0, uv_timer_start(&timer, timer_cb_touch, 100, 0)); + + ASSERT_EQ(0, fs_event_cb_stop_calls); + ASSERT_EQ(0, timer_cb_touch_called); + + ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + ASSERT_EQ(1, fs_event_cb_stop_calls); + ASSERT_EQ(1, timer_cb_touch_called); + + uv_close((uv_handle_t*) &fs, NULL); + ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT_EQ(1, fs_event_cb_stop_calls); + + remove(path); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-fs-open-flags.c b/deps/uv/test/test-fs-open-flags.c index 5f61007add..372afe1397 100644 --- a/deps/uv/test/test-fs-open-flags.c +++ b/deps/uv/test/test-fs-open-flags.c @@ -276,21 +276,21 @@ static void fs_open_flags(int add_flags) { /* r */ flags = add_flags | UV_FS_O_RDONLY; openFail(absent_file, UV_ENOENT); - writeFail(empty_file, UV_EPERM); + writeFail(empty_file, UV_EBADF); readExpect(empty_file, "", 0); - writeFail(dummy_file, UV_EPERM); + writeFail(dummy_file, UV_EBADF); readExpect(dummy_file, "a", 1); - writeFail(empty_dir, UV_EPERM); + writeFail(empty_dir, UV_EBADF); readFail(empty_dir, UV_EISDIR); /* rs */ flags = add_flags | UV_FS_O_RDONLY | UV_FS_O_SYNC; openFail(absent_file, UV_ENOENT); - writeFail(empty_file, UV_EPERM); + writeFail(empty_file, UV_EBADF); readExpect(empty_file, "", 0); - writeFail(dummy_file, UV_EPERM); + writeFail(dummy_file, UV_EBADF); readExpect(dummy_file, "a", 1); - writeFail(empty_dir, UV_EPERM); + writeFail(empty_dir, UV_EBADF); readFail(empty_dir, UV_EISDIR); /* r+ */ @@ -316,18 +316,18 @@ static void fs_open_flags(int add_flags) { /* w */ flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY; writeExpect(absent_file, "bc", 2); - readFail(absent_file, UV_EPERM); + readFail(absent_file, UV_EBADF); writeExpect(empty_file, "bc", 2); - readFail(empty_file, UV_EPERM); + readFail(empty_file, UV_EBADF); writeExpect(dummy_file, "bc", 2); - readFail(dummy_file, UV_EPERM); + readFail(dummy_file, UV_EBADF); openFail(empty_dir, UV_EISDIR); /* wx */ flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY | UV_FS_O_EXCL; writeExpect(absent_file, "bc", 2); - readFail(absent_file, UV_EPERM); + readFail(absent_file, UV_EBADF); openFail(empty_file, UV_EEXIST); openFail(dummy_file, UV_EEXIST); openFail(empty_dir, UV_EEXIST); @@ -354,19 +354,19 @@ static void fs_open_flags(int add_flags) { /* a */ flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY; writeExpect(absent_file, "bc", 2); - readFail(absent_file, UV_EPERM); + readFail(absent_file, UV_EBADF); writeExpect(empty_file, "bc", 2); - readFail(empty_file, UV_EPERM); + readFail(empty_file, UV_EBADF); writeExpect(dummy_file, "abc", 3); - readFail(dummy_file, UV_EPERM); + readFail(dummy_file, UV_EBADF); writeFail(empty_dir, UV_EISDIR); - readFail(empty_dir, UV_EPERM); + readFail(empty_dir, UV_EBADF); /* ax */ flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY | UV_FS_O_EXCL; writeExpect(absent_file, "bc", 2); - readFail(absent_file, UV_EPERM); + readFail(absent_file, UV_EBADF); openFail(empty_file, UV_EEXIST); openFail(dummy_file, UV_EEXIST); openFail(empty_dir, UV_EEXIST); @@ -375,13 +375,13 @@ static void fs_open_flags(int add_flags) { flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY | UV_FS_O_SYNC; writeExpect(absent_file, "bc", 2); - readFail(absent_file, UV_EPERM); + readFail(absent_file, UV_EBADF); writeExpect(empty_file, "bc", 2); - readFail(empty_file, UV_EPERM); + readFail(empty_file, UV_EBADF); writeExpect(dummy_file, "abc", 3); - readFail(dummy_file, UV_EPERM); + readFail(dummy_file, UV_EBADF); writeFail(empty_dir, UV_EISDIR); - readFail(empty_dir, UV_EPERM); + readFail(empty_dir, UV_EBADF); /* a+ */ flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR; diff --git a/deps/uv/test/test-fs-readdir.c b/deps/uv/test/test-fs-readdir.c index 41e1d373ca..6bb6917841 100644 --- a/deps/uv/test/test-fs-readdir.c +++ b/deps/uv/test/test-fs-readdir.c @@ -230,9 +230,6 @@ static void file_opendir_cb(uv_fs_t* req) { } TEST_IMPL(fs_readdir_file) { -#if defined(__ASAN__) - RETURN_SKIP("Test does not currently work in ASAN"); -#endif const char* path; int r; diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index 034c971d36..aecf10f9e2 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -844,7 +844,7 @@ static void check_utime(const char* path, } else { double st_atim; double st_mtim; -#ifndef __APPLE__ +#if !defined(__APPLE__) && !defined(__SUNPRO_C) /* TODO(vtjnash): would it be better to normalize this? */ ASSERT_DOUBLE_GE(s->st_atim.tv_nsec, 0); ASSERT_DOUBLE_GE(s->st_mtim.tv_nsec, 0); @@ -2897,9 +2897,6 @@ TEST_IMPL(fs_scandir_non_existent_dir) { } TEST_IMPL(fs_scandir_file) { -#if defined(__ASAN__) - RETURN_SKIP("Test does not currently work in ASAN"); -#endif const char* path; int r; @@ -3146,9 +3143,6 @@ static void fs_read_bufs(int add_flags) { uv_fs_req_cleanup(&close_req); } TEST_IMPL(fs_read_bufs) { -#if defined(__ASAN__) - RETURN_SKIP("Test does not currently work in ASAN"); -#endif fs_read_bufs(0); fs_read_bufs(UV_FS_O_FILEMAP); diff --git a/deps/uv/test/test-ip-name.c b/deps/uv/test/test-ip-name.c new file mode 100644 index 0000000000..1cb1b60583 --- /dev/null +++ b/deps/uv/test/test-ip-name.c @@ -0,0 +1,65 @@ +/* Copyright The libuv project and contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include <stdio.h> +#include <string.h> + +union TestAddr { + struct sockaddr addr; + struct sockaddr_in addr4; + struct sockaddr_in6 addr6; +}; + + +TEST_IMPL(ip_name) { + char dst[INET6_ADDRSTRLEN]; + union TestAddr test_addr; + struct sockaddr* addr = &test_addr.addr; + struct sockaddr_in* addr4 = &test_addr.addr4; + struct sockaddr_in6* addr6 = &test_addr.addr6; + + /* test ip4_name */ + ASSERT_EQ(0, uv_ip4_addr("192.168.0.1", TEST_PORT, addr4)); + ASSERT_EQ(0, uv_ip4_name(addr4, dst, INET_ADDRSTRLEN)); + ASSERT_EQ(0, strcmp("192.168.0.1", dst)); + + ASSERT_EQ(0, uv_ip_name(addr, dst, INET_ADDRSTRLEN)); + ASSERT_EQ(0, strcmp("192.168.0.1", dst)); + + /* test ip6_name */ + ASSERT_EQ(0, uv_ip6_addr("fe80::2acf:daff:fedd:342a", TEST_PORT, addr6)); + ASSERT_EQ(0, uv_ip6_name(addr6, dst, INET6_ADDRSTRLEN)); + ASSERT_EQ(0, strcmp("fe80::2acf:daff:fedd:342a", dst)); + + ASSERT_EQ(0, uv_ip_name(addr, dst, INET6_ADDRSTRLEN)); + ASSERT_EQ(0, strcmp("fe80::2acf:daff:fedd:342a", dst)); + + /* test other sa_family */ + addr->sa_family = AF_UNIX; + /* size is not a concern here */ + ASSERT_EQ(UV_EAFNOSUPPORT, uv_ip_name(addr, dst, INET6_ADDRSTRLEN)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-ip6-addr.c b/deps/uv/test/test-ip6-addr.c index 39d570659d..8036c4b171 100644 --- a/deps/uv/test/test-ip6-addr.c +++ b/deps/uv/test/test-ip6-addr.c @@ -161,11 +161,11 @@ TEST_IMPL(ip6_pton) { #undef GOOD_ADDR_LIST #undef BAD_ADDR_LIST -#ifdef SIN6_LEN TEST_IMPL(ip6_sin6_len) { struct sockaddr_in6 s; - ASSERT(uv_ip6_addr("::", 0, &s) < 0); + ASSERT_EQ(0, uv_ip6_addr("::", 0, &s)); +#ifdef SIN6_LEN ASSERT(s.sin6_len == sizeof(s)); +#endif return 0; } -#endif diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 59b95da9eb..1f566861a0 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -78,6 +78,7 @@ TEST_DECLARE (tty_pty) TEST_DECLARE (stdio_over_pipes) TEST_DECLARE (stdio_emulate_iocp) TEST_DECLARE (ip6_pton) +TEST_DECLARE (ip6_sin6_len) TEST_DECLARE (connect_unspecified) TEST_DECLARE (ipc_heavy_traffic_deadlock_bug) TEST_DECLARE (ipc_listen_before_write) @@ -159,6 +160,7 @@ TEST_DECLARE (udp_alloc_cb_fail) TEST_DECLARE (udp_bind) TEST_DECLARE (udp_bind_reuseaddr) TEST_DECLARE (udp_connect) +TEST_DECLARE (udp_connect6) TEST_DECLARE (udp_create_early) TEST_DECLARE (udp_create_early_bad_bind) TEST_DECLARE (udp_create_early_bad_domain) @@ -390,6 +392,7 @@ TEST_DECLARE (fs_event_close_in_callback) TEST_DECLARE (fs_event_start_and_close) TEST_DECLARE (fs_event_error_reporting) TEST_DECLARE (fs_event_getpath) +TEST_DECLARE (fs_event_stop_in_cb) TEST_DECLARE (fs_scandir_empty_dir) TEST_DECLARE (fs_scandir_non_existent_dir) TEST_DECLARE (fs_scandir_file) @@ -458,6 +461,7 @@ TEST_DECLARE (poll_multiple_handles) TEST_DECLARE (ip4_addr) TEST_DECLARE (ip6_addr_link_local) +TEST_DECLARE (ip_name) TEST_DECLARE (poll_close_doesnt_corrupt_stack) TEST_DECLARE (poll_closesocket) @@ -507,7 +511,7 @@ TEST_DECLARE (getters_setters) TEST_DECLARE (not_writable_after_shutdown) TEST_DECLARE (not_readable_nor_writable_on_read_error) -TEST_DECLARE (not_readable_on_eof) +TEST_DECLARE (readable_on_eof) #ifndef _WIN32 TEST_DECLARE (fork_timer) @@ -610,6 +614,7 @@ TASK_LIST_START TEST_ENTRY (stdio_over_pipes) TEST_ENTRY (stdio_emulate_iocp) TEST_ENTRY (ip6_pton) + TEST_ENTRY (ip6_sin6_len) TEST_ENTRY (connect_unspecified) TEST_ENTRY (ipc_heavy_traffic_deadlock_bug) TEST_ENTRY (ipc_listen_before_write) @@ -733,6 +738,7 @@ TASK_LIST_START TEST_ENTRY (udp_bind) TEST_ENTRY (udp_bind_reuseaddr) TEST_ENTRY (udp_connect) + TEST_ENTRY (udp_connect6) TEST_ENTRY (udp_create_early) TEST_ENTRY (udp_create_early_bad_bind) TEST_ENTRY (udp_create_early_bad_domain) @@ -1050,6 +1056,7 @@ TASK_LIST_START TEST_ENTRY (fs_event_start_and_close) TEST_ENTRY_CUSTOM (fs_event_error_reporting, 0, 0, 60000) TEST_ENTRY (fs_event_getpath) + TEST_ENTRY (fs_event_stop_in_cb) TEST_ENTRY (fs_scandir_empty_dir) TEST_ENTRY (fs_scandir_non_existent_dir) TEST_ENTRY (fs_scandir_file) @@ -1102,6 +1109,7 @@ TASK_LIST_START TEST_ENTRY (dlerror) TEST_ENTRY (ip4_addr) TEST_ENTRY (ip6_addr_link_local) + TEST_ENTRY (ip_name) TEST_ENTRY (queue_foreach_delete) @@ -1141,8 +1149,8 @@ TASK_LIST_START TEST_HELPER (not_writable_after_shutdown, tcp4_echo_server) TEST_ENTRY (not_readable_nor_writable_on_read_error) TEST_HELPER (not_readable_nor_writable_on_read_error, tcp4_echo_server) - TEST_ENTRY (not_readable_on_eof) - TEST_HELPER (not_readable_on_eof, tcp4_echo_server) + TEST_ENTRY (readable_on_eof) + TEST_HELPER (readable_on_eof, tcp4_echo_server) TEST_ENTRY (metrics_idle_time) TEST_ENTRY (metrics_idle_time_thread) diff --git a/deps/uv/test/test-ping-pong.c b/deps/uv/test/test-ping-pong.c index 4a26e4dee1..c598587d11 100644 --- a/deps/uv/test/test-ping-pong.c +++ b/deps/uv/test/test-ping-pong.c @@ -84,6 +84,7 @@ static void pinger_on_close(uv_handle_t* handle) { static void pinger_after_write(uv_write_t* req, int status) { ASSERT_EQ(status, 0); + free(req->data); free(req); } @@ -110,6 +111,7 @@ static void pinger_write_ping(pinger_t* pinger) { req = malloc(sizeof(*req)); ASSERT_NOT_NULL(req); + req->data = NULL; ASSERT_EQ(0, uv_write(req, stream, bufs, nbufs, pinger_after_write)); puts("PING"); @@ -185,6 +187,7 @@ static void ponger_read_cb(uv_stream_t* stream, writebuf = uv_buf_init(buf->base, nread); req = malloc(sizeof(*req)); ASSERT_NOT_NULL(req); + req->data = buf->base; ASSERT_EQ(0, uv_write(req, stream, &writebuf, 1, pinger_after_write)); } diff --git a/deps/uv/test/test-pipe-connect-error.c b/deps/uv/test/test-pipe-connect-error.c index 30c270d9fc..0f1e2b1c1e 100644 --- a/deps/uv/test/test-pipe-connect-error.c +++ b/deps/uv/test/test-pipe-connect-error.c @@ -76,9 +76,6 @@ TEST_IMPL(pipe_connect_bad_name) { TEST_IMPL(pipe_connect_to_file) { -#if defined(__ASAN__) - RETURN_SKIP("Test does not currently work in ASAN"); -#endif const char* path = "test/fixtures/empty_file"; uv_pipe_t client; uv_connect_t req; diff --git a/deps/uv/test/test-not-readable-on-eof.c b/deps/uv/test/test-readable-on-eof.c index 2bb5f4eecc..68e8454247 100644 --- a/deps/uv/test/test-not-readable-on-eof.c +++ b/deps/uv/test/test-readable-on-eof.c @@ -35,7 +35,7 @@ static int close_cb_called; static void write_cb(uv_write_t* req, int status) { write_cb_called++; - ASSERT(status == 0); + ASSERT_EQ(status, 0); } static void alloc_cb(uv_handle_t* handle, @@ -51,12 +51,20 @@ static void close_cb(uv_handle_t* handle) { } static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { - read_cb_called++; - - ASSERT(nread == UV_EOF); - ASSERT(0 == uv_is_readable(handle)); + int r; - uv_close((uv_handle_t*) handle, close_cb); + ASSERT_EQ(nread, UV_EOF); + ASSERT_EQ(uv_is_readable(handle), 1); + ASSERT_EQ(uv_is_writable(handle), 1); + + if (++read_cb_called == 3) { + uv_close((uv_handle_t*) handle, close_cb); + ASSERT_EQ(uv_is_readable(handle), 0); + ASSERT_EQ(uv_is_writable(handle), 0); + } else { + r = uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb); + ASSERT_EQ(r, 0); + } } static void connect_cb(uv_connect_t* req, int status) { @@ -64,10 +72,9 @@ static void connect_cb(uv_connect_t* req, int status) { uv_buf_t close_me; connect_cb_called++; - ASSERT(status == 0); + ASSERT_EQ(status, 0); - r = uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb); - ASSERT(r == 0); + read_cb((uv_stream_t*) &tcp_client, UV_EOF, NULL); close_me = uv_buf_init(close_me_cmd, sizeof(close_me_cmd)); @@ -77,26 +84,27 @@ static void connect_cb(uv_connect_t* req, int status) { 1, write_cb); - ASSERT(r == 0); + ASSERT_EQ(r, 0); } -TEST_IMPL(not_readable_on_eof) { +TEST_IMPL(readable_on_eof) { struct sockaddr_in sa; - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa)); - ASSERT(0 == uv_loop_init(&loop)); - ASSERT(0 == uv_tcp_init(&loop, &tcp_client)); - - ASSERT(0 == uv_tcp_connect(&connect_req, - &tcp_client, - (const struct sockaddr*) &sa, - connect_cb)); - - ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); - - ASSERT(connect_cb_called == 1); - ASSERT(read_cb_called == 1); - ASSERT(write_cb_called == 1); - ASSERT(close_cb_called == 1); + ASSERT_EQ(uv_ip4_addr("127.0.0.1", TEST_PORT, &sa), 0); + ASSERT_EQ(uv_loop_init(&loop), 0); + ASSERT_EQ(uv_tcp_init(&loop, &tcp_client), 0); + + ASSERT_EQ(uv_tcp_connect(&connect_req, + &tcp_client, + (const struct sockaddr*) &sa, + connect_cb), + 0); + + ASSERT_EQ(uv_run(&loop, UV_RUN_DEFAULT), 0); + + ASSERT_EQ(connect_cb_called, 1); + ASSERT_EQ(read_cb_called, 3); + ASSERT_EQ(write_cb_called, 1); + ASSERT_EQ(close_cb_called, 1); MAKE_VALGRIND_HAPPY(); return 0; diff --git a/deps/uv/test/test-tcp-connect-timeout.c b/deps/uv/test/test-tcp-connect-timeout.c index 3c34e54ae7..0f96815712 100644 --- a/deps/uv/test/test-tcp-connect-timeout.c +++ b/deps/uv/test/test-tcp-connect-timeout.c @@ -111,7 +111,7 @@ static int is_supported_system(void) { if (cnt != 3) { return 0; } - /* relase >= 10.0.16299 */ + /* release >= 10.0.16299 */ for (cnt = 0; cnt < 3; ++cnt) { if (semver[cnt] > min_semver[cnt]) return 1; diff --git a/deps/uv/test/test-thread-equal.c b/deps/uv/test/test-thread-equal.c index 27c07ee2c7..f7bde71b3d 100644 --- a/deps/uv/test/test-thread-equal.c +++ b/deps/uv/test/test-thread-equal.c @@ -28,6 +28,9 @@ uv_thread_t subthreads[2]; static void check_thread(void* arg) { uv_thread_t *thread_id = arg; uv_thread_t self_id = uv_thread_self(); +#ifdef _WIN32 + ASSERT_NOT_NULL(self_id); +#endif ASSERT(uv_thread_equal(&main_thread_id, &self_id) == 0); *thread_id = uv_thread_self(); } @@ -35,6 +38,9 @@ static void check_thread(void* arg) { TEST_IMPL(thread_equal) { uv_thread_t threads[2]; main_thread_id = uv_thread_self(); +#ifdef _WIN32 + ASSERT_NOT_NULL(main_thread_id); +#endif ASSERT(0 != uv_thread_equal(&main_thread_id, &main_thread_id)); ASSERT(0 == uv_thread_create(threads + 0, check_thread, subthreads + 0)); ASSERT(0 == uv_thread_create(threads + 1, check_thread, subthreads + 1)); diff --git a/deps/uv/test/test-tty-escape-sequence-processing.c b/deps/uv/test/test-tty-escape-sequence-processing.c index ef34e5927c..5f04291d24 100644 --- a/deps/uv/test/test-tty-escape-sequence-processing.c +++ b/deps/uv/test/test-tty-escape-sequence-processing.c @@ -271,7 +271,7 @@ static void make_expect_screen_erase(struct captured_screen* cs, static void make_expect_screen_write(struct captured_screen* cs, COORD cursor_position, const char* text) { - /* postion of cursor */ + /* position of cursor */ char* start; start = cs->text + cs->si.width * (cursor_position.Y - 1) + cursor_position.X - 1; @@ -1070,6 +1070,11 @@ TEST_IMPL(tty_set_style) { WORD attr; int i, length; +#if _MSC_VER >= 1920 && _MSC_VER <= 1929 + RETURN_SKIP("Broken on Microsoft Visual Studio 2019, to be investigated. " + "See: https://github.com/libuv/libuv/issues/3304"); +#endif + loop = uv_default_loop(); initialize_tty(&tty_out); @@ -1261,7 +1266,7 @@ TEST_IMPL(tty_save_restore_cursor_position) { cursor_pos.Y = si.height / 4; set_cursor_position(&tty_out, cursor_pos); - /* restore the cursor postion */ + /* restore the cursor position */ snprintf(buffer, sizeof(buffer), "%su", CSI); write_console(&tty_out, buffer); get_cursor_position(&tty_out, &cursor_pos); @@ -1280,7 +1285,7 @@ TEST_IMPL(tty_save_restore_cursor_position) { cursor_pos.Y = si.height / 4; set_cursor_position(&tty_out, cursor_pos); - /* restore the cursor postion */ + /* restore the cursor position */ snprintf(buffer, sizeof(buffer), "%s8", ESC); write_console(&tty_out, buffer); get_cursor_position(&tty_out, &cursor_pos); @@ -1348,6 +1353,11 @@ TEST_IMPL(tty_escape_sequence_processing) { struct captured_screen actual = {0}, expect = {0}; int dir; +#if _MSC_VER >= 1920 && _MSC_VER <= 1929 + RETURN_SKIP("Broken on Microsoft Visual Studio 2019, to be investigated. " + "See: https://github.com/libuv/libuv/issues/3304"); +#endif + loop = uv_default_loop(); initialize_tty(&tty_out); diff --git a/deps/uv/test/test-udp-connect.c b/deps/uv/test/test-udp-connect.c index 89ca1a84fc..cd159b68da 100644 --- a/deps/uv/test/test-udp-connect.c +++ b/deps/uv/test/test-udp-connect.c @@ -124,7 +124,7 @@ TEST_IMPL(udp_connect) { buf = uv_buf_init("EXIT", 4); - /* connect() to INADDR_ANY fails on Windows wih WSAEADDRNOTAVAIL */ + /* connect() to INADDR_ANY fails on Windows with WSAEADDRNOTAVAIL */ ASSERT_EQ(0, uv_ip4_addr("0.0.0.0", TEST_PORT, &tmp_addr)); r = uv_udp_connect(&client, (const struct sockaddr*) &tmp_addr); #ifdef _WIN32 diff --git a/deps/uv/test/test-udp-connect6.c b/deps/uv/test/test-udp-connect6.c new file mode 100644 index 0000000000..8e385af99b --- /dev/null +++ b/deps/uv/test/test-udp-connect6.c @@ -0,0 +1,200 @@ +/* Copyright libuv project and contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) + +static uv_udp_t server; +static uv_udp_t client; +static uv_buf_t buf; +static struct sockaddr_in6 lo_addr; + +static int cl_send_cb_called; +static int sv_recv_cb_called; + +static int close_cb_called; + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + CHECK_HANDLE(handle); + ASSERT_LE(suggested_size, sizeof(slab)); + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void close_cb(uv_handle_t* handle) { + CHECK_HANDLE(handle); + ASSERT(uv_is_closing(handle)); + close_cb_called++; +} + + +static void cl_send_cb(uv_udp_send_t* req, int status) { + int r; + + ASSERT_NOT_NULL(req); + ASSERT_EQ(status, 0); + CHECK_HANDLE(req->handle); + if (++cl_send_cb_called == 1) { + uv_udp_connect(&client, NULL); + r = uv_udp_send(req, &client, &buf, 1, NULL, cl_send_cb); + ASSERT_EQ(r, UV_EDESTADDRREQ); + r = uv_udp_send(req, + &client, + &buf, + 1, + (const struct sockaddr*) &lo_addr, + cl_send_cb); + ASSERT_EQ(r, 0); + } + +} + + +static void sv_recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* rcvbuf, + const struct sockaddr* addr, + unsigned flags) { + if (nread > 0) { + ASSERT_EQ(nread, 4); + ASSERT_NOT_NULL(addr); + ASSERT_EQ(memcmp("EXIT", rcvbuf->base, nread), 0); + if (++sv_recv_cb_called == 4) { + uv_close((uv_handle_t*) &server, close_cb); + uv_close((uv_handle_t*) &client, close_cb); + } + } +} + + +TEST_IMPL(udp_connect6) { +#if defined(__PASE__) + RETURN_SKIP( + "IBMi PASE's UDP connection can not be disconnected with AF_UNSPEC."); +#endif + uv_udp_send_t req; + struct sockaddr_in6 ext_addr; + struct sockaddr_in6 tmp_addr; + int r; + int addrlen; + + if (!can_ipv6()) + RETURN_SKIP("IPv6 not supported"); + + ASSERT_EQ(0, uv_ip6_addr("::", TEST_PORT, &lo_addr)); + + r = uv_udp_init(uv_default_loop(), &server); + ASSERT_EQ(r, 0); + + r = uv_udp_bind(&server, (const struct sockaddr*) &lo_addr, 0); + ASSERT_EQ(r, 0); + + r = uv_udp_recv_start(&server, alloc_cb, sv_recv_cb); + ASSERT_EQ(r, 0); + + r = uv_udp_init(uv_default_loop(), &client); + ASSERT_EQ(r, 0); + + buf = uv_buf_init("EXIT", 4); + + /* connect() to INADDR_ANY fails on Windows wih WSAEADDRNOTAVAIL */ + ASSERT_EQ(0, uv_ip6_addr("::", TEST_PORT, &tmp_addr)); + r = uv_udp_connect(&client, (const struct sockaddr*) &tmp_addr); +#ifdef _WIN32 + ASSERT_EQ(r, UV_EADDRNOTAVAIL); +#else + ASSERT_EQ(r, 0); + r = uv_udp_connect(&client, NULL); + ASSERT_EQ(r, 0); +#endif + + ASSERT_EQ(0, uv_ip6_addr("2001:4860:4860::8888", TEST_PORT, &ext_addr)); + ASSERT_EQ(0, uv_ip6_addr("::1", TEST_PORT, &lo_addr)); + + r = uv_udp_connect(&client, (const struct sockaddr*) &lo_addr); + ASSERT_EQ(r, 0); + r = uv_udp_connect(&client, (const struct sockaddr*) &ext_addr); + ASSERT_EQ(r, UV_EISCONN); + + addrlen = sizeof(tmp_addr); + r = uv_udp_getpeername(&client, (struct sockaddr*) &tmp_addr, &addrlen); + ASSERT_EQ(r, 0); + + /* To send messages in connected UDP sockets addr must be NULL */ + r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &lo_addr); + ASSERT_EQ(r, UV_EISCONN); + r = uv_udp_try_send(&client, &buf, 1, NULL); + ASSERT_EQ(r, 4); + r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &ext_addr); + ASSERT_EQ(r, UV_EISCONN); + + r = uv_udp_connect(&client, NULL); + ASSERT_EQ(r, 0); + r = uv_udp_connect(&client, NULL); + ASSERT_EQ(r, UV_ENOTCONN); + + addrlen = sizeof(tmp_addr); + r = uv_udp_getpeername(&client, (struct sockaddr*) &tmp_addr, &addrlen); + ASSERT_EQ(r, UV_ENOTCONN); + + /* To send messages in disconnected UDP sockets addr must be set */ + r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &lo_addr); + ASSERT_EQ(r, 4); + r = uv_udp_try_send(&client, &buf, 1, NULL); + ASSERT_EQ(r, UV_EDESTADDRREQ); + + + r = uv_udp_connect(&client, (const struct sockaddr*) &lo_addr); + ASSERT_EQ(r, 0); + r = uv_udp_send(&req, + &client, + &buf, + 1, + (const struct sockaddr*) &lo_addr, + cl_send_cb); + ASSERT_EQ(r, UV_EISCONN); + r = uv_udp_send(&req, &client, &buf, 1, NULL, cl_send_cb); + ASSERT_EQ(r, 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT_EQ(close_cb_called, 2); + ASSERT_EQ(sv_recv_cb_called, 4); + ASSERT_EQ(cl_send_cb_called, 2); + + ASSERT_EQ(client.send_queue_size, 0); + ASSERT_EQ(server.send_queue_size, 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} |