summaryrefslogtreecommitdiff
path: root/deps/uv/test
diff options
context:
space:
mode:
authorcjihrig <cjihrig@gmail.com>2019-09-09 13:08:37 -0400
committerRich Trott <rtrott@gmail.com>2019-09-12 00:49:02 -0700
commitdf0e2e3625d1f72e8b04e05ffa13997a51e9f0d7 (patch)
tree5ef978de762b47bcfc6323c48e7e22b862d6d657 /deps/uv/test
parent62e8cc5e61a36ebe1bd913983a452961aa1c9946 (diff)
downloadandroid-node-v8-df0e2e3625d1f72e8b04e05ffa13997a51e9f0d7.tar.gz
android-node-v8-df0e2e3625d1f72e8b04e05ffa13997a51e9f0d7.tar.bz2
android-node-v8-df0e2e3625d1f72e8b04e05ffa13997a51e9f0d7.zip
deps: upgrade to libuv 1.32.0
Notable changes: - `uv_tcp_close_reset()` has been added. - `uv_udp_set_source_membership()` has been added. - A double free in `uv_free_cpu_info()` on OpenBSD has been fixed. - Defined, but empty environment variables can now be read on Windows. - Several improvements to the cmake build process. - The `EILSEQ` error code is now mapped by libuv. PR-URL: https://github.com/nodejs/node/pull/29508 Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Beth Griggs <Bethany.Griggs@uk.ibm.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'deps/uv/test')
-rw-r--r--deps/uv/test/test-env-vars.c9
-rw-r--r--deps/uv/test/test-fs.c2
-rw-r--r--deps/uv/test/test-list.h12
-rw-r--r--deps/uv/test/test-signal-pending-on-close.c94
-rw-r--r--deps/uv/test/test-spawn.c2
-rw-r--r--deps/uv/test/test-tcp-bind-error.c4
-rw-r--r--deps/uv/test/test-tcp-close-reset.c290
-rw-r--r--deps/uv/test/test-timer.c13
-rw-r--r--deps/uv/test/test-udp-multicast-join.c74
-rw-r--r--deps/uv/test/test-udp-multicast-join6.c118
-rw-r--r--deps/uv/test/test.gyp2
11 files changed, 558 insertions, 62 deletions
diff --git a/deps/uv/test/test-env-vars.c b/deps/uv/test/test-env-vars.c
index d7abb42495..3814699356 100644
--- a/deps/uv/test/test-env-vars.c
+++ b/deps/uv/test/test-env-vars.c
@@ -88,6 +88,15 @@ TEST_IMPL(env_vars) {
r = uv_os_unsetenv(name);
ASSERT(r == 0);
+ /* Setting an environment variable to the empty string does not delete it. */
+ r = uv_os_setenv(name, "");
+ ASSERT(r == 0);
+ size = BUF_SIZE;
+ r = uv_os_getenv(name, buf, &size);
+ ASSERT(r == 0);
+ ASSERT(size == 0);
+ ASSERT(strlen(buf) == 0);
+
/* Check getting all env variables. */
r = uv_os_setenv(name, "123456789");
ASSERT(r == 0);
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index 0d92b0d3a0..9326c6bc27 100644
--- a/deps/uv/test/test-fs.c
+++ b/deps/uv/test/test-fs.c
@@ -354,7 +354,7 @@ static void statfs_cb(uv_fs_t* req) {
ASSERT(stats->f_files == 0);
ASSERT(stats->f_ffree == 0);
#else
- ASSERT(stats->f_files > 0);
+ /* There is no assertion for stats->f_files that makes sense, so ignore it. */
ASSERT(stats->f_ffree <= stats->f_files);
#endif
uv_fs_req_cleanup(req);
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index 6eb8ecadc7..b6066f2727 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -112,6 +112,10 @@ TEST_DECLARE (tcp_connect_error_fault)
TEST_DECLARE (tcp_connect_timeout)
TEST_DECLARE (tcp_close_while_connecting)
TEST_DECLARE (tcp_close)
+TEST_DECLARE (tcp_close_reset_accepted)
+TEST_DECLARE (tcp_close_reset_accepted_after_shutdown)
+TEST_DECLARE (tcp_close_reset_client)
+TEST_DECLARE (tcp_close_reset_client_after_shutdown)
TEST_DECLARE (tcp_create_early)
TEST_DECLARE (tcp_create_early_bad_bind)
TEST_DECLARE (tcp_create_early_bad_domain)
@@ -193,6 +197,7 @@ TEST_DECLARE (timer_huge_timeout)
TEST_DECLARE (timer_huge_repeat)
TEST_DECLARE (timer_run_once)
TEST_DECLARE (timer_from_check)
+TEST_DECLARE (timer_is_closing)
TEST_DECLARE (timer_null_callback)
TEST_DECLARE (timer_early_check)
TEST_DECLARE (idle_starvation)
@@ -445,6 +450,7 @@ TEST_DECLARE (we_get_signals)
TEST_DECLARE (we_get_signal_one_shot)
TEST_DECLARE (we_get_signals_mixed)
TEST_DECLARE (signal_multiple_loops)
+TEST_DECLARE (signal_pending_on_close)
TEST_DECLARE (closed_fd_events)
#endif
#ifdef __APPLE__
@@ -623,6 +629,10 @@ TASK_LIST_START
TEST_ENTRY (tcp_connect_timeout)
TEST_ENTRY (tcp_close_while_connecting)
TEST_ENTRY (tcp_close)
+ TEST_ENTRY (tcp_close_reset_accepted)
+ TEST_ENTRY (tcp_close_reset_accepted_after_shutdown)
+ TEST_ENTRY (tcp_close_reset_client)
+ TEST_ENTRY (tcp_close_reset_client_after_shutdown)
TEST_ENTRY (tcp_create_early)
TEST_ENTRY (tcp_create_early_bad_bind)
TEST_ENTRY (tcp_create_early_bad_domain)
@@ -720,6 +730,7 @@ TASK_LIST_START
TEST_ENTRY (timer_huge_repeat)
TEST_ENTRY (timer_run_once)
TEST_ENTRY (timer_from_check)
+ TEST_ENTRY (timer_is_closing)
TEST_ENTRY (timer_null_callback)
TEST_ENTRY (timer_early_check)
@@ -886,6 +897,7 @@ TASK_LIST_START
TEST_ENTRY (we_get_signal_one_shot)
TEST_ENTRY (we_get_signals_mixed)
TEST_ENTRY (signal_multiple_loops)
+ TEST_ENTRY (signal_pending_on_close)
TEST_ENTRY (closed_fd_events)
#endif
diff --git a/deps/uv/test/test-signal-pending-on-close.c b/deps/uv/test/test-signal-pending-on-close.c
new file mode 100644
index 0000000000..bf8d2793d5
--- /dev/null
+++ b/deps/uv/test/test-signal-pending-on-close.c
@@ -0,0 +1,94 @@
+/* Copyright libuv project 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.
+*/
+#ifndef _WIN32
+
+#include "uv.h"
+#include "task.h"
+
+#include <string.h>
+#include <unistd.h>
+
+static uv_loop_t loop;
+static uv_signal_t signal_hdl;
+static uv_pipe_t pipe_hdl;
+static uv_write_t write_req;
+static char* buf;
+static int close_cb_called;
+
+
+static void signal_cb(uv_signal_t* signal, int signum) {
+ ASSERT(0);
+}
+
+static void close_cb(uv_handle_t *handle) {
+ close_cb_called++;
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(req != NULL);
+ ASSERT(status == UV_EPIPE);
+ free(buf);
+ uv_close((uv_handle_t *) &pipe_hdl, close_cb);
+ uv_close((uv_handle_t *) &signal_hdl, close_cb);
+}
+
+
+TEST_IMPL(signal_pending_on_close) {
+ int pipefds[2];
+ uv_buf_t buffer;
+ int r;
+
+ ASSERT(0 == uv_loop_init(&loop));
+
+ ASSERT(0 == uv_signal_init(&loop, &signal_hdl));
+
+ ASSERT(0 == uv_signal_start(&signal_hdl, signal_cb, SIGPIPE));
+
+ ASSERT(0 == pipe(pipefds));
+
+ ASSERT(0 == uv_pipe_init(&loop, &pipe_hdl, 0));
+
+ ASSERT(0 == uv_pipe_open(&pipe_hdl, pipefds[1]));
+
+ /* Write data large enough so it needs loop iteration */
+ buf = malloc(1<<24);
+ ASSERT(buf != NULL);
+ memset(buf, '.', 1<<24);
+ buffer = uv_buf_init(buf, 1<<24);
+
+ r = uv_write(&write_req, (uv_stream_t *) &pipe_hdl, &buffer, 1, write_cb);
+ ASSERT(0 == r);
+
+ /* cause a SIGPIPE on write in next iteration */
+ close(pipefds[0]);
+
+ ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT));
+
+ ASSERT(0 == uv_loop_close(&loop));
+
+ ASSERT(2 == close_cb_called);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#endif \ No newline at end of file
diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c
index fec610bfde..be9e2539aa 100644
--- a/deps/uv/test/test-spawn.c
+++ b/deps/uv/test/test-spawn.c
@@ -240,7 +240,7 @@ TEST_IMPL(spawn_empty_env) {
* in the environment, but of course that doesn't work with
* the empty environment that we're testing here.
*/
- if (NULL != getenv("DYLD_LIBARY_PATH") ||
+ if (NULL != getenv("DYLD_LIBRARY_PATH") ||
NULL != getenv("LD_LIBRARY_PATH")) {
RETURN_SKIP("doesn't work with DYLD_LIBRARY_PATH/LD_LIBRARY_PATH");
}
diff --git a/deps/uv/test/test-tcp-bind-error.c b/deps/uv/test/test-tcp-bind-error.c
index 1456d081ae..f95efd9f0c 100644
--- a/deps/uv/test/test-tcp-bind-error.c
+++ b/deps/uv/test/test-tcp-bind-error.c
@@ -239,11 +239,7 @@ TEST_IMPL(tcp_bind_writable_flags) {
r = uv_write(&write_req, (uv_stream_t*) &server, &buf, 1, NULL);
ASSERT(r == UV_EPIPE);
r = uv_shutdown(&shutdown_req, (uv_stream_t*) &server, NULL);
-#ifdef _WIN32
- ASSERT(r == UV_EPIPE);
-#else
ASSERT(r == UV_ENOTCONN);
-#endif
r = uv_read_start((uv_stream_t*) &server, NULL, NULL);
ASSERT(r == UV_ENOTCONN);
diff --git a/deps/uv/test/test-tcp-close-reset.c b/deps/uv/test/test-tcp-close-reset.c
new file mode 100644
index 0000000000..7ca55c4c7f
--- /dev/null
+++ b/deps/uv/test/test-tcp-close-reset.c
@@ -0,0 +1,290 @@
+/* Copyright libuv project 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 <errno.h>
+#include <string.h> /* memset */
+
+static uv_loop_t* loop;
+static uv_tcp_t tcp_server;
+static uv_tcp_t tcp_client;
+static uv_tcp_t tcp_accepted;
+static uv_connect_t connect_req;
+static uv_shutdown_t shutdown_req;
+static uv_write_t write_reqs[4];
+
+static int client_close;
+static int shutdown_before_close;
+
+static int write_cb_called;
+static int close_cb_called;
+static int shutdown_cb_called;
+
+static void connect_cb(uv_connect_t* req, int status);
+static void write_cb(uv_write_t* req, int status);
+static void close_cb(uv_handle_t* handle);
+static void shutdown_cb(uv_shutdown_t* req, int status);
+
+static int read_size;
+
+
+static void do_write(uv_tcp_t* handle) {
+ uv_buf_t buf;
+ unsigned i;
+ int r;
+
+ buf = uv_buf_init("PING", 4);
+ for (i = 0; i < ARRAY_SIZE(write_reqs); i++) {
+ r = uv_write(&write_reqs[i], (uv_stream_t*) handle, &buf, 1, write_cb);
+ ASSERT(r == 0);
+ }
+}
+
+
+static void do_close(uv_tcp_t* handle) {
+ if (shutdown_before_close == 1) {
+ ASSERT(0 == uv_shutdown(&shutdown_req, (uv_stream_t*) handle, shutdown_cb));
+ ASSERT(UV_EINVAL == uv_tcp_close_reset(handle, close_cb));
+ } else {
+ ASSERT(0 == uv_tcp_close_reset(handle, close_cb));
+ ASSERT(UV_ENOTCONN == uv_shutdown(&shutdown_req, (uv_stream_t*) handle, shutdown_cb));
+ }
+
+ uv_close((uv_handle_t*) &tcp_server, NULL);
+}
+
+static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+ static char slab[1024];
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+static void read_cb2(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
+ ASSERT((uv_tcp_t*)stream == &tcp_client);
+ if (nread == UV_EOF)
+ uv_close((uv_handle_t*) stream, NULL);
+}
+
+
+static void connect_cb(uv_connect_t* conn_req, int status) {
+ ASSERT(conn_req == &connect_req);
+ uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb2);
+ do_write(&tcp_client);
+ if (client_close)
+ do_close(&tcp_client);
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ /* write callbacks should run before the close callback */
+ ASSERT(close_cb_called == 0);
+ ASSERT(req->handle == (uv_stream_t*)&tcp_client);
+ write_cb_called++;
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ if (client_close)
+ ASSERT(handle == (uv_handle_t*) &tcp_client);
+ else
+ ASSERT(handle == (uv_handle_t*) &tcp_accepted);
+
+ close_cb_called++;
+}
+
+static void shutdown_cb(uv_shutdown_t* req, int status) {
+ if (client_close)
+ ASSERT(req->handle == (uv_stream_t*) &tcp_client);
+ else
+ ASSERT(req->handle == (uv_stream_t*) &tcp_accepted);
+
+ shutdown_cb_called++;
+}
+
+
+static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
+ ASSERT((uv_tcp_t*)stream == &tcp_accepted);
+ if (nread < 0) {
+ uv_close((uv_handle_t*) stream, NULL);
+ } else {
+ read_size += nread;
+ if (read_size == 16 && client_close == 0)
+ do_close(&tcp_accepted);
+ }
+}
+
+
+static void connection_cb(uv_stream_t* server, int status) {
+ ASSERT(status == 0);
+
+ ASSERT(0 == uv_tcp_init(loop, &tcp_accepted));
+ ASSERT(0 == uv_accept(server, (uv_stream_t*) &tcp_accepted));
+
+ uv_read_start((uv_stream_t*) &tcp_accepted, alloc_cb, read_cb);
+}
+
+
+static void start_server(uv_loop_t* loop, uv_tcp_t* handle) {
+ struct sockaddr_in addr;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_tcp_init(loop, handle);
+ ASSERT(r == 0);
+
+ r = uv_tcp_bind(handle, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*)handle, 128, connection_cb);
+ ASSERT(r == 0);
+}
+
+
+static void do_connect(uv_loop_t* loop, uv_tcp_t* tcp_client) {
+ struct sockaddr_in addr;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_tcp_init(loop, tcp_client);
+ ASSERT(r == 0);
+
+ r = uv_tcp_connect(&connect_req,
+ tcp_client,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ ASSERT(r == 0);
+}
+
+
+/* Check that pending write requests have their callbacks
+ * invoked when the handle is closed.
+ */
+TEST_IMPL(tcp_close_reset_client) {
+ int r;
+
+ loop = uv_default_loop();
+
+ start_server(loop, &tcp_server);
+
+ client_close = 1;
+ shutdown_before_close = 0;
+
+ do_connect(loop, &tcp_client);
+
+ ASSERT(write_cb_called == 0);
+ ASSERT(close_cb_called == 0);
+ ASSERT(shutdown_cb_called == 0);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(write_cb_called == 4);
+ ASSERT(close_cb_called == 1);
+ ASSERT(shutdown_cb_called == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+TEST_IMPL(tcp_close_reset_client_after_shutdown) {
+ int r;
+
+ loop = uv_default_loop();
+
+ start_server(loop, &tcp_server);
+
+ client_close = 1;
+ shutdown_before_close = 1;
+
+ do_connect(loop, &tcp_client);
+
+ ASSERT(write_cb_called == 0);
+ ASSERT(close_cb_called == 0);
+ ASSERT(shutdown_cb_called == 0);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(write_cb_called == 4);
+ ASSERT(close_cb_called == 0);
+ ASSERT(shutdown_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+TEST_IMPL(tcp_close_reset_accepted) {
+ int r;
+
+ loop = uv_default_loop();
+
+ start_server(loop, &tcp_server);
+
+ client_close = 0;
+ shutdown_before_close = 0;
+
+ do_connect(loop, &tcp_client);
+
+ ASSERT(write_cb_called == 0);
+ ASSERT(close_cb_called == 0);
+ ASSERT(shutdown_cb_called == 0);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(write_cb_called == 4);
+ ASSERT(close_cb_called == 1);
+ ASSERT(shutdown_cb_called == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+TEST_IMPL(tcp_close_reset_accepted_after_shutdown) {
+ int r;
+
+ loop = uv_default_loop();
+
+ start_server(loop, &tcp_server);
+
+ client_close = 0;
+ shutdown_before_close = 1;
+
+ do_connect(loop, &tcp_client);
+
+ ASSERT(write_cb_called == 0);
+ ASSERT(close_cb_called == 0);
+ ASSERT(shutdown_cb_called == 0);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(write_cb_called == 4);
+ ASSERT(close_cb_called == 0);
+ ASSERT(shutdown_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-timer.c b/deps/uv/test/test-timer.c
index 080a73005e..c667da00ec 100644
--- a/deps/uv/test/test-timer.c
+++ b/deps/uv/test/test-timer.c
@@ -292,6 +292,19 @@ TEST_IMPL(timer_run_once) {
}
+TEST_IMPL(timer_is_closing) {
+ uv_timer_t handle;
+
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
+ uv_close((uv_handle_t *)&handle, NULL);
+
+ ASSERT(UV_EINVAL == uv_timer_start(&handle, never_cb, 100, 100));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
TEST_IMPL(timer_null_callback) {
uv_timer_t handle;
diff --git a/deps/uv/test/test-udp-multicast-join.c b/deps/uv/test/test-udp-multicast-join.c
index 053d2f7914..9ee80e44e7 100644
--- a/deps/uv/test/test-udp-multicast-join.c
+++ b/deps/uv/test/test-udp-multicast-join.c
@@ -29,8 +29,12 @@
#define CHECK_HANDLE(handle) \
ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client)
+#define MULTICAST_ADDR "239.255.0.1"
+
static uv_udp_t server;
static uv_udp_t client;
+static uv_udp_send_t req;
+static uv_udp_send_t req_ss;
static int cl_recv_cb_called;
@@ -62,7 +66,26 @@ static void sv_send_cb(uv_udp_send_t* req, int status) {
sv_send_cb_called++;
- uv_close((uv_handle_t*) req->handle, close_cb);
+ if (sv_send_cb_called == 2)
+ uv_close((uv_handle_t*) req->handle, close_cb);
+}
+
+
+static int do_send(uv_udp_send_t* send_req) {
+ uv_buf_t buf;
+ struct sockaddr_in addr;
+
+ buf = uv_buf_init("PING", 4);
+
+ ASSERT(0 == uv_ip4_addr(MULTICAST_ADDR, TEST_PORT, &addr));
+
+ /* client sends "PING" */
+ return uv_udp_send(send_req,
+ &client,
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ sv_send_cb);
}
@@ -74,8 +97,6 @@ static void cl_recv_cb(uv_udp_t* handle,
CHECK_HANDLE(handle);
ASSERT(flags == 0);
- cl_recv_cb_called++;
-
if (nread < 0) {
ASSERT(0 && "unexpected error");
}
@@ -90,18 +111,35 @@ static void cl_recv_cb(uv_udp_t* handle,
ASSERT(nread == 4);
ASSERT(!memcmp("PING", buf->base, nread));
- /* we are done with the client handle, we can close it */
- uv_close((uv_handle_t*) &client, close_cb);
+ cl_recv_cb_called++;
+
+ if (cl_recv_cb_called == 2) {
+ /* we are done with the server handle, we can close it */
+ uv_close((uv_handle_t*) &server, close_cb);
+ } else {
+ int r;
+ char source_addr[64];
+
+ r = uv_ip4_name((const struct sockaddr_in*)addr, source_addr, sizeof(source_addr));
+ ASSERT(r == 0);
+
+ r = uv_udp_set_membership(&server, MULTICAST_ADDR, NULL, UV_LEAVE_GROUP);
+ ASSERT(r == 0);
+
+ r = uv_udp_set_source_membership(&server, MULTICAST_ADDR, NULL, source_addr, UV_JOIN_GROUP);
+ ASSERT(r == 0);
+
+ r = do_send(&req_ss);
+ ASSERT(r == 0);
+ }
}
TEST_IMPL(udp_multicast_join) {
int r;
- uv_udp_send_t req;
- uv_buf_t buf;
struct sockaddr_in addr;
- ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
r = uv_udp_init(uv_default_loop(), &server);
ASSERT(r == 0);
@@ -110,27 +148,19 @@ TEST_IMPL(udp_multicast_join) {
ASSERT(r == 0);
/* bind to the desired port */
- r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0);
+ r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
/* join the multicast channel */
- r = uv_udp_set_membership(&client, "239.255.0.1", NULL, UV_JOIN_GROUP);
+ r = uv_udp_set_membership(&server, MULTICAST_ADDR, NULL, UV_JOIN_GROUP);
if (r == UV_ENODEV)
RETURN_SKIP("No multicast support.");
ASSERT(r == 0);
- r = uv_udp_recv_start(&client, alloc_cb, cl_recv_cb);
+ r = uv_udp_recv_start(&server, alloc_cb, cl_recv_cb);
ASSERT(r == 0);
- buf = uv_buf_init("PING", 4);
-
- /* server sends "PING" */
- r = uv_udp_send(&req,
- &server,
- &buf,
- 1,
- (const struct sockaddr*) &addr,
- sv_send_cb);
+ r = do_send(&req);
ASSERT(r == 0);
ASSERT(close_cb_called == 0);
@@ -140,8 +170,8 @@ TEST_IMPL(udp_multicast_join) {
/* run the loop till all events are processed */
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
- ASSERT(cl_recv_cb_called == 1);
- ASSERT(sv_send_cb_called == 1);
+ ASSERT(cl_recv_cb_called == 2);
+ ASSERT(sv_send_cb_called == 2);
ASSERT(close_cb_called == 2);
MAKE_VALGRIND_HAPPY();
diff --git a/deps/uv/test/test-udp-multicast-join6.c b/deps/uv/test/test-udp-multicast-join6.c
index bda5e20ea7..edcd371b2c 100644
--- a/deps/uv/test/test-udp-multicast-join6.c
+++ b/deps/uv/test/test-udp-multicast-join6.c
@@ -30,8 +30,23 @@
#define CHECK_HANDLE(handle) \
ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client)
+#if defined(__APPLE__) || \
+ defined(_AIX) || \
+ defined(__MVS__) || \
+ defined(__FreeBSD_kernel__) || \
+ defined(__NetBSD__) || \
+ defined(__OpenBSD__)
+ #define MULTICAST_ADDR "ff02::1%lo0"
+ #define INTERFACE_ADDR "::1%lo0"
+#else
+ #define MULTICAST_ADDR "ff02::1"
+ #define INTERFACE_ADDR NULL
+#endif
+
static uv_udp_t server;
static uv_udp_t client;
+static uv_udp_send_t req;
+static uv_udp_send_t req_ss;
static int cl_recv_cb_called;
@@ -63,7 +78,26 @@ static void sv_send_cb(uv_udp_send_t* req, int status) {
sv_send_cb_called++;
- uv_close((uv_handle_t*) req->handle, close_cb);
+ if (sv_send_cb_called == 2)
+ uv_close((uv_handle_t*) req->handle, close_cb);
+}
+
+
+static int do_send(uv_udp_send_t* send_req) {
+ uv_buf_t buf;
+ struct sockaddr_in6 addr;
+
+ buf = uv_buf_init("PING", 4);
+
+ ASSERT(0 == uv_ip6_addr(MULTICAST_ADDR, TEST_PORT, &addr));
+
+ /* client sends "PING" */
+ return uv_udp_send(send_req,
+ &client,
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ sv_send_cb);
}
@@ -75,8 +109,6 @@ static void cl_recv_cb(uv_udp_t* handle,
CHECK_HANDLE(handle);
ASSERT(flags == 0);
- cl_recv_cb_called++;
-
if (nread < 0) {
ASSERT(0 && "unexpected error");
}
@@ -91,21 +123,57 @@ static void cl_recv_cb(uv_udp_t* handle,
ASSERT(nread == 4);
ASSERT(!memcmp("PING", buf->base, nread));
- /* we are done with the client handle, we can close it */
- uv_close((uv_handle_t*) &client, close_cb);
+ cl_recv_cb_called++;
+
+ if (cl_recv_cb_called == 2) {
+ /* we are done with the server handle, we can close it */
+ uv_close((uv_handle_t*) &server, close_cb);
+ } else {
+ int r;
+ char source_addr[64];
+
+ r = uv_ip6_name((const struct sockaddr_in6*)addr, source_addr, sizeof(source_addr));
+ ASSERT(r == 0);
+
+ r = uv_udp_set_membership(&server, MULTICAST_ADDR, INTERFACE_ADDR, UV_LEAVE_GROUP);
+ ASSERT(r == 0);
+
+ r = uv_udp_set_source_membership(&server, MULTICAST_ADDR, INTERFACE_ADDR, source_addr, UV_JOIN_GROUP);
+ ASSERT(r == 0);
+
+ r = do_send(&req_ss);
+ ASSERT(r == 0);
+ }
+}
+
+
+static int can_ipv6_external(void) {
+ uv_interface_address_t* addr;
+ int supported;
+ int count;
+ int i;
+
+ if (uv_interface_addresses(&addr, &count))
+ return 0; /* Assume no IPv6 support on failure. */
+
+ supported = 0;
+ for (i = 0; supported == 0 && i < count; i += 1)
+ supported = (AF_INET6 == addr[i].address.address6.sin6_family &&
+ !addr[i].is_internal);
+
+ uv_free_interface_addresses(addr, count);
+ return supported;
}
TEST_IMPL(udp_multicast_join6) {
int r;
- uv_udp_send_t req;
- uv_buf_t buf;
struct sockaddr_in6 addr;
- if (!can_ipv6())
- RETURN_SKIP("IPv6 not supported");
+ if (!can_ipv6_external())
+ RETURN_SKIP("No external IPv6 interface available");
- ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr));
+ ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr));
r = uv_udp_init(uv_default_loop(), &server);
ASSERT(r == 0);
@@ -114,20 +182,10 @@ TEST_IMPL(udp_multicast_join6) {
ASSERT(r == 0);
/* bind to the desired port */
- r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0);
+ r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
- /* join the multicast channel */
-#if defined(__APPLE__) || \
- defined(_AIX) || \
- defined(__MVS__) || \
- defined(__FreeBSD_kernel__) || \
- defined(__NetBSD__) || \
- defined(__OpenBSD__)
- r = uv_udp_set_membership(&client, "ff02::1", "::1%lo0", UV_JOIN_GROUP);
-#else
- r = uv_udp_set_membership(&client, "ff02::1", NULL, UV_JOIN_GROUP);
-#endif
+ r = uv_udp_set_membership(&server, MULTICAST_ADDR, INTERFACE_ADDR, UV_JOIN_GROUP);
if (r == UV_ENODEV) {
MAKE_VALGRIND_HAPPY();
RETURN_SKIP("No ipv6 multicast route");
@@ -135,18 +193,10 @@ TEST_IMPL(udp_multicast_join6) {
ASSERT(r == 0);
- r = uv_udp_recv_start(&client, alloc_cb, cl_recv_cb);
+ r = uv_udp_recv_start(&server, alloc_cb, cl_recv_cb);
ASSERT(r == 0);
- buf = uv_buf_init("PING", 4);
-
- /* server sends "PING" */
- r = uv_udp_send(&req,
- &server,
- &buf,
- 1,
- (const struct sockaddr*) &addr,
- sv_send_cb);
+ r = do_send(&req);
ASSERT(r == 0);
ASSERT(close_cb_called == 0);
@@ -156,8 +206,8 @@ TEST_IMPL(udp_multicast_join6) {
/* run the loop till all events are processed */
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
- ASSERT(cl_recv_cb_called == 1);
- ASSERT(sv_send_cb_called == 1);
+ ASSERT(cl_recv_cb_called == 2);
+ ASSERT(sv_send_cb_called == 2);
ASSERT(close_cb_called == 2);
MAKE_VALGRIND_HAPPY();
diff --git a/deps/uv/test/test.gyp b/deps/uv/test/test.gyp
index 6158a2b8b6..60792ad6eb 100644
--- a/deps/uv/test/test.gyp
+++ b/deps/uv/test/test.gyp
@@ -99,6 +99,7 @@
'test-shutdown-twice.c',
'test-signal.c',
'test-signal-multiple-loops.c',
+ 'test-signal-pending-on-close.c',
'test-socket-buffer-size.c',
'test-spawn.c',
'test-strscpy.c',
@@ -108,6 +109,7 @@
'test-tcp-bind6-error.c',
'test-tcp-close.c',
'test-tcp-close-accept.c',
+ 'test-tcp-close-reset.c',
'test-tcp-close-while-connecting.c',
'test-tcp-create-socket-early.c',
'test-tcp-connect-error-after-write.c',