aboutsummaryrefslogtreecommitdiff
path: root/deps/uv/test
diff options
context:
space:
mode:
Diffstat (limited to 'deps/uv/test')
-rw-r--r--deps/uv/test/runner-win.c24
-rw-r--r--deps/uv/test/task.h20
-rw-r--r--deps/uv/test/test-env-vars.c90
-rw-r--r--deps/uv/test/test-fork.c677
-rw-r--r--deps/uv/test/test-fs-event.c66
-rw-r--r--deps/uv/test/test-fs.c69
-rw-r--r--deps/uv/test/test-gethostname.c62
-rw-r--r--deps/uv/test/test-ip6-addr.c4
-rw-r--r--deps/uv/test/test-ipc-send-recv.c14
-rw-r--r--deps/uv/test/test-ipc.c12
-rw-r--r--deps/uv/test/test-list.h44
-rw-r--r--deps/uv/test/test-ping-pong.c4
-rw-r--r--deps/uv/test/test-pipe-bind-error.c3
-rw-r--r--deps/uv/test/test-pipe-connect-multiple.c3
-rw-r--r--deps/uv/test/test-pipe-getsockname.c3
-rw-r--r--deps/uv/test/test-pipe-sendmsg.c3
-rw-r--r--deps/uv/test/test-pipe-server-close.c3
-rw-r--r--deps/uv/test/test-platform-output.c8
-rw-r--r--deps/uv/test/test-poll.c9
-rw-r--r--deps/uv/test/test-process-title.c4
-rw-r--r--deps/uv/test/test-ref.c4
-rw-r--r--deps/uv/test/test-shutdown-twice.c1
-rw-r--r--deps/uv/test/test-signal-multiple-loops.c7
-rw-r--r--deps/uv/test/test-signal.c146
-rw-r--r--deps/uv/test/test-spawn.c30
-rw-r--r--deps/uv/test/test-tcp-create-socket-early.c2
-rw-r--r--deps/uv/test/test-tcp-write-queue-order.c6
-rw-r--r--deps/uv/test/test-threadpool-cancel.c5
-rw-r--r--deps/uv/test/test-tty.c2
-rw-r--r--deps/uv/test/test-udp-create-socket-early.c2
-rw-r--r--deps/uv/test/test-udp-ipv6.c5
-rw-r--r--deps/uv/test/test-udp-send-hang-loop.c99
-rw-r--r--deps/uv/test/test-udp-send-immediate.c1
-rw-r--r--deps/uv/test/test-watcher-cross-stop.c5
34 files changed, 1379 insertions, 58 deletions
diff --git a/deps/uv/test/runner-win.c b/deps/uv/test/runner-win.c
index 1b4a569aef..0f1b56e777 100644
--- a/deps/uv/test/runner-win.c
+++ b/deps/uv/test/runner-win.c
@@ -209,22 +209,30 @@ long int process_output_size(process_info_t *p) {
int process_copy_output(process_info_t* p, FILE* stream) {
- DWORD read;
char buf[1024];
+ int fd, r;
+ FILE* f;
- if (SetFilePointer(p->stdio_out,
- 0,
- 0,
- FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
+ fd = _open_osfhandle((intptr_t)p->stdio_out, _O_RDONLY | _O_TEXT);
+ if (fd == -1)
+ return -1;
+ f = _fdopen(fd, "rt");
+ if (f == NULL) {
+ _close(fd);
return -1;
}
- while (ReadFile(p->stdio_out, &buf, sizeof(buf), &read, NULL) && read > 0)
- print_lines(buf, read, stream);
+ r = fseek(f, 0, SEEK_SET);
+ if (r < 0)
+ return -1;
- if (GetLastError() != ERROR_HANDLE_EOF)
+ while (fgets(buf, sizeof(buf), f) != NULL)
+ print_lines(buf, strlen(buf), stream);
+
+ if (ferror(f))
return -1;
+ fclose(f);
return 0;
}
diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h
index 65a1132e49..67eb980492 100644
--- a/deps/uv/test/task.h
+++ b/deps/uv/test/task.h
@@ -209,4 +209,24 @@ UNUSED static int can_ipv6(void) {
return supported;
}
+#if defined(__MVS__) || defined(__CYGWIN__) || defined(__MSYS__)
+# define NO_FS_EVENTS "Filesystem watching not supported on this platform."
+#endif
+
+#if defined(__MSYS__)
+# define NO_SEND_HANDLE_ON_PIPE \
+ "MSYS2 runtime does not support sending handles on pipes."
+#elif defined(__CYGWIN__)
+# define NO_SEND_HANDLE_ON_PIPE \
+ "Cygwin runtime does not support sending handles on pipes."
+#endif
+
+#if defined(__MSYS__)
+# define NO_SELF_CONNECT \
+ "MSYS2 runtime hangs on listen+connect in same process."
+#elif defined(__CYGWIN__)
+# define NO_SELF_CONNECT \
+ "Cygwin runtime hangs on listen+connect in same process."
+#endif
+
#endif /* TASK_H_ */
diff --git a/deps/uv/test/test-env-vars.c b/deps/uv/test/test-env-vars.c
new file mode 100644
index 0000000000..641050e675
--- /dev/null
+++ b/deps/uv/test/test-env-vars.c
@@ -0,0 +1,90 @@
+/* Copyright libuv 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 <string.h>
+
+#define BUF_SIZE 10
+
+TEST_IMPL(env_vars) {
+ const char* name = "UV_TEST_FOO";
+ char buf[BUF_SIZE];
+ size_t size;
+ int r;
+
+ /* Reject invalid inputs when setting an environment variable */
+ r = uv_os_setenv(NULL, "foo");
+ ASSERT(r == UV_EINVAL);
+ r = uv_os_setenv(name, NULL);
+ ASSERT(r == UV_EINVAL);
+ r = uv_os_setenv(NULL, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ /* Reject invalid inputs when retrieving an environment variable */
+ size = BUF_SIZE;
+ r = uv_os_getenv(NULL, buf, &size);
+ ASSERT(r == UV_EINVAL);
+ r = uv_os_getenv(name, NULL, &size);
+ ASSERT(r == UV_EINVAL);
+ r = uv_os_getenv(name, buf, NULL);
+ ASSERT(r == UV_EINVAL);
+ size = 0;
+ r = uv_os_getenv(name, buf, &size);
+ ASSERT(r == UV_EINVAL);
+
+ /* Reject invalid inputs when deleting an environment variable */
+ r = uv_os_unsetenv(NULL);
+ ASSERT(r == UV_EINVAL);
+
+ /* Successfully set an environment variable */
+ r = uv_os_setenv(name, "123456789");
+ ASSERT(r == 0);
+
+ /* Successfully read an environment variable */
+ size = BUF_SIZE;
+ buf[0] = '\0';
+ r = uv_os_getenv(name, buf, &size);
+ ASSERT(r == 0);
+ ASSERT(strcmp(buf, "123456789") == 0);
+ ASSERT(size == BUF_SIZE - 1);
+
+ /* Return UV_ENOBUFS if the buffer cannot hold the environment variable */
+ size = BUF_SIZE - 1;
+ buf[0] = '\0';
+ r = uv_os_getenv(name, buf, &size);
+ ASSERT(r == UV_ENOBUFS);
+ ASSERT(size == BUF_SIZE);
+
+ /* Successfully delete an environment variable */
+ r = uv_os_unsetenv(name);
+ ASSERT(r == 0);
+
+ /* Return UV_ENOENT retrieving an environment variable that does not exist */
+ r = uv_os_getenv(name, buf, &size);
+ ASSERT(r == UV_ENOENT);
+
+ /* Successfully delete an environment variable that does not exist */
+ r = uv_os_unsetenv(name);
+ ASSERT(r == 0);
+
+ return 0;
+}
diff --git a/deps/uv/test/test-fork.c b/deps/uv/test/test-fork.c
new file mode 100644
index 0000000000..3716a3ad97
--- /dev/null
+++ b/deps/uv/test/test-fork.c
@@ -0,0 +1,677 @@
+/* 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.
+ */
+
+/* These tests are Unix only. */
+#ifndef _WIN32
+
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <string.h>
+
+#include "uv.h"
+#include "task.h"
+
+static int timer_cb_called;
+static int socket_cb_called;
+
+static void timer_cb(uv_timer_t* timer) {
+ timer_cb_called++;
+ uv_close((uv_handle_t*) timer, NULL);
+}
+
+
+static int socket_cb_read_fd;
+static int socket_cb_read_size;
+static char socket_cb_read_buf[1024];
+
+
+static void socket_cb(uv_poll_t* poll, int status, int events) {
+ ssize_t cnt;
+ socket_cb_called++;
+ ASSERT(0 == status);
+ printf("Socket cb got events %d\n", events);
+ ASSERT(UV_READABLE == (events & UV_READABLE));
+ if (socket_cb_read_fd) {
+ cnt = read(socket_cb_read_fd, socket_cb_read_buf, socket_cb_read_size);
+ ASSERT(cnt == socket_cb_read_size);
+ }
+ uv_close((uv_handle_t*) poll, NULL);
+}
+
+
+static void run_timer_loop_once(void) {
+ uv_loop_t* loop;
+ uv_timer_t timer_handle;
+
+ loop = uv_default_loop();
+
+ timer_cb_called = 0; /* Reset for the child. */
+
+ ASSERT(0 == uv_timer_init(loop, &timer_handle));
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(1 == timer_cb_called);
+}
+
+
+static void assert_wait_child(pid_t child_pid) {
+ pid_t waited_pid;
+ int child_stat;
+
+ waited_pid = waitpid(child_pid, &child_stat, 0);
+ printf("Waited pid is %d with status %d\n", waited_pid, child_stat);
+ if (waited_pid == -1) {
+ perror("Failed to wait");
+ }
+ ASSERT(child_pid == waited_pid);
+ ASSERT(WIFEXITED(child_stat)); /* Clean exit, not a signal. */
+ ASSERT(!WIFSIGNALED(child_stat));
+ ASSERT(0 == WEXITSTATUS(child_stat));
+}
+
+
+TEST_IMPL(fork_timer) {
+ /* Timers continue to work after we fork. */
+
+ /*
+ * Establish the loop before we fork to make sure that it
+ * has state to get reset after the fork.
+ */
+ pid_t child_pid;
+
+ run_timer_loop_once();
+ child_pid = fork();
+ ASSERT(child_pid != -1);
+
+ if (child_pid != 0) {
+ /* parent */
+ assert_wait_child(child_pid);
+ } else {
+ /* child */
+ ASSERT(0 == uv_loop_fork(uv_default_loop()));
+ run_timer_loop_once();
+ }
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fork_socketpair) {
+ /* A socket opened in the parent and accept'd in the
+ child works after a fork. */
+ pid_t child_pid;
+ int socket_fds[2];
+ uv_poll_t poll_handle;
+
+ /* Prime the loop. */
+ run_timer_loop_once();
+
+ ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds));
+
+ /* Create the server watcher in the parent, use it in the child. */
+ ASSERT(0 == uv_poll_init(uv_default_loop(), &poll_handle, socket_fds[0]));
+
+ child_pid = fork();
+ ASSERT(child_pid != -1);
+
+ if (child_pid != 0) {
+ /* parent */
+ ASSERT(3 == send(socket_fds[1], "hi\n", 3, 0));
+ assert_wait_child(child_pid);
+ } else {
+ /* child */
+ ASSERT(0 == uv_loop_fork(uv_default_loop()));
+ ASSERT(0 == socket_cb_called);
+ ASSERT(0 == uv_poll_start(&poll_handle, UV_READABLE, socket_cb));
+ printf("Going to run the loop in the child\n");
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(1 == socket_cb_called);
+ }
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fork_socketpair_started) {
+ /* A socket opened in the parent and accept'd in the
+ child works after a fork, even if the watcher was already
+ started, and then stopped in the parent. */
+ pid_t child_pid;
+ int socket_fds[2];
+ int sync_pipe[2];
+ char sync_buf[1];
+ uv_poll_t poll_handle;
+
+ ASSERT(0 == pipe(sync_pipe));
+
+ /* Prime the loop. */
+ run_timer_loop_once();
+
+ ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds));
+
+ /* Create and start the server watcher in the parent, use it in the child. */
+ ASSERT(0 == uv_poll_init(uv_default_loop(), &poll_handle, socket_fds[0]));
+ ASSERT(0 == uv_poll_start(&poll_handle, UV_READABLE, socket_cb));
+
+ /* Run the loop AFTER the poll watcher is registered to make sure it
+ gets passed to the kernel. Use NOWAIT and expect a non-zero
+ return to prove the poll watcher is active.
+ */
+ ASSERT(1 == uv_run(uv_default_loop(), UV_RUN_NOWAIT));
+
+ child_pid = fork();
+ ASSERT(child_pid != -1);
+
+ if (child_pid != 0) {
+ /* parent */
+ ASSERT(0 == uv_poll_stop(&poll_handle));
+ uv_close((uv_handle_t*)&poll_handle, NULL);
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(0 == socket_cb_called);
+ ASSERT(1 == write(sync_pipe[1], "1", 1)); /* alert child */
+ ASSERT(3 == send(socket_fds[1], "hi\n", 3, 0));
+
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(0 == socket_cb_called);
+
+ assert_wait_child(child_pid);
+ } else {
+ /* child */
+ printf("Child is %d\n", getpid());
+ ASSERT(1 == read(sync_pipe[0], sync_buf, 1)); /* wait for parent */
+ ASSERT(0 == uv_loop_fork(uv_default_loop()));
+ ASSERT(0 == socket_cb_called);
+
+ printf("Going to run the loop in the child\n");
+ socket_cb_read_fd = socket_fds[0];
+ socket_cb_read_size = 3;
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(1 == socket_cb_called);
+ printf("Buf %s\n", socket_cb_read_buf);
+ ASSERT(0 == strcmp("hi\n", socket_cb_read_buf));
+ }
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+static int fork_signal_cb_called;
+
+void fork_signal_to_child_cb(uv_signal_t* handle, int signum)
+{
+ fork_signal_cb_called = signum;
+ uv_close((uv_handle_t*)handle, NULL);
+}
+
+
+TEST_IMPL(fork_signal_to_child) {
+ /* A signal handler installed before forking
+ is run only in the child when the child is signalled. */
+ uv_signal_t signal_handle;
+ pid_t child_pid;
+ int sync_pipe[2];
+ char sync_buf[1];
+
+ fork_signal_cb_called = 0; /* reset */
+
+ ASSERT(0 == pipe(sync_pipe));
+
+ /* Prime the loop. */
+ run_timer_loop_once();
+
+ ASSERT(0 == uv_signal_init(uv_default_loop(), &signal_handle));
+ ASSERT(0 == uv_signal_start(&signal_handle, fork_signal_to_child_cb, SIGUSR1));
+
+ child_pid = fork();
+ ASSERT(child_pid != -1);
+
+ if (child_pid != 0) {
+ /* parent */
+ ASSERT(1 == read(sync_pipe[0], sync_buf, 1)); /* wait for child */
+ ASSERT(0 == kill(child_pid, SIGUSR1));
+ /* Run the loop, make sure we don't get the signal. */
+ printf("Running loop in parent\n");
+ uv_unref((uv_handle_t*)&signal_handle);
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_NOWAIT));
+ ASSERT(0 == fork_signal_cb_called);
+ printf("Waiting for child in parent\n");
+ assert_wait_child(child_pid);
+ } else {
+ /* child */
+ ASSERT(0 == uv_loop_fork(uv_default_loop()));
+ ASSERT(1 == write(sync_pipe[1], "1", 1)); /* alert parent */
+ /* Get the signal. */
+ ASSERT(0 != uv_loop_alive(uv_default_loop()));
+ printf("Running loop in child\n");
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
+ ASSERT(SIGUSR1 == fork_signal_cb_called);
+ }
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fork_signal_to_child_closed) {
+ /* A signal handler installed before forking
+ doesn't get received anywhere when the child is signalled,
+ but isnt running the loop. */
+ uv_signal_t signal_handle;
+ pid_t child_pid;
+ int sync_pipe[2];
+ int sync_pipe2[2];
+ char sync_buf[1];
+
+ fork_signal_cb_called = 0; /* reset */
+
+ ASSERT(0 == pipe(sync_pipe));
+ ASSERT(0 == pipe(sync_pipe2));
+
+ /* Prime the loop. */
+ run_timer_loop_once();
+
+ ASSERT(0 == uv_signal_init(uv_default_loop(), &signal_handle));
+ ASSERT(0 == uv_signal_start(&signal_handle, fork_signal_to_child_cb, SIGUSR1));
+
+ child_pid = fork();
+ ASSERT(child_pid != -1);
+
+ if (child_pid != 0) {
+ /* parent */
+ printf("Wating on child in parent\n");
+ ASSERT(1 == read(sync_pipe[0], sync_buf, 1)); /* wait for child */
+ printf("Parent killing child\n");
+ ASSERT(0 == kill(child_pid, SIGUSR1));
+ /* Run the loop, make sure we don't get the signal. */
+ printf("Running loop in parent\n");
+ uv_unref((uv_handle_t*)&signal_handle); /* so the loop can exit;
+ we *shouldn't* get any signals */
+ run_timer_loop_once(); /* but while we share a pipe, we do, so
+ have something active. */
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
+ printf("Signal in parent %d\n", fork_signal_cb_called);
+ ASSERT(0 == fork_signal_cb_called);
+ ASSERT(1 == write(sync_pipe2[1], "1", 1)); /* alert child */
+ printf("Waiting for child in parent\n");
+ assert_wait_child(child_pid);
+ } else {
+ /* child */
+ /* Our signal handler should still be installed. */
+ ASSERT(0 == uv_loop_fork(uv_default_loop()));
+ printf("Checking loop in child\n");
+ ASSERT(0 != uv_loop_alive(uv_default_loop()));
+ printf("Alerting parent in child\n");
+ ASSERT(1 == write(sync_pipe[1], "1", 1)); /* alert parent */
+ /* Don't run the loop. Wait for the parent to call us */
+ printf("Waiting on parent in child\n");
+ /* Wait for parent. read may fail if the parent tripped an ASSERT
+ and exited, so this isn't in an ASSERT.
+ */
+ read(sync_pipe2[0], sync_buf, 1);
+ ASSERT(0 == fork_signal_cb_called);
+ printf("Exiting child \n");
+ /* Note that we're deliberately not running the loop
+ * in the child, and also not closing the loop's handles,
+ * so the child default loop can't be cleanly closed.
+ * We need te explicitly exit to avoid an automatic failure
+ * in that case.
+ */
+ exit(0);
+ }
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+static void create_file(const char* name) {
+ int r;
+ uv_file file;
+ uv_fs_t req;
+
+ r = uv_fs_open(NULL, &req, name, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ file = r;
+ uv_fs_req_cleanup(&req);
+ r = uv_fs_close(NULL, &req, file, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&req);
+}
+
+
+static void touch_file(const char* name) {
+ int r;
+ uv_file file;
+ uv_fs_t req;
+ uv_buf_t buf;
+
+ r = uv_fs_open(NULL, &req, name, O_RDWR, 0, NULL);
+ ASSERT(r >= 0);
+ file = r;
+ uv_fs_req_cleanup(&req);
+
+ buf = uv_buf_init("foo", 4);
+ r = uv_fs_write(NULL, &req, file, &buf, 1, -1, NULL);
+ ASSERT(r >= 0);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_close(NULL, &req, file, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&req);
+}
+
+
+static int timer_cb_touch_called;
+
+static void timer_cb_touch(uv_timer_t* timer) {
+ uv_close((uv_handle_t*)timer, NULL);
+ touch_file("watch_file");
+ timer_cb_touch_called++;
+}
+
+
+static int fs_event_cb_called;
+
+static void fs_event_cb_file_current_dir(uv_fs_event_t* handle,
+ const char* filename,
+ int events,
+ int status) {
+ ASSERT(fs_event_cb_called == 0);
+ ++fs_event_cb_called;
+ ASSERT(status == 0);
+#if defined(__APPLE__) || defined(__linux__)
+ ASSERT(strcmp(filename, "watch_file") == 0);
+#else
+ ASSERT(filename == NULL || strcmp(filename, "watch_file") == 0);
+#endif
+ uv_close((uv_handle_t*)handle, NULL);
+}
+
+
+static void assert_watch_file_current_dir(uv_loop_t* const loop, int file_or_dir) {
+ uv_timer_t timer;
+ uv_fs_event_t fs_event;
+ int r;
+
+ /* Setup */
+ remove("watch_file");
+ create_file("watch_file");
+
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ /* watching a dir is the only way to get fsevents involved on apple
+ platforms */
+ r = uv_fs_event_start(&fs_event,
+ fs_event_cb_file_current_dir,
+ file_or_dir == 1 ? "." : "watch_file",
+ 0);
+ ASSERT(r == 0);
+
+ r = uv_timer_init(loop, &timer);
+ ASSERT(r == 0);
+
+ r = uv_timer_start(&timer, timer_cb_touch, 100, 0);
+ ASSERT(r == 0);
+
+ ASSERT(timer_cb_touch_called == 0);
+ ASSERT(fs_event_cb_called == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(timer_cb_touch_called == 1);
+ ASSERT(fs_event_cb_called == 1);
+
+ /* Cleanup */
+ remove("watch_file");
+ fs_event_cb_called = 0;
+ timer_cb_touch_called = 0;
+ uv_run(loop, UV_RUN_DEFAULT); /* flush pending closes */
+}
+
+
+#define FS_TEST_FILE 0
+#define FS_TEST_DIR 1
+
+static int _do_fork_fs_events_child(int file_or_dir) {
+ /* basic fsevents work in the child after a fork */
+ pid_t child_pid;
+ uv_loop_t loop;
+
+ /* Watch in the parent, prime the loop and/or threads. */
+ assert_watch_file_current_dir(uv_default_loop(), file_or_dir);
+ child_pid = fork();
+ ASSERT(child_pid != -1);
+
+ if (child_pid != 0) {
+ /* parent */
+ assert_wait_child(child_pid);
+ } else {
+ /* child */
+ /* Ee can watch in a new loop, but dirs only work
+ if we're on linux. */
+#if defined(__APPLE__)
+ file_or_dir = FS_TEST_FILE;
+#endif
+ printf("Running child\n");
+ uv_loop_init(&loop);
+ printf("Child first watch\n");
+ assert_watch_file_current_dir(&loop, file_or_dir);
+ ASSERT(0 == uv_loop_close(&loop));
+ printf("Child second watch default loop\n");
+ /* Ee can watch in the default loop. */
+ ASSERT(0 == uv_loop_fork(uv_default_loop()));
+ /* On some platforms (OS X), if we don't update the time now,
+ * the timer cb fires before the event loop enters uv__io_poll,
+ * instead of after, meaning we don't see the change! This may be
+ * a general race.
+ */
+ uv_update_time(uv_default_loop());
+ assert_watch_file_current_dir(uv_default_loop(), file_or_dir);
+
+ /* We can close the parent loop successfully too. This is
+ especially important on Apple platforms where if we're not
+ careful trying to touch the CFRunLoop, even just to shut it
+ down, that we allocated in the FS_TEST_DIR case would crash. */
+ ASSERT(0 == uv_loop_close(uv_default_loop()));
+
+ printf("Exiting child \n");
+ }
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+
+}
+
+
+TEST_IMPL(fork_fs_events_child) {
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
+#endif
+ return _do_fork_fs_events_child(FS_TEST_FILE);
+}
+
+
+TEST_IMPL(fork_fs_events_child_dir) {
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
+#endif
+#if defined(__APPLE__) || defined (__linux__)
+ return _do_fork_fs_events_child(FS_TEST_DIR);
+#else
+ /* You can't spin up a cfrunloop thread on an apple platform
+ and then fork. See
+ http://objectivistc.tumblr.com/post/16187948939/you-must-exec-a-core-foundation-fork-safety-tale
+ */
+ return 0;
+#endif
+}
+
+
+TEST_IMPL(fork_fs_events_file_parent_child) {
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
+#endif
+#if defined(__sun) || defined(_AIX)
+ /* It's not possible to implement this without additional
+ * bookkeeping on SunOS. For AIX it is possible, but has to be
+ * written. See https://github.com/libuv/libuv/pull/846#issuecomment-287170420
+ */
+ return 0;
+#else
+ /* Establishing a started fs events watcher in the parent should
+ still work in the child. */
+ uv_timer_t timer;
+ uv_fs_event_t fs_event;
+ int r;
+ pid_t child_pid;
+ uv_loop_t* loop;
+
+ loop = uv_default_loop();
+
+ /* Setup */
+ remove("watch_file");
+ create_file("watch_file");
+
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event,
+ fs_event_cb_file_current_dir,
+ "watch_file",
+ 0);
+ ASSERT(r == 0);
+
+ r = uv_timer_init(loop, &timer);
+ ASSERT(r == 0);
+
+ child_pid = fork();
+ ASSERT(child_pid != -1);
+ if (child_pid != 0) {
+ /* parent */
+ assert_wait_child(child_pid);
+ } else {
+ /* child */
+ printf("Running child\n");
+ ASSERT(0 == uv_loop_fork(loop));
+
+ r = uv_timer_start(&timer, timer_cb_touch, 100, 0);
+ ASSERT(r == 0);
+
+ ASSERT(timer_cb_touch_called == 0);
+ ASSERT(fs_event_cb_called == 0);
+ printf("Running loop in child \n");
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(timer_cb_touch_called == 1);
+ ASSERT(fs_event_cb_called == 1);
+
+ /* Cleanup */
+ remove("watch_file");
+ fs_event_cb_called = 0;
+ timer_cb_touch_called = 0;
+ uv_run(loop, UV_RUN_DEFAULT); /* Flush pending closes. */
+ }
+
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+#endif
+}
+
+
+static int work_cb_count;
+static int after_work_cb_count;
+
+
+static void work_cb(uv_work_t* req) {
+ work_cb_count++;
+}
+
+
+static void after_work_cb(uv_work_t* req, int status) {
+ ASSERT(status == 0);
+ after_work_cb_count++;
+}
+
+
+static void assert_run_work(uv_loop_t* const loop) {
+ uv_work_t work_req;
+ int r;
+
+ ASSERT(work_cb_count == 0);
+ ASSERT(after_work_cb_count == 0);
+ printf("Queue in %d\n", getpid());
+ r = uv_queue_work(loop, &work_req, work_cb, after_work_cb);
+ ASSERT(r == 0);
+ printf("Running in %d\n", getpid());
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(work_cb_count == 1);
+ ASSERT(after_work_cb_count == 1);
+
+ /* cleanup */
+ work_cb_count = 0;
+ after_work_cb_count = 0;
+}
+
+
+TEST_IMPL(fork_threadpool_queue_work_simple) {
+ /* The threadpool works in a child process. */
+
+ pid_t child_pid;
+ uv_loop_t loop;
+
+ /* Prime the pool and default loop. */
+ assert_run_work(uv_default_loop());
+
+ child_pid = fork();
+ ASSERT(child_pid != -1);
+
+ if (child_pid != 0) {
+ /* parent */
+ /* We can still run work. */
+ assert_run_work(uv_default_loop());
+ assert_wait_child(child_pid);
+ } else {
+ /* child */
+ /* We can work in a new loop. */
+ printf("Running child in %d\n", getpid());
+ uv_loop_init(&loop);
+ printf("Child first watch\n");
+ assert_run_work(&loop);
+ uv_loop_close(&loop);
+ printf("Child second watch default loop\n");
+ /* We can work in the default loop. */
+ ASSERT(0 == uv_loop_fork(uv_default_loop()));
+ assert_run_work(uv_default_loop());
+ printf("Exiting child \n");
+ }
+
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+#endif /* !_WIN32 */
diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c
index df8dc4c2f7..fba6b5440b 100644
--- a/deps/uv/test/test-fs-event.c
+++ b/deps/uv/test/test-fs-event.c
@@ -394,8 +394,8 @@ static void timer_cb_watch_twice(uv_timer_t* handle) {
}
TEST_IMPL(fs_event_watch_dir) {
-#if defined(__MVS__)
- RETURN_SKIP("Filesystem watching not supported on this platform.");
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
#endif
uv_loop_t* loop = uv_default_loop();
@@ -477,8 +477,8 @@ TEST_IMPL(fs_event_watch_dir_recursive) {
TEST_IMPL(fs_event_watch_file) {
-#if defined(__MVS__)
- RETURN_SKIP("Filesystem watching not supported on this platform.");
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
#endif
uv_loop_t* loop = uv_default_loop();
@@ -522,8 +522,8 @@ TEST_IMPL(fs_event_watch_file_exact_path) {
"file.js". The test verifies that no events occur for file.jsx.
*/
-#if defined(__MVS__)
- RETURN_SKIP("Filesystem watching not supported on this platform.");
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
#endif
uv_loop_t* loop;
@@ -561,8 +561,8 @@ TEST_IMPL(fs_event_watch_file_exact_path) {
}
TEST_IMPL(fs_event_watch_file_twice) {
-#if defined(__MVS__)
- RETURN_SKIP("Filesystem watching not supported on this platform.");
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
#endif
const char path[] = "test/fixtures/empty_file";
uv_fs_event_t watchers[2];
@@ -585,8 +585,8 @@ TEST_IMPL(fs_event_watch_file_twice) {
}
TEST_IMPL(fs_event_watch_file_current_dir) {
-#if defined(__MVS__)
- RETURN_SKIP("Filesystem watching not supported on this platform.");
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
#endif
uv_timer_t timer;
uv_loop_t* loop;
@@ -658,8 +658,8 @@ TEST_IMPL(fs_event_watch_file_root_dir) {
#endif
TEST_IMPL(fs_event_no_callback_after_close) {
-#if defined(__MVS__)
- RETURN_SKIP("Filesystem watching not supported on this platform.");
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
#endif
uv_loop_t* loop = uv_default_loop();
@@ -696,8 +696,8 @@ TEST_IMPL(fs_event_no_callback_after_close) {
}
TEST_IMPL(fs_event_no_callback_on_close) {
-#if defined(__MVS__)
- RETURN_SKIP("Filesystem watching not supported on this platform.");
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
#endif
uv_loop_t* loop = uv_default_loop();
@@ -747,8 +747,8 @@ static void timer_cb(uv_timer_t* handle) {
TEST_IMPL(fs_event_immediate_close) {
-#if defined(__MVS__)
- RETURN_SKIP("Filesystem watching not supported on this platform.");
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
#endif
uv_timer_t timer;
uv_loop_t* loop;
@@ -772,8 +772,8 @@ TEST_IMPL(fs_event_immediate_close) {
TEST_IMPL(fs_event_close_with_pending_event) {
-#if defined(__MVS__)
- RETURN_SKIP("Filesystem watching not supported on this platform.");
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
#endif
uv_loop_t* loop;
int r;
@@ -818,8 +818,8 @@ static void fs_event_cb_close(uv_fs_event_t* handle, const char* filename,
}
TEST_IMPL(fs_event_close_in_callback) {
-#if defined(__MVS__)
- RETURN_SKIP("Filesystem watching not supported on this platform.");
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
#endif
uv_loop_t* loop;
int r;
@@ -857,8 +857,8 @@ TEST_IMPL(fs_event_close_in_callback) {
}
TEST_IMPL(fs_event_start_and_close) {
-#if defined(__MVS__)
- RETURN_SKIP("Filesystem watching not supported on this platform.");
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
#endif
uv_loop_t* loop;
uv_fs_event_t fs_event1;
@@ -892,8 +892,8 @@ TEST_IMPL(fs_event_start_and_close) {
}
TEST_IMPL(fs_event_getpath) {
-#if defined(__MVS__)
- RETURN_SKIP("Filesystem watching not supported on this platform.");
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
#endif
uv_loop_t* loop = uv_default_loop();
int r;
@@ -1027,3 +1027,21 @@ TEST_IMPL(fs_event_error_reporting) {
}
#endif /* defined(__APPLE__) */
+
+TEST_IMPL(fs_event_watch_invalid_path) {
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
+#endif
+
+ uv_loop_t* loop;
+ int r;
+
+ loop = uv_default_loop();
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event, fs_event_cb_file, "<:;", 0);
+ ASSERT(r != 0);
+ ASSERT(uv_is_active((uv_handle_t*) &fs_event) == 0);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index 030245eadc..c482ab5c71 100644
--- a/deps/uv/test/test-fs.c
+++ b/deps/uv/test/test-fs.c
@@ -125,7 +125,7 @@ static void check_permission(const char* filename, unsigned int mode) {
ASSERT(req.result == 0);
s = &req.statbuf;
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MSYS__)
/*
* On Windows, chmod can only modify S_IWUSR (_S_IWRITE) bit,
* so only testing for the specified flags.
@@ -240,7 +240,7 @@ static void chown_cb(uv_fs_t* req) {
static void chown_root_cb(uv_fs_t* req) {
ASSERT(req->fs_type == UV_FS_CHOWN);
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__MSYS__)
/* On windows, chown is a no-op and always succeeds. */
ASSERT(req->result == 0);
#else
@@ -250,7 +250,12 @@ static void chown_root_cb(uv_fs_t* req) {
if (geteuid() == 0)
ASSERT(req->result == 0);
else
+# if defined(__CYGWIN__)
+ /* On Cygwin, uid 0 is invalid (no root). */
+ ASSERT(req->result == UV_EINVAL);
+# else
ASSERT(req->result == UV_EPERM);
+# endif
#endif
chown_cb_count++;
uv_fs_req_cleanup(req);
@@ -641,6 +646,11 @@ TEST_IMPL(fs_file_loop) {
*/
if (r == UV_ENOTSUP || r == UV_EPERM)
return 0;
+#elif defined(__MSYS__)
+ /* MSYS2's approximation of symlinks with copies does not work for broken
+ links. */
+ if (r == UV_ENOENT)
+ return 0;
#endif
ASSERT(r == 0);
uv_fs_req_cleanup(&req);
@@ -1485,6 +1495,7 @@ TEST_IMPL(fs_chown) {
/* chown to root (fail) */
chown_cb_count = 0;
r = uv_fs_chown(loop, &req, "test_file", 0, 0, chown_root_cb);
+ ASSERT(r == 0);
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(chown_cb_count == 1);
@@ -1734,6 +1745,10 @@ TEST_IMPL(fs_symlink) {
ASSERT(r == 0);
uv_fs_req_cleanup(&req);
+#if defined(__MSYS__)
+ RETURN_SKIP("symlink reading is not supported on MSYS2");
+#endif
+
r = uv_fs_readlink(NULL, &req, "test_file_symlink_symlink", NULL);
ASSERT(r == 0);
ASSERT(strcmp(req.ptr, "test_file_symlink") == 0);
@@ -1877,6 +1892,9 @@ TEST_IMPL(fs_symlink_dir) {
r = uv_fs_lstat(NULL, &req, "test_dir_symlink", NULL);
ASSERT(r == 0);
+#if defined(__MSYS__)
+ RETURN_SKIP("symlink reading is not supported on MSYS2");
+#endif
ASSERT(((uv_stat_t*)req.ptr)->st_mode & S_IFLNK);
#ifdef _WIN32
ASSERT(((uv_stat_t*)req.ptr)->st_size == strlen(test_dir + 4));
@@ -2102,8 +2120,13 @@ TEST_IMPL(fs_futime) {
uv_fs_req_cleanup(&req);
r = uv_fs_futime(NULL, &req, file, atime, mtime, NULL);
+#if defined(__CYGWIN__) || defined(__MSYS__)
+ ASSERT(r == UV_ENOSYS);
+ RETURN_SKIP("futime not supported on Cygwin");
+#else
ASSERT(r == 0);
ASSERT(req.result == 0);
+#endif
uv_fs_req_cleanup(&req);
r = uv_fs_stat(NULL, &req, path, NULL);
@@ -2412,6 +2435,9 @@ TEST_IMPL(fs_rename_to_existing_file) {
TEST_IMPL(fs_read_file_eof) {
+#if defined(__CYGWIN__) || defined(__MSYS__)
+ RETURN_SKIP("Cygwin pread at EOF may (incorrectly) return data!");
+#endif
int r;
/* Setup. */
@@ -2739,3 +2765,42 @@ TEST_IMPL(fs_read_write_null_arguments) {
return 0;
}
+
+
+TEST_IMPL(get_osfhandle_valid_handle) {
+ int r;
+ uv_os_fd_t fd;
+
+ /* Setup. */
+ unlink("test_file");
+
+ loop = uv_default_loop();
+
+ r = uv_fs_open(NULL,
+ &open_req1,
+ "test_file",
+ O_RDWR | O_CREAT,
+ S_IWUSR | S_IRUSR,
+ NULL);
+ ASSERT(r >= 0);
+ ASSERT(open_req1.result >= 0);
+ uv_fs_req_cleanup(&open_req1);
+
+ fd = uv_get_osfhandle(open_req1.result);
+#ifdef _WIN32
+ ASSERT(fd != INVALID_HANDLE_VALUE);
+#else
+ ASSERT(fd >= 0);
+#endif
+
+ r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ ASSERT(close_req.result == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ /* Cleanup. */
+ unlink("test_file");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-gethostname.c b/deps/uv/test/test-gethostname.c
new file mode 100644
index 0000000000..5229804b56
--- /dev/null
+++ b/deps/uv/test/test-gethostname.c
@@ -0,0 +1,62 @@
+/* Copyright libuv 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 <string.h>
+
+#ifndef MAXHOSTNAMELEN
+# define MAXHOSTNAMELEN 256
+#endif
+
+TEST_IMPL(gethostname) {
+ char buf[MAXHOSTNAMELEN + 1];
+ size_t size;
+ size_t enobufs_size;
+ int r;
+
+ /* Reject invalid inputs */
+ size = 1;
+ r = uv_os_gethostname(NULL, &size);
+ ASSERT(r == UV_EINVAL);
+ r = uv_os_gethostname(buf, NULL);
+ ASSERT(r == UV_EINVAL);
+ size = 0;
+ r = uv_os_gethostname(buf, &size);
+ ASSERT(r == UV_EINVAL);
+
+ /* Return UV_ENOBUFS if the buffer cannot hold the hostname */
+ enobufs_size = 1;
+ buf[0] = '\0';
+ r = uv_os_gethostname(buf, &enobufs_size);
+ ASSERT(r == UV_ENOBUFS);
+ ASSERT(buf[0] == '\0');
+ ASSERT(enobufs_size > 1);
+
+ /* Successfully get the hostname */
+ size = MAXHOSTNAMELEN + 1;
+ r = uv_os_gethostname(buf, &size);
+ ASSERT(r == 0);
+ ASSERT(size > 1 && size == strlen(buf));
+ ASSERT(size + 1 == enobufs_size);
+
+ return 0;
+}
diff --git a/deps/uv/test/test-ip6-addr.c b/deps/uv/test/test-ip6-addr.c
index 869b099e0f..156fccde39 100644
--- a/deps/uv/test/test-ip6-addr.c
+++ b/deps/uv/test/test-ip6-addr.c
@@ -32,6 +32,10 @@
TEST_IMPL(ip6_addr_link_local) {
+#if defined(__CYGWIN__) || defined(__MSYS__)
+ /* FIXME: Does Cygwin support this? */
+ RETURN_SKIP("FIXME: This test needs more investigation on Cygwin");
+#endif
char string_address[INET6_ADDRSTRLEN];
uv_interface_address_t* addresses;
uv_interface_address_t* address;
diff --git a/deps/uv/test/test-ipc-send-recv.c b/deps/uv/test/test-ipc-send-recv.c
index 133ae90149..160c235078 100644
--- a/deps/uv/test/test-ipc-send-recv.c
+++ b/deps/uv/test/test-ipc-send-recv.c
@@ -224,10 +224,16 @@ static int run_ipc_send_recv_pipe(int inprocess) {
}
TEST_IMPL(ipc_send_recv_pipe) {
+#if defined(NO_SEND_HANDLE_ON_PIPE)
+ RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE);
+#endif
return run_ipc_send_recv_pipe(0);
}
TEST_IMPL(ipc_send_recv_pipe_inprocess) {
+#if defined(NO_SEND_HANDLE_ON_PIPE)
+ RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE);
+#endif
return run_ipc_send_recv_pipe(1);
}
@@ -259,10 +265,16 @@ static int run_ipc_send_recv_tcp(int inprocess) {
}
TEST_IMPL(ipc_send_recv_tcp) {
+#if defined(NO_SEND_HANDLE_ON_PIPE)
+ RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE);
+#endif
return run_ipc_send_recv_tcp(0);
}
TEST_IMPL(ipc_send_recv_tcp_inprocess) {
+#if defined(NO_SEND_HANDLE_ON_PIPE)
+ RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE);
+#endif
return run_ipc_send_recv_tcp(1);
}
@@ -335,7 +347,7 @@ static void read_cb(uv_stream_t* handle,
} while (uv_pipe_pending_count(pipe) > 0);
}
-static void send_recv_start() {
+static void send_recv_start(void) {
int r;
ASSERT(1 == uv_is_readable((uv_stream_t*)&ctx2.channel));
ASSERT(1 == uv_is_writable((uv_stream_t*)&ctx2.channel));
diff --git a/deps/uv/test/test-ipc.c b/deps/uv/test/test-ipc.c
index f018c2d4d4..a2fda24585 100644
--- a/deps/uv/test/test-ipc.c
+++ b/deps/uv/test/test-ipc.c
@@ -411,6 +411,9 @@ static int run_ipc_test(const char* helper, uv_read_cb read_cb) {
TEST_IMPL(ipc_listen_before_write) {
+#if defined(NO_SEND_HANDLE_ON_PIPE)
+ RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE);
+#endif
int r = run_ipc_test("ipc_helper_listen_before_write", on_read);
ASSERT(local_conn_accepted == 1);
ASSERT(remote_conn_accepted == 1);
@@ -421,6 +424,9 @@ TEST_IMPL(ipc_listen_before_write) {
TEST_IMPL(ipc_listen_after_write) {
+#if defined(NO_SEND_HANDLE_ON_PIPE)
+ RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE);
+#endif
int r = run_ipc_test("ipc_helper_listen_after_write", on_read);
ASSERT(local_conn_accepted == 1);
ASSERT(remote_conn_accepted == 1);
@@ -431,6 +437,9 @@ TEST_IMPL(ipc_listen_after_write) {
TEST_IMPL(ipc_tcp_connection) {
+#if defined(NO_SEND_HANDLE_ON_PIPE)
+ RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE);
+#endif
int r = run_ipc_test("ipc_helper_tcp_connection", on_read_connection);
ASSERT(read_cb_called == 1);
ASSERT(tcp_write_cb_called == 1);
@@ -491,6 +500,9 @@ TEST_IMPL(listen_no_simultaneous_accepts) {
}
TEST_IMPL(ipc_listen_after_bind_twice) {
+#if defined(NO_SEND_HANDLE_ON_PIPE)
+ RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE);
+#endif
int r = run_ipc_test("ipc_helper_bind_twice", on_read_listen_after_bound_twice);
ASSERT(read_cb_called == 2);
ASSERT(exit_cb_called == 1);
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index 3a1e82a919..3571aa2308 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -116,6 +116,7 @@ TEST_DECLARE (udp_create_early)
TEST_DECLARE (udp_create_early_bad_bind)
TEST_DECLARE (udp_create_early_bad_domain)
TEST_DECLARE (udp_send_and_recv)
+TEST_DECLARE (udp_send_hang_loop)
TEST_DECLARE (udp_send_immediate)
TEST_DECLARE (udp_send_unreachable)
TEST_DECLARE (udp_multicast_join)
@@ -153,6 +154,7 @@ TEST_DECLARE (shutdown_close_pipe)
TEST_DECLARE (shutdown_eof)
TEST_DECLARE (shutdown_twice)
TEST_DECLARE (callback_stack)
+TEST_DECLARE (env_vars)
TEST_DECLARE (error_message)
TEST_DECLARE (sys_error)
TEST_DECLARE (timer)
@@ -218,6 +220,7 @@ TEST_DECLARE (getaddrinfo_fail_sync)
TEST_DECLARE (getaddrinfo_basic)
TEST_DECLARE (getaddrinfo_basic_sync)
TEST_DECLARE (getaddrinfo_concurrent)
+TEST_DECLARE (gethostname)
TEST_DECLARE (getnameinfo_basic_ip4)
TEST_DECLARE (getnameinfo_basic_ip4_sync)
TEST_DECLARE (getnameinfo_basic_ip6)
@@ -286,6 +289,7 @@ TEST_DECLARE (fs_event_watch_file_current_dir)
#ifdef _WIN32
TEST_DECLARE (fs_event_watch_file_root_dir)
#endif
+TEST_DECLARE (fs_event_watch_invalid_path)
TEST_DECLARE (fs_event_no_callback_after_close)
TEST_DECLARE (fs_event_no_callback_on_close)
TEST_DECLARE (fs_event_immediate_close)
@@ -301,6 +305,7 @@ TEST_DECLARE (fs_open_dir)
TEST_DECLARE (fs_rename_to_existing_file)
TEST_DECLARE (fs_write_multiple_bufs)
TEST_DECLARE (fs_read_write_null_arguments)
+TEST_DECLARE (get_osfhandle_valid_handle)
TEST_DECLARE (fs_write_alotof_bufs)
TEST_DECLARE (fs_write_alotof_bufs_with_offset)
TEST_DECLARE (threadpool_queue_work_simple)
@@ -354,6 +359,8 @@ TEST_DECLARE (spawn_fs_open)
TEST_DECLARE (spawn_setuid_setgid)
TEST_DECLARE (we_get_signal)
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 (closed_fd_events)
#endif
@@ -368,6 +375,18 @@ HELPER_DECLARE (pipe_echo_server)
TEST_DECLARE (queue_foreach_delete)
+#ifndef _WIN32
+TEST_DECLARE (fork_timer)
+TEST_DECLARE (fork_socketpair)
+TEST_DECLARE (fork_socketpair_started)
+TEST_DECLARE (fork_signal_to_child)
+TEST_DECLARE (fork_signal_to_child_closed)
+TEST_DECLARE (fork_fs_events_child)
+TEST_DECLARE (fork_fs_events_child_dir)
+TEST_DECLARE (fork_fs_events_file_parent_child)
+TEST_DECLARE (fork_threadpool_queue_work_simple)
+#endif
+
TASK_LIST_START
TEST_ENTRY_CUSTOM (platform_output, 0, 1, 5000)
@@ -443,7 +462,11 @@ TASK_LIST_START
TEST_ENTRY (tcp_write_after_connect)
#endif
+#ifdef __MVS__
+ TEST_ENTRY_CUSTOM (tcp_writealot, 0, 0, 20000)
+#else
TEST_ENTRY (tcp_writealot)
+#endif
TEST_HELPER (tcp_writealot, tcp4_echo_server)
TEST_ENTRY (tcp_write_fail)
@@ -501,6 +524,7 @@ TASK_LIST_START
TEST_ENTRY (udp_create_early_bad_bind)
TEST_ENTRY (udp_create_early_bad_domain)
TEST_ENTRY (udp_send_and_recv)
+ TEST_ENTRY (udp_send_hang_loop)
TEST_ENTRY (udp_send_immediate)
TEST_ENTRY (udp_send_unreachable)
TEST_ENTRY (udp_dgram_too_big)
@@ -548,6 +572,8 @@ TASK_LIST_START
TEST_ENTRY (callback_stack)
TEST_HELPER (callback_stack, tcp4_echo_server)
+ TEST_ENTRY (env_vars)
+
TEST_ENTRY (error_message)
TEST_ENTRY (sys_error)
@@ -635,6 +661,8 @@ TASK_LIST_START
TEST_ENTRY (getaddrinfo_basic_sync)
TEST_ENTRY (getaddrinfo_concurrent)
+ TEST_ENTRY (gethostname)
+
TEST_ENTRY (getnameinfo_basic_ip4)
TEST_ENTRY (getnameinfo_basic_ip4_sync)
TEST_ENTRY (getnameinfo_basic_ip6)
@@ -704,6 +732,8 @@ TASK_LIST_START
TEST_ENTRY (spawn_setuid_setgid)
TEST_ENTRY (we_get_signal)
TEST_ENTRY (we_get_signals)
+ TEST_ENTRY (we_get_signal_one_shot)
+ TEST_ENTRY (we_get_signals_mixed)
TEST_ENTRY (signal_multiple_loops)
TEST_ENTRY (closed_fd_events)
#endif
@@ -745,6 +775,7 @@ TASK_LIST_START
#ifdef _WIN32
TEST_ENTRY (fs_event_watch_file_root_dir)
#endif
+ TEST_ENTRY (fs_event_watch_invalid_path)
TEST_ENTRY (fs_event_no_callback_after_close)
TEST_ENTRY (fs_event_no_callback_on_close)
TEST_ENTRY (fs_event_immediate_close)
@@ -762,6 +793,7 @@ TASK_LIST_START
TEST_ENTRY (fs_write_alotof_bufs)
TEST_ENTRY (fs_write_alotof_bufs_with_offset)
TEST_ENTRY (fs_read_write_null_arguments)
+ TEST_ENTRY (get_osfhandle_valid_handle)
TEST_ENTRY (threadpool_queue_work_simple)
TEST_ENTRY (threadpool_queue_work_einval)
#if defined(__PPC__) || defined(__PPC64__) /* For linux PPC and AIX */
@@ -790,6 +822,18 @@ TASK_LIST_START
TEST_ENTRY (queue_foreach_delete)
+#ifndef _WIN32
+ TEST_ENTRY (fork_timer)
+ TEST_ENTRY (fork_socketpair)
+ TEST_ENTRY (fork_socketpair_started)
+ TEST_ENTRY (fork_signal_to_child)
+ TEST_ENTRY (fork_signal_to_child_closed)
+ TEST_ENTRY (fork_fs_events_child)
+ TEST_ENTRY (fork_fs_events_child_dir)
+ TEST_ENTRY (fork_fs_events_file_parent_child)
+ TEST_ENTRY (fork_threadpool_queue_work_simple)
+#endif
+
#if 0
/* These are for testing the test runner. */
TEST_ENTRY (fail_always)
diff --git a/deps/uv/test/test-ping-pong.c b/deps/uv/test/test-ping-pong.c
index c074178541..bdc967151e 100644
--- a/deps/uv/test/test-ping-pong.c
+++ b/deps/uv/test/test-ping-pong.c
@@ -27,7 +27,11 @@
static int completed_pingers = 0;
+#if defined(__CYGWIN__) || defined(__MSYS__)
+#define NUM_PINGS 100 /* fewer pings to avoid timeout */
+#else
#define NUM_PINGS 1000
+#endif
/* 64 bytes is enough for a pinger */
#define BUFSIZE 10240
diff --git a/deps/uv/test/test-pipe-bind-error.c b/deps/uv/test/test-pipe-bind-error.c
index 38b57db699..9cf93165e4 100644
--- a/deps/uv/test/test-pipe-bind-error.c
+++ b/deps/uv/test/test-pipe-bind-error.c
@@ -116,6 +116,9 @@ TEST_IMPL(pipe_bind_error_inval) {
TEST_IMPL(pipe_listen_without_bind) {
+#if defined(NO_SELF_CONNECT)
+ RETURN_SKIP(NO_SELF_CONNECT);
+#endif
uv_pipe_t server;
int r;
diff --git a/deps/uv/test/test-pipe-connect-multiple.c b/deps/uv/test/test-pipe-connect-multiple.c
index 3de5a9a0bf..0a60d4a964 100644
--- a/deps/uv/test/test-pipe-connect-multiple.c
+++ b/deps/uv/test/test-pipe-connect-multiple.c
@@ -70,6 +70,9 @@ static void connect_cb(uv_connect_t* connect_req, int status) {
TEST_IMPL(pipe_connect_multiple) {
+#if defined(NO_SELF_CONNECT)
+ RETURN_SKIP(NO_SELF_CONNECT);
+#endif
int i;
int r;
uv_loop_t* loop;
diff --git a/deps/uv/test/test-pipe-getsockname.c b/deps/uv/test/test-pipe-getsockname.c
index 4b4ceccc45..d1628a67d5 100644
--- a/deps/uv/test/test-pipe-getsockname.c
+++ b/deps/uv/test/test-pipe-getsockname.c
@@ -87,6 +87,9 @@ static void pipe_server_connection_cb(uv_stream_t* handle, int status) {
TEST_IMPL(pipe_getsockname) {
+#if defined(NO_SELF_CONNECT)
+ RETURN_SKIP(NO_SELF_CONNECT);
+#endif
uv_loop_t* loop;
char buf[1024];
size_t len;
diff --git a/deps/uv/test/test-pipe-sendmsg.c b/deps/uv/test/test-pipe-sendmsg.c
index f6d893b449..3bf427f8aa 100644
--- a/deps/uv/test/test-pipe-sendmsg.c
+++ b/deps/uv/test/test-pipe-sendmsg.c
@@ -102,6 +102,9 @@ static void read_cb(uv_stream_t* handle,
TEST_IMPL(pipe_sendmsg) {
+#if defined(NO_SEND_HANDLE_ON_PIPE)
+ RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE);
+#endif
uv_pipe_t p;
int r;
int fds[2];
diff --git a/deps/uv/test/test-pipe-server-close.c b/deps/uv/test/test-pipe-server-close.c
index 1dcdfffaf7..ea9977dd84 100644
--- a/deps/uv/test/test-pipe-server-close.c
+++ b/deps/uv/test/test-pipe-server-close.c
@@ -61,6 +61,9 @@ static void pipe_server_connection_cb(uv_stream_t* handle, int status) {
TEST_IMPL(pipe_server_close) {
+#if defined(NO_SELF_CONNECT)
+ RETURN_SKIP(NO_SELF_CONNECT);
+#endif
uv_loop_t* loop;
int r;
diff --git a/deps/uv/test/test-platform-output.c b/deps/uv/test/test-platform-output.c
index b895508010..72c176edc4 100644
--- a/deps/uv/test/test-platform-output.c
+++ b/deps/uv/test/test-platform-output.c
@@ -47,8 +47,12 @@ TEST_IMPL(platform_output) {
printf("uv_cwd: %s\n", buffer);
err = uv_resident_set_memory(&rss);
+#if defined(__CYGWIN__) || defined(__MSYS__)
+ ASSERT(err == UV_ENOSYS);
+#else
ASSERT(err == 0);
printf("uv_resident_set_memory: %llu\n", (unsigned long long) rss);
+#endif
err = uv_uptime(&uptime);
ASSERT(err == 0);
@@ -73,6 +77,9 @@ TEST_IMPL(platform_output) {
(unsigned long long) rusage.ru_maxrss);
err = uv_cpu_info(&cpus, &count);
+#if defined(__CYGWIN__) || defined(__MSYS__)
+ ASSERT(err == UV_ENOSYS);
+#else
ASSERT(err == 0);
printf("uv_cpu_info:\n");
@@ -88,6 +95,7 @@ TEST_IMPL(platform_output) {
printf(" times.nice: %llu\n",
(unsigned long long) cpus[i].cpu_times.nice);
}
+#endif
uv_free_cpu_info(cpus, count);
err = uv_interface_addresses(&interfaces, &count);
diff --git a/deps/uv/test/test-poll.c b/deps/uv/test/test-poll.c
index 6c1f98b7ef..7cfc159a2b 100644
--- a/deps/uv/test/test-poll.c
+++ b/deps/uv/test/test-poll.c
@@ -574,6 +574,9 @@ static void start_poll_test(void) {
TEST_IMPL(poll_duplex) {
+#if defined(NO_SELF_CONNECT)
+ RETURN_SKIP(NO_SELF_CONNECT);
+#endif
test_mode = DUPLEX;
start_poll_test();
return 0;
@@ -581,6 +584,9 @@ TEST_IMPL(poll_duplex) {
TEST_IMPL(poll_unidirectional) {
+#if defined(NO_SELF_CONNECT)
+ RETURN_SKIP(NO_SELF_CONNECT);
+#endif
test_mode = UNIDIRECTIONAL;
start_poll_test();
return 0;
@@ -594,7 +600,8 @@ TEST_IMPL(poll_unidirectional) {
*/
TEST_IMPL(poll_bad_fdtype) {
#if !defined(__DragonFly__) && !defined(__FreeBSD__) && !defined(__sun) && \
- !defined(_AIX) && !defined(__MVS__) && !defined(__FreeBSD_kernel__)
+ !defined(_AIX) && !defined(__MVS__) && !defined(__FreeBSD_kernel__) && \
+ !defined(__OpenBSD__) && !defined(__CYGWIN__) && !defined(__MSYS__)
uv_poll_t poll_handle;
int fd;
diff --git a/deps/uv/test/test-process-title.c b/deps/uv/test/test-process-title.c
index 5d5ede9d60..886f83a7d3 100644
--- a/deps/uv/test/test-process-title.c
+++ b/deps/uv/test/test-process-title.c
@@ -41,7 +41,7 @@ static void set_title(const char* title) {
}
-static void uv_get_process_title_edge_cases() {
+static void uv_get_process_title_edge_cases(void) {
char buffer[512];
int r;
@@ -60,7 +60,7 @@ static void uv_get_process_title_edge_cases() {
TEST_IMPL(process_title) {
-#if defined(__sun)
+#if defined(__sun) || defined(__CYGWIN__) || defined(__MSYS__)
RETURN_SKIP("uv_(get|set)_process_title is not implemented.");
#else
/* Check for format string vulnerabilities. */
diff --git a/deps/uv/test/test-ref.c b/deps/uv/test/test-ref.c
index 39f4b0fc73..05728c8336 100644
--- a/deps/uv/test/test-ref.c
+++ b/deps/uv/test/test-ref.c
@@ -194,8 +194,8 @@ TEST_IMPL(timer_ref2) {
TEST_IMPL(fs_event_ref) {
-#if defined(__MVS__)
- RETURN_SKIP("Filesystem watching not supported on this platform.");
+#if defined(NO_FS_EVENTS)
+ RETURN_SKIP(NO_FS_EVENTS);
#endif
uv_fs_event_t h;
uv_fs_event_init(uv_default_loop(), &h);
diff --git a/deps/uv/test/test-shutdown-twice.c b/deps/uv/test/test-shutdown-twice.c
index 75c0543549..d7aae89914 100644
--- a/deps/uv/test/test-shutdown-twice.c
+++ b/deps/uv/test/test-shutdown-twice.c
@@ -67,6 +67,7 @@ TEST_IMPL(shutdown_twice) {
loop = uv_default_loop();
r = uv_tcp_init(loop, &h);
+ ASSERT(r == 0);
r = uv_tcp_connect(&connect_req,
&h,
diff --git a/deps/uv/test/test-signal-multiple-loops.c b/deps/uv/test/test-signal-multiple-loops.c
index 158129919b..11193dcf50 100644
--- a/deps/uv/test/test-signal-multiple-loops.c
+++ b/deps/uv/test/test-signal-multiple-loops.c
@@ -193,6 +193,13 @@ static void loop_creating_worker(void* context) {
TEST_IMPL(signal_multiple_loops) {
+#if defined(__CYGWIN__) || defined(__MSYS__)
+ /* FIXME: This test needs more investigation. Somehow the `read` in
+ uv__signal_lock fails spuriously with EACCES or even EAGAIN even
+ though it is supposed to be blocking. Also the test hangs during
+ thread setup occasionally. */
+ RETURN_SKIP("FIXME: This test needs more investigation on Cygwin");
+#endif
uv_thread_t loop_creating_threads[NUM_LOOP_CREATING_THREADS];
uv_thread_t signal_handling_threads[NUM_SIGNAL_HANDLING_THREADS];
enum signal_action action;
diff --git a/deps/uv/test/test-signal.c b/deps/uv/test/test-signal.c
index c0424c60a0..9a881510c7 100644
--- a/deps/uv/test/test-signal.c
+++ b/deps/uv/test/test-signal.c
@@ -70,17 +70,17 @@ struct timer_ctx {
};
struct signal_ctx {
- enum { CLOSE, STOP } stop_or_close;
+ enum { CLOSE, STOP, NOOP } stop_or_close;
unsigned int ncalls;
uv_signal_t handle;
int signum;
+ int one_shot;
};
static void signal_cb(uv_signal_t* handle, int signum) {
struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle);
ASSERT(signum == ctx->signum);
-
if (++ctx->ncalls == NSIGNALS) {
if (ctx->stop_or_close == STOP)
uv_signal_stop(handle);
@@ -91,6 +91,14 @@ static void signal_cb(uv_signal_t* handle, int signum) {
}
}
+static void signal_cb_one_shot(uv_signal_t* handle, int signum) {
+ struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle);
+ ASSERT(signum == ctx->signum);
+ ASSERT(++ctx->ncalls == 1);
+ if (ctx->stop_or_close == CLOSE)
+ uv_close((uv_handle_t*)handle, NULL);
+}
+
static void timer_cb(uv_timer_t* handle) {
struct timer_ctx* ctx = container_of(handle, struct timer_ctx, handle);
@@ -102,15 +110,21 @@ static void timer_cb(uv_timer_t* handle) {
}
-static void start_watcher(uv_loop_t* loop, int signum, struct signal_ctx* ctx) {
+static void start_watcher(uv_loop_t* loop,
+ int signum,
+ struct signal_ctx* ctx,
+ int one_shot) {
ctx->ncalls = 0;
ctx->signum = signum;
ctx->stop_or_close = CLOSE;
+ ctx->one_shot = one_shot;
ASSERT(0 == uv_signal_init(loop, &ctx->handle));
- ASSERT(0 == uv_signal_start(&ctx->handle, signal_cb, signum));
+ if (one_shot)
+ ASSERT(0 == uv_signal_start_oneshot(&ctx->handle, signal_cb_one_shot, signum));
+ else
+ ASSERT(0 == uv_signal_start(&ctx->handle, signal_cb, signum));
}
-
static void start_timer(uv_loop_t* loop, int signum, struct timer_ctx* ctx) {
ctx->ncalls = 0;
ctx->signum = signum;
@@ -126,7 +140,7 @@ TEST_IMPL(we_get_signal) {
loop = uv_default_loop();
start_timer(loop, SIGCHLD, &tc);
- start_watcher(loop, SIGCHLD, &sc);
+ start_watcher(loop, SIGCHLD, &sc, 0);
sc.stop_or_close = STOP; /* stop, don't close the signal handle */
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(tc.ncalls == NSIGNALS);
@@ -158,10 +172,10 @@ TEST_IMPL(we_get_signals) {
unsigned int i;
loop = uv_default_loop();
- start_watcher(loop, SIGUSR1, sc + 0);
- start_watcher(loop, SIGUSR1, sc + 1);
- start_watcher(loop, SIGUSR2, sc + 2);
- start_watcher(loop, SIGUSR2, sc + 3);
+ start_watcher(loop, SIGUSR1, sc + 0, 0);
+ start_watcher(loop, SIGUSR1, sc + 1, 0);
+ start_watcher(loop, SIGUSR2, sc + 2, 0);
+ start_watcher(loop, SIGUSR2, sc + 3, 0);
start_timer(loop, SIGUSR1, tc + 0);
start_timer(loop, SIGUSR2, tc + 1);
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
@@ -176,4 +190,116 @@ TEST_IMPL(we_get_signals) {
return 0;
}
+TEST_IMPL(we_get_signal_one_shot) {
+ struct signal_ctx sc;
+ struct timer_ctx tc;
+ uv_loop_t* loop;
+
+ loop = uv_default_loop();
+ start_timer(loop, SIGCHLD, &tc);
+ start_watcher(loop, SIGCHLD, &sc, 1);
+ sc.stop_or_close = NOOP;
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(tc.ncalls == NSIGNALS);
+ ASSERT(sc.ncalls == 1);
+
+ start_timer(loop, SIGCHLD, &tc);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(sc.ncalls == 1);
+
+ sc.ncalls = 0;
+ sc.stop_or_close = CLOSE; /* now close it when it's done */
+ uv_signal_start_oneshot(&sc.handle, signal_cb_one_shot, SIGCHLD);
+ start_timer(loop, SIGCHLD, &tc);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(tc.ncalls == NSIGNALS);
+ ASSERT(sc.ncalls == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+TEST_IMPL(we_get_signals_mixed) {
+ struct signal_ctx sc[4];
+ struct timer_ctx tc;
+ uv_loop_t* loop;
+
+ loop = uv_default_loop();
+
+ /* 2 one-shot */
+ start_timer(loop, SIGCHLD, &tc);
+ start_watcher(loop, SIGCHLD, sc + 0, 1);
+ start_watcher(loop, SIGCHLD, sc + 1, 1);
+ sc[0].stop_or_close = CLOSE;
+ sc[1].stop_or_close = CLOSE;
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(tc.ncalls == NSIGNALS);
+ ASSERT(sc[0].ncalls == 1);
+ ASSERT(sc[1].ncalls == 1);
+
+ /* 2 one-shot, 1 normal then remove normal */
+ start_timer(loop, SIGCHLD, &tc);
+ start_watcher(loop, SIGCHLD, sc + 0, 1);
+ start_watcher(loop, SIGCHLD, sc + 1, 1);
+ sc[0].stop_or_close = CLOSE;
+ sc[1].stop_or_close = CLOSE;
+ start_watcher(loop, SIGCHLD, sc + 2, 0);
+ uv_close((uv_handle_t*)&(sc[2]).handle, NULL);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(tc.ncalls == NSIGNALS);
+ ASSERT(sc[0].ncalls == 1);
+ ASSERT(sc[1].ncalls == 1);
+ ASSERT(sc[2].ncalls == 0);
+
+ /* 2 normal, 1 one-shot then remove one-shot */
+ start_timer(loop, SIGCHLD, &tc);
+ start_watcher(loop, SIGCHLD, sc + 0, 0);
+ start_watcher(loop, SIGCHLD, sc + 1, 0);
+ sc[0].stop_or_close = CLOSE;
+ sc[1].stop_or_close = CLOSE;
+ start_watcher(loop, SIGCHLD, sc + 2, 1);
+ uv_close((uv_handle_t*)&(sc[2]).handle, NULL);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(tc.ncalls == NSIGNALS);
+ ASSERT(sc[0].ncalls == NSIGNALS);
+ ASSERT(sc[1].ncalls == NSIGNALS);
+ ASSERT(sc[2].ncalls == 0);
+
+ /* 2 normal, 2 one-shot then remove 2 normal */
+ start_timer(loop, SIGCHLD, &tc);
+ start_watcher(loop, SIGCHLD, sc + 0, 0);
+ start_watcher(loop, SIGCHLD, sc + 1, 0);
+ start_watcher(loop, SIGCHLD, sc + 2, 1);
+ start_watcher(loop, SIGCHLD, sc + 3, 1);
+ sc[2].stop_or_close = CLOSE;
+ sc[3].stop_or_close = CLOSE;
+ uv_close((uv_handle_t*)&(sc[0]).handle, NULL);
+ uv_close((uv_handle_t*)&(sc[1]).handle, NULL);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(tc.ncalls == NSIGNALS);
+ ASSERT(sc[0].ncalls == 0);
+ ASSERT(sc[1].ncalls == 0);
+ ASSERT(sc[2].ncalls == 1);
+ ASSERT(sc[2].ncalls == 1);
+
+ /* 1 normal, 1 one-shot, 2 normal then remove 1st normal, 2nd normal */
+ start_timer(loop, SIGCHLD, &tc);
+ start_watcher(loop, SIGCHLD, sc + 0, 0);
+ start_watcher(loop, SIGCHLD, sc + 1, 1);
+ start_watcher(loop, SIGCHLD, sc + 2, 0);
+ start_watcher(loop, SIGCHLD, sc + 3, 0);
+ sc[3].stop_or_close = CLOSE;
+ uv_close((uv_handle_t*)&(sc[0]).handle, NULL);
+ uv_close((uv_handle_t*)&(sc[2]).handle, NULL);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(tc.ncalls == NSIGNALS);
+ ASSERT(sc[0].ncalls == 0);
+ ASSERT(sc[1].ncalls == 1);
+ ASSERT(sc[2].ncalls == 0);
+ ASSERT(sc[3].ncalls == NSIGNALS);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
#endif /* _WIN32 */
diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c
index 53a036969b..52fc7f6cc5 100644
--- a/deps/uv/test/test-spawn.c
+++ b/deps/uv/test/test-spawn.c
@@ -90,7 +90,16 @@ static void kill_cb(uv_process_t* process,
#else
ASSERT(exit_status == 0);
#endif
- ASSERT(no_term_signal || term_signal == 15);
+#if defined(__APPLE__)
+ /*
+ * At least starting with Darwin Kernel Version 16.4.0, sending a SIGTERM to a
+ * process that is still starting up kills it with SIGKILL instead of SIGTERM.
+ * See: https://github.com/libuv/libuv/issues/1226
+ */
+ ASSERT(no_term_signal || term_signal == SIGTERM || term_signal == SIGKILL);
+#else
+ ASSERT(no_term_signal || term_signal == SIGTERM);
+#endif
uv_close((uv_handle_t*)process, close_cb);
/*
@@ -1288,7 +1297,11 @@ TEST_IMPL(spawn_setuid_fails) {
options.uid = 0;
r = uv_spawn(uv_default_loop(), &process, &options);
+#if defined(__CYGWIN__)
+ ASSERT(r == UV_EINVAL);
+#else
ASSERT(r == UV_EPERM);
+#endif
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
@@ -1319,7 +1332,11 @@ TEST_IMPL(spawn_setgid_fails) {
options.gid = 0;
r = uv_spawn(uv_default_loop(), &process, &options);
+#if defined(__CYGWIN__)
+ ASSERT(r == UV_EINVAL);
+#else
ASSERT(r == UV_EPERM);
+#endif
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
@@ -1528,6 +1545,17 @@ TEST_IMPL(spawn_reads_child_path) {
exepath[len] = 0;
strcpy(path, "PATH=");
strcpy(path + 5, exepath);
+#if defined(__CYGWIN__) || defined(__MSYS__)
+ /* Carry over the dynamic linker path in case the test runner
+ is linked against cyguv-1.dll or msys-uv-1.dll, see above. */
+ {
+ char* syspath = getenv("PATH");
+ if (syspath != NULL) {
+ strcat(path, ":");
+ strcat(path, syspath);
+ }
+ }
+#endif
env[0] = path;
env[1] = getenv(dyld_path_var);
diff --git a/deps/uv/test/test-tcp-create-socket-early.c b/deps/uv/test/test-tcp-create-socket-early.c
index 1a508e474a..b87e732418 100644
--- a/deps/uv/test/test-tcp-create-socket-early.c
+++ b/deps/uv/test/test-tcp-create-socket-early.c
@@ -164,7 +164,7 @@ TEST_IMPL(tcp_create_early_bad_bind) {
#endif
r = uv_tcp_bind(&client, (const struct sockaddr*) &addr, 0);
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MSYS__)
ASSERT(r == UV_EINVAL);
#else
ASSERT(r == UV_EFAULT);
diff --git a/deps/uv/test/test-tcp-write-queue-order.c b/deps/uv/test/test-tcp-write-queue-order.c
index d50289c3c2..5119be6d33 100644
--- a/deps/uv/test/test-tcp-write-queue-order.c
+++ b/deps/uv/test/test-tcp-write-queue-order.c
@@ -89,6 +89,9 @@ static void connection_cb(uv_stream_t* tcp, int status) {
ASSERT(0 == uv_tcp_init(tcp->loop, &incoming));
ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming));
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &timer));
+ ASSERT(0 == uv_timer_start(&timer, timer_cb, 1, 0));
+
connection_cb_called++;
}
@@ -120,9 +123,6 @@ TEST_IMPL(tcp_write_queue_order) {
connect_cb));
ASSERT(0 == uv_send_buffer_size((uv_handle_t*) &client, &buffer_size));
- ASSERT(0 == uv_timer_init(uv_default_loop(), &timer));
- ASSERT(0 == uv_timer_start(&timer, timer_cb, 100, 0));
-
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
ASSERT(connect_cb_called == 1);
diff --git a/deps/uv/test/test-threadpool-cancel.c b/deps/uv/test/test-threadpool-cancel.c
index 917f5f4751..dd13d8ae4b 100644
--- a/deps/uv/test/test-threadpool-cancel.c
+++ b/deps/uv/test/test-threadpool-cancel.c
@@ -60,7 +60,10 @@ static void saturate_threadpool(void) {
char buf[64];
size_t i;
- snprintf(buf, sizeof(buf), "UV_THREADPOOL_SIZE=%zu", ARRAY_SIZE(pause_reqs));
+ snprintf(buf,
+ sizeof(buf),
+ "UV_THREADPOOL_SIZE=%lu",
+ (unsigned long)ARRAY_SIZE(pause_reqs));
putenv(buf);
loop = uv_default_loop();
diff --git a/deps/uv/test/test-tty.c b/deps/uv/test/test-tty.c
index 6fc2c95c98..e761822fa3 100644
--- a/deps/uv/test/test-tty.c
+++ b/deps/uv/test/test-tty.c
@@ -244,7 +244,7 @@ TEST_IMPL(tty_empty_write) {
ASSERT(r == 0);
bufs[0].len = 0;
- bufs[0].base = &dummy;
+ bufs[0].base = &dummy[0];
r = uv_try_write((uv_stream_t*) &tty_out, bufs, 1);
ASSERT(r == 0);
diff --git a/deps/uv/test/test-udp-create-socket-early.c b/deps/uv/test/test-udp-create-socket-early.c
index 3f30274047..f7e46abc98 100644
--- a/deps/uv/test/test-udp-create-socket-early.c
+++ b/deps/uv/test/test-udp-create-socket-early.c
@@ -104,7 +104,7 @@ TEST_IMPL(udp_create_early_bad_bind) {
#endif
r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0);
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MSYS__)
ASSERT(r == UV_EINVAL);
#else
ASSERT(r == UV_EFAULT);
diff --git a/deps/uv/test/test-udp-ipv6.c b/deps/uv/test/test-udp-ipv6.c
index a65f09e0c6..54b364da9e 100644
--- a/deps/uv/test/test-udp-ipv6.c
+++ b/deps/uv/test/test-udp-ipv6.c
@@ -163,6 +163,11 @@ static void do_test(uv_udp_recv_cb recv_cb, int bind_flags) {
TEST_IMPL(udp_dual_stack) {
+#if defined(__CYGWIN__) || defined(__MSYS__)
+ /* FIXME: Does Cygwin support this? */
+ RETURN_SKIP("FIXME: This test needs more investigation on Cygwin");
+#endif
+
if (!can_ipv6())
RETURN_SKIP("IPv6 not supported");
diff --git a/deps/uv/test/test-udp-send-hang-loop.c b/deps/uv/test/test-udp-send-hang-loop.c
new file mode 100644
index 0000000000..6253ff7a41
--- /dev/null
+++ b/deps/uv/test/test-udp-send-hang-loop.c
@@ -0,0 +1,99 @@
+/* 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 <stdlib.h>
+#include <string.h>
+
+#define CHECK_OBJECT(handle, type, parent) \
+ ASSERT((type*)(handle) == &(parent))
+
+static uv_udp_t client;
+static uv_idle_t idle_handle;
+static uv_udp_send_t send_req;
+static uv_buf_t buf;
+static struct sockaddr_in addr;
+static char send_data[1024];
+
+static int loop_hang_called;
+
+static void send_cb(uv_udp_send_t* req, int status);
+
+
+static void idle_cb(uv_idle_t* handle) {
+ int r;
+
+ ASSERT(send_req.handle == NULL);
+ CHECK_OBJECT(handle, uv_idle_t, idle_handle);
+ ASSERT(0 == uv_idle_stop(handle));
+
+ /* It probably would have stalled by now if it's going to stall at all. */
+ if (++loop_hang_called > 1000) {
+ uv_close((uv_handle_t*) &client, NULL);
+ uv_close((uv_handle_t*) &idle_handle, NULL);
+ return;
+ }
+
+ r = uv_udp_send(&send_req,
+ &client,
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ send_cb);
+ ASSERT(r == 0);
+}
+
+
+static void send_cb(uv_udp_send_t* req, int status) {
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+ CHECK_OBJECT(req->handle, uv_udp_t, client);
+ CHECK_OBJECT(req, uv_udp_send_t, send_req);
+ req->handle = NULL;
+
+ ASSERT(0 == uv_idle_start(&idle_handle, idle_cb));
+}
+
+
+TEST_IMPL(udp_send_hang_loop) {
+ ASSERT(0 == uv_idle_init(uv_default_loop(), &idle_handle));
+
+ /* 192.0.2.0/8 is "TEST-NET" and reserved for documentation.
+ * Good for us, though. Since we want to have something unreachable.
+ */
+ ASSERT(0 == uv_ip4_addr("192.0.2.3", TEST_PORT, &addr));
+
+ ASSERT(0 == uv_udp_init(uv_default_loop(), &client));
+
+ buf = uv_buf_init(send_data, sizeof(send_data));
+
+ ASSERT(0 == uv_idle_start(&idle_handle, idle_cb));
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(loop_hang_called > 1000);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-udp-send-immediate.c b/deps/uv/test/test-udp-send-immediate.c
index 0999f6b342..215f722572 100644
--- a/deps/uv/test/test-udp-send-immediate.c
+++ b/deps/uv/test/test-udp-send-immediate.c
@@ -136,6 +136,7 @@ TEST_IMPL(udp_send_immediate) {
1,
(const struct sockaddr*) &addr,
cl_send_cb);
+ ASSERT(r == 0);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
diff --git a/deps/uv/test/test-watcher-cross-stop.c b/deps/uv/test/test-watcher-cross-stop.c
index 6ff48d44c8..29a82a5c37 100644
--- a/deps/uv/test/test-watcher-cross-stop.c
+++ b/deps/uv/test/test-watcher-cross-stop.c
@@ -26,7 +26,12 @@
#include <errno.h>
/* NOTE: Number should be big enough to trigger this problem */
+#if defined(__CYGWIN__) || defined(__MSYS__)
+/* Cygwin crashes or hangs in socket() with too many AF_INET sockets. */
+static uv_udp_t sockets[1250];
+#else
static uv_udp_t sockets[2500];
+#endif
static uv_udp_send_t reqs[ARRAY_SIZE(sockets)];
static char slab[1];
static unsigned int recv_cb_called;