libuv 1.42.0.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3650 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
2021-07-27 22:08:18 +00:00
parent 5197eb91f7
commit da51e87774
183 changed files with 4013 additions and 1768 deletions

View File

@ -68,7 +68,7 @@ static int test_async_pummel(int nthreads) {
int i;
tids = calloc(nthreads, sizeof(tids[0]));
ASSERT(tids != NULL);
ASSERT_NOT_NULL(tids);
ASSERT(0 == uv_async_init(uv_default_loop(), &handle, async_cb));
ACCESS_ONCE(const char*, handle.data) = running;

View File

@ -79,7 +79,7 @@ static int test_async(int nthreads) {
int i;
threads = calloc(nthreads, sizeof(threads[0]));
ASSERT(threads != NULL);
ASSERT_NOT_NULL(threads);
for (i = 0; i < nthreads; i++) {
ctx = threads + i;

View File

@ -86,7 +86,7 @@ BENCHMARK_IMPL(million_async) {
timeout = 5000;
container = malloc(sizeof(*container));
ASSERT(container != NULL);
ASSERT_NOT_NULL(container);
container->async_events = 0;
container->handles_seen = 0;

View File

@ -49,7 +49,7 @@ BENCHMARK_IMPL(million_timers) {
int i;
timers = malloc(NUM_TIMERS * sizeof(timers[0]));
ASSERT(timers != NULL);
ASSERT_NOT_NULL(timers);
loop = uv_default_loop();
timeout = 0;

View File

@ -114,7 +114,7 @@ static void ipc_connection_cb(uv_stream_t* ipc_pipe, int status) {
buf = uv_buf_init("PING", 4);
sc = container_of(ipc_pipe, struct ipc_server_ctx, ipc_pipe);
pc = calloc(1, sizeof(*pc));
ASSERT(pc != NULL);
ASSERT_NOT_NULL(pc);
if (ipc_pipe->type == UV_TCP)
ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) &pc->peer_handle));
@ -295,7 +295,7 @@ static void sv_connection_cb(uv_stream_t* server_handle, int status) {
ASSERT(status == 0);
storage = malloc(sizeof(*storage));
ASSERT(storage != NULL);
ASSERT_NOT_NULL(storage);
if (server_handle->type == UV_TCP)
ASSERT(0 == uv_tcp_init(server_handle->loop, (uv_tcp_t*) storage));
@ -372,8 +372,8 @@ static int test_tcp(unsigned int num_servers, unsigned int num_clients) {
servers = calloc(num_servers, sizeof(servers[0]));
clients = calloc(num_clients, sizeof(clients[0]));
ASSERT(servers != NULL);
ASSERT(clients != NULL);
ASSERT_NOT_NULL(servers);
ASSERT_NOT_NULL(clients);
/* We're making the assumption here that from the perspective of the
* OS scheduler, threads are functionally equivalent to and interchangeable

View File

@ -114,11 +114,11 @@ static void connect_cb(uv_connect_t* req, int status) {
return;
}
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
conn = (conn_rec*)req->data;
ASSERT(conn != NULL);
ASSERT_NOT_NULL(conn);
#if DEBUG
printf("connect_cb %d\n", conn->i);
@ -137,7 +137,7 @@ static void connect_cb(uv_connect_t* req, int status) {
static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
ASSERT(stream != NULL);
ASSERT_NOT_NULL(stream);
#if DEBUG
printf("read_cb %d\n", p->i);
@ -161,7 +161,7 @@ static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
static void close_cb(uv_handle_t* handle) {
conn_rec* p = (conn_rec*)handle->data;
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
closed_streams++;
#if DEBUG

View File

@ -390,6 +390,7 @@ HELPER_IMPL(tcp_pump_server) {
r = uv_listen((uv_stream_t*)&tcpServer, MAX_WRITE_HANDLES, connection_cb);
ASSERT(r == 0);
notify_parent_process();
uv_run(loop, UV_RUN_DEFAULT);
return 0;
@ -411,6 +412,7 @@ HELPER_IMPL(pipe_pump_server) {
r = uv_listen((uv_stream_t*)&pipeServer, MAX_WRITE_HANDLES, connection_cb);
ASSERT(r == 0);
notify_parent_process();
uv_run(loop, UV_RUN_DEFAULT);
MAKE_VALGRIND_HAPPY();

View File

@ -71,7 +71,7 @@ static void connect_cb(uv_connect_t* req, int status) {
static void write_cb(uv_write_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
write_cb_called++;
}
@ -103,7 +103,7 @@ BENCHMARK_IMPL(tcp_write_batch) {
int r;
write_reqs = malloc(sizeof(*write_reqs) * NUM_WRITE_REQS);
ASSERT(write_reqs != NULL);
ASSERT_NOT_NULL(write_reqs);
/* Prepare the data to write out. */
for (i = 0; i < NUM_WRITE_REQS; i++) {

View File

@ -72,7 +72,7 @@ static void alloc_cb(uv_handle_t* handle,
static void send_cb(uv_udp_send_t* req, int status) {
struct sender_state* s;
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
if (status != 0) {
ASSERT(status == UV_ECANCELED);
@ -127,7 +127,7 @@ static void recv_cb(uv_udp_t* handle,
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}
@ -179,11 +179,11 @@ static int pummel(unsigned int n_senders,
uv_unref((uv_handle_t*)&s->udp_handle);
}
bufs[0] = uv_buf_init(EXPECTED + 0, 10);
bufs[1] = uv_buf_init(EXPECTED + 10, 10);
bufs[2] = uv_buf_init(EXPECTED + 20, 10);
bufs[3] = uv_buf_init(EXPECTED + 30, 10);
bufs[4] = uv_buf_init(EXPECTED + 40, 5);
bufs[0] = uv_buf_init(&EXPECTED[0], 10);
bufs[1] = uv_buf_init(&EXPECTED[10], 10);
bufs[2] = uv_buf_init(&EXPECTED[20], 10);
bufs[3] = uv_buf_init(&EXPECTED[30], 10);
bufs[4] = uv_buf_init(&EXPECTED[40], 5);
for (i = 0; i < n_senders; i++) {
struct sender_state* s = senders + i;

View File

@ -47,7 +47,7 @@ static void connection_cb(uv_stream_t* stream, int status) {
ASSERT(stream == (uv_stream_t*)&tcp_server);
conn = malloc(sizeof *conn);
ASSERT(conn != NULL);
ASSERT_NOT_NULL(conn);
r = uv_tcp_init(stream->loop, &conn->handle);
ASSERT(r == 0);
@ -114,6 +114,7 @@ HELPER_IMPL(tcp4_blackhole_server) {
r = uv_listen((uv_stream_t*)&tcp_server, 128, connection_cb);
ASSERT(r == 0);
notify_parent_process();
r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(0 && "Blackhole server dropped out of event loop.");

View File

@ -280,7 +280,7 @@ static void on_connection(uv_stream_t* server, int status) {
ASSERT(status == 0);
handle = (dnshandle*) malloc(sizeof *handle);
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
/* initialize read buffer state */
handle->state.prevbuf_ptr = 0;

View File

@ -65,25 +65,35 @@ static void after_write(uv_write_t* req, int status) {
static void after_shutdown(uv_shutdown_t* req, int status) {
ASSERT_EQ(status, 0);
uv_close((uv_handle_t*) req->handle, on_close);
free(req);
}
static void on_shutdown(uv_shutdown_t* req, int status) {
ASSERT_EQ(status, 0);
free(req);
}
static void after_read(uv_stream_t* handle,
ssize_t nread,
const uv_buf_t* buf) {
int i;
write_req_t *wr;
uv_shutdown_t* sreq;
int shutdown = 0;
if (nread < 0) {
/* Error or EOF */
ASSERT(nread == UV_EOF);
ASSERT_EQ(nread, UV_EOF);
free(buf->base);
sreq = malloc(sizeof* sreq);
ASSERT(0 == uv_shutdown(sreq, handle, after_shutdown));
if (uv_is_writable(handle)) {
ASSERT_EQ(0, uv_shutdown(sreq, handle, after_shutdown));
}
return;
}
@ -96,29 +106,42 @@ static void after_read(uv_stream_t* handle,
/*
* Scan for the letter Q which signals that we should quit the server.
* If we get QS it means close the stream.
* If we get QSS it means shutdown the stream.
* If we get QSH it means disable linger before close the socket.
*/
if (!server_closed) {
for (i = 0; i < nread; i++) {
if (buf->base[i] == 'Q') {
if (i + 1 < nread && buf->base[i + 1] == 'S') {
free(buf->base);
uv_close((uv_handle_t*)handle, on_close);
return;
} else {
uv_close(server, on_server_close);
server_closed = 1;
}
for (i = 0; i < nread; i++) {
if (buf->base[i] == 'Q') {
if (i + 1 < nread && buf->base[i + 1] == 'S') {
int reset = 0;
if (i + 2 < nread && buf->base[i + 2] == 'S')
shutdown = 1;
if (i + 2 < nread && buf->base[i + 2] == 'H')
reset = 1;
if (reset && handle->type == UV_TCP)
ASSERT_EQ(0, uv_tcp_close_reset((uv_tcp_t*) handle, on_close));
else if (shutdown)
break;
else
uv_close((uv_handle_t*) handle, on_close);
free(buf->base);
return;
} else if (!server_closed) {
uv_close(server, on_server_close);
server_closed = 1;
}
}
}
wr = (write_req_t*) malloc(sizeof *wr);
ASSERT(wr != NULL);
ASSERT_NOT_NULL(wr);
wr->buf = uv_buf_init(buf->base, nread);
if (uv_write(&wr->req, handle, &wr->buf, 1, after_write)) {
FATAL("uv_write failed");
}
if (shutdown)
ASSERT_EQ(0, uv_shutdown(malloc(sizeof* sreq), handle, on_shutdown));
}
@ -155,14 +178,14 @@ static void on_connection(uv_stream_t* server, int status) {
switch (serverType) {
case TCP:
stream = malloc(sizeof(uv_tcp_t));
ASSERT(stream != NULL);
ASSERT_NOT_NULL(stream);
r = uv_tcp_init(loop, (uv_tcp_t*)stream);
ASSERT(r == 0);
break;
case PIPE:
stream = malloc(sizeof(uv_pipe_t));
ASSERT(stream != NULL);
ASSERT_NOT_NULL(stream);
r = uv_pipe_init(loop, (uv_pipe_t*)stream, 0);
ASSERT(r == 0);
break;
@ -197,7 +220,7 @@ static uv_udp_send_t* send_alloc(void) {
}
static void on_send(uv_udp_send_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
req->data = send_freelist;
send_freelist = req;
@ -209,6 +232,7 @@ static void on_recv(uv_udp_t* handle,
const struct sockaddr* addr,
unsigned flags) {
uv_buf_t sndbuf;
uv_udp_send_t* req;
if (nread == 0) {
/* Everything OK, but nothing read. */
@ -218,8 +242,8 @@ static void on_recv(uv_udp_t* handle,
ASSERT(nread > 0);
ASSERT(addr->sa_family == AF_INET);
uv_udp_send_t* req = send_alloc();
ASSERT(req != NULL);
req = send_alloc();
ASSERT_NOT_NULL(req);
sndbuf = uv_buf_init(rcvbuf->base, nread);
ASSERT(0 <= uv_udp_send(req, handle, &sndbuf, 1, addr, on_send));
}
@ -228,7 +252,7 @@ static int tcp4_echo_start(int port) {
struct sockaddr_in addr;
int r;
ASSERT(0 == uv_ip4_addr("0.0.0.0", port, &addr));
ASSERT(0 == uv_ip4_addr("127.0.0.1", port, &addr));
server = (uv_handle_t*)&tcpServer;
serverType = TCP;

View File

@ -28,6 +28,16 @@
/* Actual benchmarks and helpers are defined in benchmark-list.h */
#include "benchmark-list.h"
#ifdef __MVS__
#include "zos-base.h"
/* Initialize environment and zoslib */
__attribute__((constructor)) void init() {
zoslib_config_t config;
init_zoslib_config(&config);
init_zoslib(config);
}
#endif
static int maybe_run_test(int argc, char **argv);
@ -44,8 +54,6 @@ int main(int argc, char **argv) {
fflush(stderr);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

View File

@ -36,6 +36,16 @@
/* Actual tests and helpers are defined in test-list.h */
#include "test-list.h"
#ifdef __MVS__
#include "zos-base.h"
/* Initialize environment and zoslib */
__attribute__((constructor)) void init() {
zoslib_config_t config;
init_zoslib_config(&config);
init_zoslib(config);
}
#endif
int ipc_helper(int listen_after_write);
int ipc_helper_heavy_traffic_deadlock_bug(void);
int ipc_helper_tcp_connection(void);
@ -50,6 +60,10 @@ int spawn_tcp_server_helper(void);
static int maybe_run_test(int argc, char **argv);
#ifdef _WIN32
typedef BOOL (WINAPI *sCompareObjectHandles)(_In_ HANDLE, _In_ HANDLE);
#endif
int main(int argc, char **argv) {
#ifndef _WIN32
@ -149,7 +163,7 @@ static int maybe_run_test(int argc, char **argv) {
if (strcmp(argv[1], "spawn_helper4") == 0) {
notify_parent_process();
/* Never surrender, never return! */
while (1) uv_sleep(10000);
for (;;) uv_sleep(10000);
}
if (strcmp(argv[1], "spawn_helper5") == 0) {
@ -194,7 +208,7 @@ static int maybe_run_test(int argc, char **argv) {
/* Test if the test value from the parent is still set */
test = getenv("ENV_TEST");
ASSERT(test != NULL);
ASSERT_NOT_NULL(test);
r = fprintf(stdout, "%s", test);
ASSERT(r > 0);
@ -202,22 +216,36 @@ static int maybe_run_test(int argc, char **argv) {
return 1;
}
#ifndef _WIN32
if (strcmp(argv[1], "spawn_helper8") == 0) {
int fd;
uv_os_fd_t closed_fd;
uv_os_fd_t open_fd;
#ifdef _WIN32
DWORD flags;
HMODULE kernelbase_module;
sCompareObjectHandles pCompareObjectHandles; /* function introduced in Windows 10 */
#endif
notify_parent_process();
ASSERT(sizeof(fd) == read(0, &fd, sizeof(fd)));
ASSERT(fd > 2);
ASSERT(sizeof(closed_fd) == read(0, &closed_fd, sizeof(closed_fd)));
ASSERT(sizeof(open_fd) == read(0, &open_fd, sizeof(open_fd)));
#ifdef _WIN32
ASSERT((intptr_t) closed_fd > 0);
ASSERT((intptr_t) open_fd > 0);
ASSERT(0 != GetHandleInformation(open_fd, &flags));
kernelbase_module = GetModuleHandleA("kernelbase.dll");
pCompareObjectHandles = (sCompareObjectHandles)
GetProcAddress(kernelbase_module, "CompareObjectHandles");
ASSERT(pCompareObjectHandles == NULL || !pCompareObjectHandles(open_fd, closed_fd));
#else
ASSERT(open_fd > 2);
ASSERT(closed_fd > 2);
# if defined(__PASE__) /* On IBMi PASE, write() returns 1 */
ASSERT(1 == write(fd, "x", 1));
ASSERT(1 == write(closed_fd, "x", 1));
# else
ASSERT(-1 == write(fd, "x", 1));
ASSERT(-1 == write(closed_fd, "x", 1));
# endif /* !__PASE__ */
#endif
return 1;
}
#endif /* !_WIN32 */
if (strcmp(argv[1], "spawn_helper9") == 0) {
notify_parent_process();

View File

@ -197,7 +197,7 @@ static void* dowait(void* data) {
process_info_t* p;
for (i = 0; i < args->n; i++) {
p = (process_info_t*)(args->vec + i * sizeof(process_info_t));
p = &args->vec[i];
if (p->terminated) continue;
r = waitpid(p->pid, &p->status, 0);
if (r < 0) {
@ -323,7 +323,7 @@ int process_wait(process_info_t* vec, int n, int timeout) {
} else {
/* Timeout. Kill all the children. */
for (i = 0; i < n; i++) {
p = (process_info_t*)(vec + i * sizeof(process_info_t));
p = &vec[i];
kill(p->pid, SIGTERM);
}
retval = -2;

View File

@ -98,8 +98,8 @@ int run_tests(int benchmark_output) {
skip = (actual > 0 && 0 == strcmp(TASKS[0].task_name, "platform_output"));
qsort(TASKS + skip, actual - skip, sizeof(TASKS[0]), compare_task);
fprintf(stderr, "1..%d\n", total);
fflush(stderr);
fprintf(stdout, "1..%d\n", total);
fflush(stdout);
/* Run all tests. */
passed = 0;
@ -156,8 +156,8 @@ void log_tap_result(int test_count,
reason[0] = '\0';
}
fprintf(stderr, "%s %d - %s%s%s\n", result, test_count, test, directive, reason);
fflush(stderr);
fprintf(stdout, "%s %d - %s%s%s\n", result, test_count, test, directive, reason);
fflush(stdout);
}
@ -307,28 +307,28 @@ out:
/* Show error and output from processes if the test failed. */
if ((status != TEST_OK && status != TEST_SKIP) || task->show_output) {
if (strlen(errmsg) > 0)
fprintf(stderr, "# %s\n", errmsg);
fprintf(stderr, "# ");
fflush(stderr);
fprintf(stdout, "# %s\n", errmsg);
fprintf(stdout, "# ");
fflush(stdout);
for (i = 0; i < process_count; i++) {
switch (process_output_size(&processes[i])) {
case -1:
fprintf(stderr, "Output from process `%s`: (unavailable)\n",
fprintf(stdout, "Output from process `%s`: (unavailable)\n",
process_get_name(&processes[i]));
fflush(stderr);
fflush(stdout);
break;
case 0:
fprintf(stderr, "Output from process `%s`: (no output)\n",
fprintf(stdout, "Output from process `%s`: (no output)\n",
process_get_name(&processes[i]));
fflush(stderr);
fflush(stdout);
break;
default:
fprintf(stderr, "Output from process `%s`:\n", process_get_name(&processes[i]));
fflush(stderr);
process_copy_output(&processes[i], stderr);
fprintf(stdout, "Output from process `%s`:\n", process_get_name(&processes[i]));
fflush(stdout);
process_copy_output(&processes[i], stdout);
break;
}
}
@ -337,18 +337,18 @@ out:
} else if (benchmark_output) {
switch (process_output_size(main_proc)) {
case -1:
fprintf(stderr, "%s: (unavailable)\n", test);
fflush(stderr);
fprintf(stdout, "%s: (unavailable)\n", test);
fflush(stdout);
break;
case 0:
fprintf(stderr, "%s: (no output)\n", test);
fflush(stderr);
fprintf(stdout, "%s: (no output)\n", test);
fflush(stdout);
break;
default:
for (i = 0; i < process_count; i++) {
process_copy_output(&processes[i], stderr);
process_copy_output(&processes[i], stdout);
}
break;
}
@ -378,8 +378,8 @@ int run_test_part(const char* test, const char* part) {
}
}
fprintf(stderr, "No test part with that name: %s:%s\n", test, part);
fflush(stderr);
fprintf(stdout, "No test part with that name: %s:%s\n", test, part);
fflush(stdout);
return 255;
}

View File

@ -52,6 +52,7 @@
#define TEST_PORT 9123
#define TEST_PORT_2 9124
#define TEST_PORT_3 9125
#ifdef _WIN32
# define TEST_PIPENAME "\\\\?\\pipe\\uv-test"
@ -113,8 +114,8 @@ typedef enum {
#define ASSERT_BASE(a, operator, b, type, conv) \
do { \
type eval_a = (type) (a); \
type eval_b = (type) (b); \
volatile type eval_a = (type) (a); \
volatile type eval_b = (type) (b); \
if (!(eval_a operator eval_b)) { \
fprintf(stderr, \
"Assertion failed in %s on line %d: `%s %s %s` " \
@ -196,22 +197,26 @@ typedef enum {
} \
} while (0)
#define ASSERT_INT_BASE(a, operator, b, type, conv) \
ASSERT_BASE(a, operator, b, type, conv)
#define ASSERT_EQ(a, b) ASSERT_BASE(a, ==, b, int64_t, PRId64)
#define ASSERT_GE(a, b) ASSERT_BASE(a, >=, b, int64_t, PRId64)
#define ASSERT_GT(a, b) ASSERT_BASE(a, >, b, int64_t, PRId64)
#define ASSERT_LE(a, b) ASSERT_BASE(a, <=, b, int64_t, PRId64)
#define ASSERT_LT(a, b) ASSERT_BASE(a, <, b, int64_t, PRId64)
#define ASSERT_NE(a, b) ASSERT_BASE(a, !=, b, int64_t, PRId64)
#define ASSERT_EQ(a, b) ASSERT_INT_BASE(a, ==, b, int64_t, PRId64)
#define ASSERT_GE(a, b) ASSERT_INT_BASE(a, >=, b, int64_t, PRId64)
#define ASSERT_GT(a, b) ASSERT_INT_BASE(a, >, b, int64_t, PRId64)
#define ASSERT_LE(a, b) ASSERT_INT_BASE(a, <=, b, int64_t, PRId64)
#define ASSERT_LT(a, b) ASSERT_INT_BASE(a, <, b, int64_t, PRId64)
#define ASSERT_NE(a, b) ASSERT_INT_BASE(a, !=, b, int64_t, PRId64)
#define ASSERT_UINT64_EQ(a, b) ASSERT_BASE(a, ==, b, uint64_t, PRIu64)
#define ASSERT_UINT64_GE(a, b) ASSERT_BASE(a, >=, b, uint64_t, PRIu64)
#define ASSERT_UINT64_GT(a, b) ASSERT_BASE(a, >, b, uint64_t, PRIu64)
#define ASSERT_UINT64_LE(a, b) ASSERT_BASE(a, <=, b, uint64_t, PRIu64)
#define ASSERT_UINT64_LT(a, b) ASSERT_BASE(a, <, b, uint64_t, PRIu64)
#define ASSERT_UINT64_NE(a, b) ASSERT_BASE(a, !=, b, uint64_t, PRIu64)
#define ASSERT_UINT64_EQ(a, b) ASSERT_INT_BASE(a, ==, b, uint64_t, PRIu64)
#define ASSERT_UINT64_GE(a, b) ASSERT_INT_BASE(a, >=, b, uint64_t, PRIu64)
#define ASSERT_UINT64_GT(a, b) ASSERT_INT_BASE(a, >, b, uint64_t, PRIu64)
#define ASSERT_UINT64_LE(a, b) ASSERT_INT_BASE(a, <=, b, uint64_t, PRIu64)
#define ASSERT_UINT64_LT(a, b) ASSERT_INT_BASE(a, <, b, uint64_t, PRIu64)
#define ASSERT_UINT64_NE(a, b) ASSERT_INT_BASE(a, !=, b, uint64_t, PRIu64)
#define ASSERT_DOUBLE_EQ(a, b) ASSERT_BASE(a, ==, b, double, "f")
#define ASSERT_DOUBLE_GE(a, b) ASSERT_BASE(a, >=, b, double, "f")
#define ASSERT_DOUBLE_GT(a, b) ASSERT_BASE(a, >, b, double, "f")
#define ASSERT_DOUBLE_LE(a, b) ASSERT_BASE(a, <=, b, double, "f")
#define ASSERT_DOUBLE_LT(a, b) ASSERT_BASE(a, <, b, double, "f")
#define ASSERT_DOUBLE_NE(a, b) ASSERT_BASE(a, !=, b, double, "f")
#define ASSERT_STR_EQ(a, b) \
ASSERT_BASE_STR(strcmp(a, b) == 0, a, == , b, char*, "s")

View File

@ -30,7 +30,7 @@ static int close_cb_called = 0;
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}

View File

@ -70,7 +70,7 @@ static void thread_cb(void *arg) {
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}

View File

@ -48,7 +48,7 @@ static int shutdown_cb_called = 0;
static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
buf->len = size;
buf->base = malloc(size);
ASSERT(buf->base != NULL);
ASSERT_NOT_NULL(buf->base);
}

View File

@ -19,12 +19,11 @@
* IN THE SOFTWARE.
*/
#if !defined(_WIN32)
#include "uv.h"
#include "task.h"
#include <fcntl.h>
#ifndef _WIN32
#include <unistd.h>
#endif
static unsigned int read_cb_called;
@ -51,14 +50,25 @@ static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
TEST_IMPL(close_fd) {
uv_pipe_t pipe_handle;
int fd[2];
uv_fs_t req;
uv_buf_t bufs[1];
uv_file fd[2];
bufs[0] = uv_buf_init("", 1);
ASSERT(0 == pipe(fd));
ASSERT(0 == uv_pipe(fd, 0, 0));
ASSERT(0 == uv_pipe_init(uv_default_loop(), &pipe_handle, 0));
ASSERT(0 == uv_pipe_open(&pipe_handle, fd[0]));
fd[0] = -1; /* uv_pipe_open() takes ownership of the file descriptor. */
ASSERT(1 == write(fd[1], "", 1));
/* uv_pipe_open() takes ownership of the file descriptor. */
fd[0] = -1;
ASSERT(1 == uv_fs_write(NULL, &req, fd[1], bufs, 1, -1, NULL));
ASSERT(1 == req.result);
uv_fs_req_cleanup(&req);
#ifdef _WIN32
ASSERT(0 == _close(fd[1]));
#else
ASSERT(0 == close(fd[1]));
#endif
fd[1] = -1;
ASSERT(0 == uv_read_start((uv_stream_t *) &pipe_handle, alloc_cb, read_cb));
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
@ -72,9 +82,3 @@ TEST_IMPL(close_fd) {
MAKE_VALGRIND_HAPPY();
return 0;
}
#else
typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */
#endif /* !_WIN32 */

View File

@ -32,7 +32,7 @@ static uv_timer_t timer_handle2;
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}

View File

@ -37,7 +37,7 @@ TEST_IMPL(default_loop_close) {
uv_timer_t timer_handle;
loop = uv_default_loop();
ASSERT(loop != NULL);
ASSERT_NOT_NULL(loop);
ASSERT(0 == uv_timer_init(loop, &timer_handle));
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0));
@ -46,7 +46,7 @@ TEST_IMPL(default_loop_close) {
ASSERT(0 == uv_loop_close(loop));
loop = uv_default_loop();
ASSERT(loop != NULL);
ASSERT_NOT_NULL(loop);
ASSERT(0 == uv_timer_init(loop, &timer_handle));
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0));

View File

@ -37,7 +37,7 @@ static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
free(handle);
@ -50,8 +50,8 @@ static void do_accept(uv_timer_t* timer_handle) {
uv_tcp_t* accepted_handle = (uv_tcp_t*)malloc(sizeof *accepted_handle);
int r;
ASSERT(timer_handle != NULL);
ASSERT(accepted_handle != NULL);
ASSERT_NOT_NULL(timer_handle);
ASSERT_NOT_NULL(accepted_handle);
r = uv_tcp_init(uv_default_loop(), accepted_handle);
ASSERT(r == 0);
@ -82,7 +82,7 @@ static void connection_cb(uv_stream_t* tcp, int status) {
ASSERT(status == 0);
timer_handle = (uv_timer_t*)malloc(sizeof *timer_handle);
ASSERT(timer_handle != NULL);
ASSERT_NOT_NULL(timer_handle);
/* Accept the client after 1 second */
r = uv_timer_init(uv_default_loop(), timer_handle);
@ -103,7 +103,7 @@ static void start_server(void) {
int r;
ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
ASSERT(server != NULL);
ASSERT_NOT_NULL(server);
r = uv_tcp_init(uv_default_loop(), server);
ASSERT(r == 0);
@ -125,7 +125,7 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
if (nread >= 0) {
ASSERT(nread == 0);
} else {
ASSERT(tcp != NULL);
ASSERT_NOT_NULL(tcp);
ASSERT(nread == UV_EOF);
uv_close((uv_handle_t*)tcp, close_cb);
}
@ -135,7 +135,7 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
static void connect_cb(uv_connect_t* req, int status) {
int r;
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
/* Not that the server will send anything, but otherwise we'll never know
@ -156,8 +156,8 @@ static void client_connect(void) {
int r;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
ASSERT(client != NULL);
ASSERT(connect_req != NULL);
ASSERT_NOT_NULL(client);
ASSERT_NOT_NULL(connect_req);
r = uv_tcp_init(uv_default_loop(), client);
ASSERT(r == 0);

View File

@ -34,26 +34,26 @@ TEST_IMPL(dlerror) {
lib.errmsg = NULL;
lib.handle = NULL;
msg = uv_dlerror(&lib);
ASSERT(msg != NULL);
ASSERT(strstr(msg, dlerror_no_error) != NULL);
ASSERT_NOT_NULL(msg);
ASSERT_NOT_NULL(strstr(msg, dlerror_no_error));
r = uv_dlopen(path, &lib);
ASSERT(r == -1);
msg = uv_dlerror(&lib);
ASSERT(msg != NULL);
ASSERT_NOT_NULL(msg);
#if !defined(__OpenBSD__) && !defined(__QNX__)
ASSERT(strstr(msg, path) != NULL);
ASSERT_NOT_NULL(strstr(msg, path));
#endif
ASSERT(strstr(msg, dlerror_no_error) == NULL);
ASSERT_NULL(strstr(msg, dlerror_no_error));
/* Should return the same error twice in a row. */
msg = uv_dlerror(&lib);
ASSERT(msg != NULL);
ASSERT_NOT_NULL(msg);
#if !defined(__OpenBSD__) && !defined(__QNX__)
ASSERT(strstr(msg, path) != NULL);
ASSERT_NOT_NULL(strstr(msg, path));
#endif
ASSERT(strstr(msg, dlerror_no_error) == NULL);
ASSERT_NULL(strstr(msg, dlerror_no_error));
uv_dlclose(&lib);

View File

@ -37,6 +37,9 @@
* See https://github.com/joyent/libuv/issues/210
*/
TEST_IMPL(error_message) {
#if defined(__ASAN__)
RETURN_SKIP("Test does not currently work in ASAN");
#endif
char buf[32];
/* Cop out. Can't do proper checks on systems with
@ -47,13 +50,13 @@ TEST_IMPL(error_message) {
return 0;
}
ASSERT(strstr(uv_strerror(UV_EINVAL), "Success") == NULL);
ASSERT_NULL(strstr(uv_strerror(UV_EINVAL), "Success"));
ASSERT(strcmp(uv_strerror(1337), "Unknown error") == 0);
ASSERT(strcmp(uv_strerror(-1337), "Unknown error") == 0);
ASSERT(strstr(uv_strerror_r(UV_EINVAL, buf, sizeof(buf)), "Success") == NULL);
ASSERT(strstr(uv_strerror_r(1337, buf, sizeof(buf)), "1337") != NULL);
ASSERT(strstr(uv_strerror_r(-1337, buf, sizeof(buf)), "-1337") != NULL);
ASSERT_NULL(strstr(uv_strerror_r(UV_EINVAL, buf, sizeof(buf)), "Success"));
ASSERT_NOT_NULL(strstr(uv_strerror_r(1337, buf, sizeof(buf)), "1337"));
ASSERT_NOT_NULL(strstr(uv_strerror_r(-1337, buf, sizeof(buf)), "-1337"));
return 0;
}

View File

@ -96,6 +96,9 @@ 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;

View File

@ -118,7 +118,7 @@ static void touch_file(const char* name) {
}
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}
@ -337,7 +337,7 @@ static void fs_event_cb_file(uv_fs_event_t* handle, const char* filename,
static void timer_cb_close_handle(uv_timer_t* timer) {
uv_handle_t* handle;
ASSERT(timer != NULL);
ASSERT_NOT_NULL(timer);
handle = timer->data;
uv_close((uv_handle_t*)timer, NULL);
@ -673,6 +673,9 @@ TEST_IMPL(fs_event_watch_file_exact_path) {
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];
@ -755,7 +758,7 @@ TEST_IMPL(fs_event_watch_file_root_dir) {
const char* sys_drive = getenv("SystemDrive");
char path[] = "\\\\?\\X:\\bootsect.bak";
ASSERT(sys_drive != NULL);
ASSERT_NOT_NULL(sys_drive);
strncpy(path + sizeof("\\\\?\\") - 1, sys_drive, 1);
loop = uv_default_loop();
@ -1069,7 +1072,7 @@ static void timer_cb_nop(uv_timer_t* handle) {
}
static void fs_event_error_report_close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
/* handle is allocated on-stack, no need to free it */

View File

@ -105,8 +105,8 @@ static void poll_cb(uv_fs_poll_t* handle,
ASSERT(handle == &poll_handle);
ASSERT(1 == uv_is_active((uv_handle_t*) handle));
ASSERT(prev != NULL);
ASSERT(curr != NULL);
ASSERT_NOT_NULL(prev);
ASSERT_NOT_NULL(curr);
switch (poll_cb_called++) {
case 0:

View File

@ -77,7 +77,7 @@ static void empty_opendir_cb(uv_fs_t* req) {
ASSERT(req == &opendir_req);
ASSERT(req->fs_type == UV_FS_OPENDIR);
ASSERT(req->result == 0);
ASSERT(req->ptr != NULL);
ASSERT_NOT_NULL(req->ptr);
dir = req->ptr;
dir->dirents = dirents;
dir->nentries = ARRAY_SIZE(dirents);
@ -118,7 +118,7 @@ TEST_IMPL(fs_readdir_empty_dir) {
ASSERT(r == 0);
ASSERT(opendir_req.fs_type == UV_FS_OPENDIR);
ASSERT(opendir_req.result == 0);
ASSERT(opendir_req.ptr != NULL);
ASSERT_NOT_NULL(opendir_req.ptr);
dir = opendir_req.ptr;
uv_fs_req_cleanup(&opendir_req);
@ -171,7 +171,7 @@ static void non_existing_opendir_cb(uv_fs_t* req) {
ASSERT(req == &opendir_req);
ASSERT(req->fs_type == UV_FS_OPENDIR);
ASSERT(req->result == UV_ENOENT);
ASSERT(req->ptr == NULL);
ASSERT_NULL(req->ptr);
uv_fs_req_cleanup(req);
++non_existing_opendir_cb_count;
@ -191,7 +191,7 @@ TEST_IMPL(fs_readdir_non_existing_dir) {
ASSERT(r == UV_ENOENT);
ASSERT(opendir_req.fs_type == UV_FS_OPENDIR);
ASSERT(opendir_req.result == UV_ENOENT);
ASSERT(opendir_req.ptr == NULL);
ASSERT_NULL(opendir_req.ptr);
uv_fs_req_cleanup(&opendir_req);
/* Fill the req to ensure that required fields are cleaned up. */
@ -223,13 +223,16 @@ static void file_opendir_cb(uv_fs_t* req) {
ASSERT(req == &opendir_req);
ASSERT(req->fs_type == UV_FS_OPENDIR);
ASSERT(req->result == UV_ENOTDIR);
ASSERT(req->ptr == NULL);
ASSERT_NULL(req->ptr);
uv_fs_req_cleanup(req);
++file_opendir_cb_count;
}
TEST_IMPL(fs_readdir_file) {
#if defined(__ASAN__)
RETURN_SKIP("Test does not currently work in ASAN");
#endif
const char* path;
int r;
@ -244,7 +247,7 @@ TEST_IMPL(fs_readdir_file) {
ASSERT(r == UV_ENOTDIR);
ASSERT(opendir_req.fs_type == UV_FS_OPENDIR);
ASSERT(opendir_req.result == UV_ENOTDIR);
ASSERT(opendir_req.ptr == NULL);
ASSERT_NULL(opendir_req.ptr);
uv_fs_req_cleanup(&opendir_req);
@ -326,7 +329,7 @@ static void non_empty_opendir_cb(uv_fs_t* req) {
ASSERT(req == &opendir_req);
ASSERT(req->fs_type == UV_FS_OPENDIR);
ASSERT(req->result == 0);
ASSERT(req->ptr != NULL);
ASSERT_NOT_NULL(req->ptr);
dir = req->ptr;
dir->dirents = dirents;
@ -400,7 +403,7 @@ TEST_IMPL(fs_readdir_non_empty_dir) {
ASSERT(r == 0);
ASSERT(opendir_req.fs_type == UV_FS_OPENDIR);
ASSERT(opendir_req.result == 0);
ASSERT(opendir_req.ptr != NULL);
ASSERT_NOT_NULL(opendir_req.ptr);
entries_count = 0;
dir = opendir_req.ptr;

View File

@ -343,7 +343,7 @@ static void statfs_cb(uv_fs_t* req) {
ASSERT(req->fs_type == UV_FS_STATFS);
ASSERT(req->result == 0);
ASSERT(req->ptr != NULL);
ASSERT_NOT_NULL(req->ptr);
stats = req->ptr;
#if defined(_WIN32) || defined(__sun) || defined(_AIX) || defined(__MVS__) || \
@ -366,7 +366,7 @@ static void statfs_cb(uv_fs_t* req) {
ASSERT(stats->f_ffree <= stats->f_files);
#endif
uv_fs_req_cleanup(req);
ASSERT(req->ptr == NULL);
ASSERT_NULL(req->ptr);
statfs_cb_count++;
}
@ -630,7 +630,7 @@ static void empty_scandir_cb(uv_fs_t* req) {
ASSERT(req == &scandir_req);
ASSERT(req->fs_type == UV_FS_SCANDIR);
ASSERT(req->result == 0);
ASSERT(req->ptr == NULL);
ASSERT_NULL(req->ptr);
ASSERT(UV_EOF == uv_fs_scandir_next(req, &dent));
uv_fs_req_cleanup(req);
scandir_cb_count++;
@ -642,7 +642,7 @@ static void non_existent_scandir_cb(uv_fs_t* req) {
ASSERT(req == &scandir_req);
ASSERT(req->fs_type == UV_FS_SCANDIR);
ASSERT(req->result == UV_ENOENT);
ASSERT(req->ptr == NULL);
ASSERT_NULL(req->ptr);
ASSERT(UV_ENOENT == uv_fs_scandir_next(req, &dent));
uv_fs_req_cleanup(req);
scandir_cb_count++;
@ -653,7 +653,7 @@ static void file_scandir_cb(uv_fs_t* req) {
ASSERT(req == &scandir_req);
ASSERT(req->fs_type == UV_FS_SCANDIR);
ASSERT(req->result == UV_ENOTDIR);
ASSERT(req->ptr == NULL);
ASSERT_NULL(req->ptr);
uv_fs_req_cleanup(req);
scandir_cb_count++;
}
@ -673,7 +673,7 @@ static void stat_cb(uv_fs_t* req) {
static void sendfile_cb(uv_fs_t* req) {
ASSERT(req == &sendfile_req);
ASSERT(req->fs_type == UV_FS_SENDFILE);
ASSERT(req->result == 65546);
ASSERT(req->result == 65545);
sendfile_cb_count++;
uv_fs_req_cleanup(req);
}
@ -816,13 +816,44 @@ static void check_utime(const char* path,
else
r = uv_fs_stat(loop, &req, path, NULL);
ASSERT(r == 0);
ASSERT_EQ(r, 0);
ASSERT(req.result == 0);
ASSERT_EQ(req.result, 0);
s = &req.statbuf;
ASSERT(s->st_atim.tv_sec + (s->st_atim.tv_nsec / 1000000000.0) == atime);
ASSERT(s->st_mtim.tv_sec + (s->st_mtim.tv_nsec / 1000000000.0) == mtime);
if (s->st_atim.tv_nsec == 0 && s->st_mtim.tv_nsec == 0) {
/*
* Test sub-second timestamps only when supported (such as Windows with
* NTFS). Some other platforms support sub-second timestamps, but that
* support is filesystem-dependent. Notably OS X (HFS Plus) does NOT
* support sub-second timestamps. But kernels may round or truncate in
* either direction, so we may accept either possible answer.
*/
#ifdef _WIN32
ASSERT_DOUBLE_EQ(atime, (long) atime);
ASSERT_DOUBLE_EQ(mtime, (long) atime);
#endif
if (atime > 0 || (long) atime == atime)
ASSERT_EQ(s->st_atim.tv_sec, (long) atime);
if (mtime > 0 || (long) mtime == mtime)
ASSERT_EQ(s->st_mtim.tv_sec, (long) mtime);
ASSERT_GE(s->st_atim.tv_sec, (long) atime - 1);
ASSERT_GE(s->st_mtim.tv_sec, (long) mtime - 1);
ASSERT_LE(s->st_atim.tv_sec, (long) atime);
ASSERT_LE(s->st_mtim.tv_sec, (long) mtime);
} else {
double st_atim;
double st_mtim;
#ifndef __APPLE__
/* 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);
#endif
st_atim = s->st_atim.tv_sec + s->st_atim.tv_nsec / 1e9;
st_mtim = s->st_mtim.tv_sec + s->st_mtim.tv_nsec / 1e9;
ASSERT_DOUBLE_EQ(st_atim, atime);
ASSERT_DOUBLE_EQ(st_mtim, mtime);
}
uv_fs_req_cleanup(&req);
}
@ -1159,6 +1190,8 @@ TEST_IMPL(fs_async_dir) {
static int test_sendfile(void (*setup)(int), uv_fs_cb cb, off_t expected_size) {
int f, r;
struct stat s1, s2;
uv_fs_t req;
char buf1[1];
loop = uv_default_loop();
@ -1188,7 +1221,7 @@ static int test_sendfile(void (*setup)(int), uv_fs_cb cb, off_t expected_size) {
uv_fs_req_cleanup(&open_req2);
r = uv_fs_sendfile(loop, &sendfile_req, open_req2.result, open_req1.result,
0, 131072, cb);
1, 131072, cb);
ASSERT(r == 0);
uv_run(loop, UV_RUN_DEFAULT);
@ -1203,9 +1236,26 @@ static int test_sendfile(void (*setup)(int), uv_fs_cb cb, off_t expected_size) {
ASSERT(0 == stat("test_file", &s1));
ASSERT(0 == stat("test_file2", &s2));
ASSERT(s1.st_size == s2.st_size);
ASSERT(s2.st_size == expected_size);
if (expected_size > 0) {
ASSERT_UINT64_EQ(s1.st_size, s2.st_size + 1);
r = uv_fs_open(NULL, &open_req1, "test_file2", O_RDWR, 0, NULL);
ASSERT(r >= 0);
ASSERT(open_req1.result >= 0);
uv_fs_req_cleanup(&open_req1);
memset(buf1, 0, sizeof(buf1));
iov = uv_buf_init(buf1, sizeof(buf1));
r = uv_fs_read(NULL, &req, open_req1.result, &iov, 1, -1, NULL);
ASSERT(r >= 0);
ASSERT(req.result >= 0);
ASSERT_EQ(buf1[0], 'e'); /* 'e' from begin */
uv_fs_req_cleanup(&req);
} else {
ASSERT_UINT64_EQ(s1.st_size, s2.st_size);
}
/* Cleanup. */
unlink("test_file");
unlink("test_file2");
@ -1223,7 +1273,7 @@ static void sendfile_setup(int f) {
TEST_IMPL(fs_async_sendfile) {
return test_sendfile(sendfile_setup, sendfile_cb, 65546);
return test_sendfile(sendfile_setup, sendfile_cb, 65545);
}
@ -1403,7 +1453,8 @@ TEST_IMPL(fs_fstat) {
ASSERT(s->st_mtim.tv_nsec == t.st_mtimespec.tv_nsec);
ASSERT(s->st_ctim.tv_sec == t.st_ctimespec.tv_sec);
ASSERT(s->st_ctim.tv_nsec == t.st_ctimespec.tv_nsec);
#elif defined(_AIX)
#elif defined(_AIX) || \
defined(__MVS__)
ASSERT(s->st_atim.tv_sec == t.st_atime);
ASSERT(s->st_atim.tv_nsec == 0);
ASSERT(s->st_mtim.tv_sec == t.st_mtime);
@ -1961,12 +2012,12 @@ TEST_IMPL(fs_readlink) {
ASSERT(0 == uv_fs_readlink(loop, &req, "no_such_file", dummy_cb));
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(dummy_cb_count == 1);
ASSERT(req.ptr == NULL);
ASSERT_NULL(req.ptr);
ASSERT(req.result == UV_ENOENT);
uv_fs_req_cleanup(&req);
ASSERT(UV_ENOENT == uv_fs_readlink(NULL, &req, "no_such_file", NULL));
ASSERT(req.ptr == NULL);
ASSERT_NULL(req.ptr);
ASSERT(req.result == UV_ENOENT);
uv_fs_req_cleanup(&req);
@ -1982,7 +2033,7 @@ TEST_IMPL(fs_realpath) {
ASSERT(0 == uv_fs_realpath(loop, &req, "no_such_file", dummy_cb));
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(dummy_cb_count == 1);
ASSERT(req.ptr == NULL);
ASSERT_NULL(req.ptr);
#ifdef _WIN32
/*
* Windows XP and Server 2003 don't support GetFinalPathNameByHandleW()
@ -1996,7 +2047,7 @@ TEST_IMPL(fs_realpath) {
uv_fs_req_cleanup(&req);
ASSERT(UV_ENOENT == uv_fs_realpath(NULL, &req, "no_such_file", NULL));
ASSERT(req.ptr == NULL);
ASSERT_NULL(req.ptr);
ASSERT(req.result == UV_ENOENT);
uv_fs_req_cleanup(&req);
@ -2523,29 +2574,16 @@ TEST_IMPL(fs_utime) {
uv_fs_req_cleanup(&req);
uv_fs_close(loop, &req, r, NULL);
atime = mtime = 400497753; /* 1982-09-10 11:22:33 */
/*
* Test sub-second timestamps only on Windows (assuming NTFS). Some other
* platforms support sub-second timestamps, but that support is filesystem-
* dependent. Notably OS X (HFS Plus) does NOT support sub-second timestamps.
*/
#ifdef _WIN32
mtime += 0.444; /* 1982-09-10 11:22:33.444 */
#endif
atime = mtime = 400497753.25; /* 1982-09-10 11:22:33.25 */
r = uv_fs_utime(NULL, &req, path, atime, mtime, NULL);
ASSERT(r == 0);
ASSERT(req.result == 0);
uv_fs_req_cleanup(&req);
r = uv_fs_stat(NULL, &req, path, NULL);
ASSERT(r == 0);
ASSERT(req.result == 0);
check_utime(path, atime, mtime, /* test_lutime */ 0);
uv_fs_req_cleanup(&req);
atime = mtime = 1291404900; /* 2010-12-03 20:35:00 - mees <3 */
atime = mtime = 1291404900.25; /* 2010-12-03 20:35:00.25 - mees <3 */
checkme.path = path;
checkme.atime = atime;
checkme.mtime = mtime;
@ -2565,6 +2603,45 @@ TEST_IMPL(fs_utime) {
}
TEST_IMPL(fs_utime_round) {
const char path[] = "test_file";
double atime;
double mtime;
uv_fs_t req;
int r;
loop = uv_default_loop();
unlink(path);
r = uv_fs_open(NULL, &req, path, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR, NULL);
ASSERT_GE(r, 0);
ASSERT_GE(req.result, 0);
uv_fs_req_cleanup(&req);
ASSERT_EQ(0, uv_fs_close(loop, &req, r, NULL));
atime = mtime = -14245440.25; /* 1969-07-20T02:56:00.25Z */
r = uv_fs_utime(NULL, &req, path, atime, mtime, NULL);
#if !defined(__linux__) && \
!defined(_WIN32) && \
!defined(__APPLE__) && \
!defined(__FreeBSD__) && \
!defined(__sun)
if (r != 0) {
ASSERT_EQ(r, UV_EINVAL);
RETURN_SKIP("utime on some OS (z/OS, IBM i PASE, AIX) or filesystems may reject pre-epoch timestamps");
}
#endif
ASSERT_EQ(0, r);
ASSERT_EQ(0, req.result);
uv_fs_req_cleanup(&req);
check_utime(path, atime, mtime, /* test_lutime */ 0);
unlink(path);
MAKE_VALGRIND_HAPPY();
return 0;
}
#ifdef _WIN32
TEST_IMPL(fs_stat_root) {
int r;
@ -2618,16 +2695,7 @@ TEST_IMPL(fs_futime) {
uv_fs_req_cleanup(&req);
uv_fs_close(loop, &req, r, NULL);
atime = mtime = 400497753; /* 1982-09-10 11:22:33 */
/*
* Test sub-second timestamps only on Windows (assuming NTFS). Some other
* platforms support sub-second timestamps, but that support is filesystem-
* dependent. Notably OS X (HFS Plus) does NOT support sub-second timestamps.
*/
#ifdef _WIN32
mtime += 0.444; /* 1982-09-10 11:22:33.444 */
#endif
atime = mtime = 400497753.25; /* 1982-09-10 11:22:33.25 */
r = uv_fs_open(NULL, &req, path, O_RDWR, 0, NULL);
ASSERT(r >= 0);
@ -2645,11 +2713,7 @@ TEST_IMPL(fs_futime) {
#endif
uv_fs_req_cleanup(&req);
r = uv_fs_stat(NULL, &req, path, NULL);
ASSERT(r == 0);
ASSERT(req.result == 0);
check_utime(path, atime, mtime, /* test_lutime */ 0);
uv_fs_req_cleanup(&req);
atime = mtime = 1291404900; /* 2010-12-03 20:35:00 - mees <3 */
@ -2708,11 +2772,7 @@ TEST_IMPL(fs_lutime) {
uv_fs_req_cleanup(&req);
/* Test the synchronous version. */
atime = mtime = 400497753; /* 1982-09-10 11:22:33 */
#ifdef _WIN32
mtime += 0.444; /* 1982-09-10 11:22:33.444 */
#endif
atime = mtime = 400497753.25; /* 1982-09-10 11:22:33.25 */
checkme.atime = atime;
checkme.mtime = mtime;
@ -2784,7 +2844,7 @@ TEST_IMPL(fs_scandir_empty_dir) {
r = uv_fs_scandir(NULL, &req, path, 0, NULL);
ASSERT(r == 0);
ASSERT(req.result == 0);
ASSERT(req.ptr == NULL);
ASSERT_NULL(req.ptr);
ASSERT(UV_EOF == uv_fs_scandir_next(&req, &dent));
uv_fs_req_cleanup(&req);
@ -2821,7 +2881,7 @@ TEST_IMPL(fs_scandir_non_existent_dir) {
r = uv_fs_scandir(NULL, &req, path, 0, NULL);
ASSERT(r == UV_ENOENT);
ASSERT(req.result == UV_ENOENT);
ASSERT(req.ptr == NULL);
ASSERT_NULL(req.ptr);
ASSERT(UV_ENOENT == uv_fs_scandir_next(&req, &dent));
uv_fs_req_cleanup(&req);
@ -2837,6 +2897,9 @@ 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;
@ -2870,7 +2933,7 @@ TEST_IMPL(fs_open_dir) {
r = uv_fs_open(NULL, &req, path, O_RDONLY, 0, NULL);
ASSERT(r >= 0);
ASSERT(req.result >= 0);
ASSERT(req.ptr == NULL);
ASSERT_NULL(req.ptr);
file = r;
uv_fs_req_cleanup(&req);
@ -3083,6 +3146,9 @@ 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);
@ -3267,7 +3333,7 @@ static void fs_write_alotof_bufs(int add_flags) {
loop = uv_default_loop();
iovs = malloc(sizeof(*iovs) * iovcount);
ASSERT(iovs != NULL);
ASSERT_NOT_NULL(iovs);
iovmax = uv_test_getiovmax();
r = uv_fs_open(NULL,
@ -3296,7 +3362,7 @@ static void fs_write_alotof_bufs(int add_flags) {
/* Read the strings back to separate buffers. */
buffer = malloc(sizeof(test_buf) * iovcount);
ASSERT(buffer != NULL);
ASSERT_NOT_NULL(buffer);
for (index = 0; index < iovcount; ++index)
iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf),
@ -3379,7 +3445,7 @@ static void fs_write_alotof_bufs_with_offset(int add_flags) {
loop = uv_default_loop();
iovs = malloc(sizeof(*iovs) * iovcount);
ASSERT(iovs != NULL);
ASSERT_NOT_NULL(iovs);
iovmax = uv_test_getiovmax();
r = uv_fs_open(NULL,
@ -3415,7 +3481,7 @@ static void fs_write_alotof_bufs_with_offset(int add_flags) {
/* Read the strings back to separate buffers. */
buffer = malloc(sizeof(test_buf) * iovcount);
ASSERT(buffer != NULL);
ASSERT_NOT_NULL(buffer);
for (index = 0; index < iovcount; ++index)
iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf),
@ -3611,16 +3677,16 @@ static void test_fs_partial(int doread) {
iovcount = 54321;
iovs = malloc(sizeof(*iovs) * iovcount);
ASSERT(iovs != NULL);
ASSERT_NOT_NULL(iovs);
ctx.pid = pthread_self();
ctx.doread = doread;
ctx.interval = 1000;
ctx.size = sizeof(test_buf) * iovcount;
ctx.data = malloc(ctx.size);
ASSERT(ctx.data != NULL);
ASSERT_NOT_NULL(ctx.data);
buffer = malloc(ctx.size);
ASSERT(buffer != NULL);
ASSERT_NOT_NULL(buffer);
for (index = 0; index < iovcount; ++index)
iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf), sizeof(test_buf));
@ -3708,15 +3774,15 @@ TEST_IMPL(fs_read_write_null_arguments) {
/* Validate some memory management on failed input validation before sending
fs work to the thread pool. */
ASSERT(r == UV_EINVAL);
ASSERT(write_req.path == NULL);
ASSERT(write_req.ptr == NULL);
ASSERT_NULL(write_req.path);
ASSERT_NULL(write_req.ptr);
#ifdef _WIN32
ASSERT(write_req.file.pathw == NULL);
ASSERT(write_req.fs.info.new_pathw == NULL);
ASSERT(write_req.fs.info.bufs == NULL);
ASSERT_NULL(write_req.file.pathw);
ASSERT_NULL(write_req.fs.info.new_pathw);
ASSERT_NULL(write_req.fs.info.bufs);
#else
ASSERT(write_req.new_path == NULL);
ASSERT(write_req.bufs == NULL);
ASSERT_NULL(write_req.new_path);
ASSERT_NULL(write_req.bufs);
#endif
uv_fs_req_cleanup(&write_req);
@ -4372,6 +4438,7 @@ TEST_IMPL(fs_invalid_mkdir_name) {
loop = uv_default_loop();
r = uv_fs_mkdir(loop, &req, "invalid>", 0, NULL);
ASSERT(r == UV_EINVAL);
ASSERT_EQ(UV_EINVAL, uv_fs_mkdir(loop, &req, "test:lol", 0, NULL));
return 0;
}

View File

@ -49,7 +49,7 @@ TEST_IMPL(get_currentexe) {
#ifdef _WIN32
snprintf(path, sizeof(path), "%s", executable_path);
#else
ASSERT(NULL != realpath(executable_path, path));
ASSERT_NOT_NULL(realpath(executable_path, path));
#endif
match = strstr(buffer, path);

View File

@ -40,7 +40,7 @@ TEST_IMPL(get_passwd) {
ASSERT(len > 0);
#ifdef _WIN32
ASSERT(pwd.shell == NULL);
ASSERT_NULL(pwd.shell);
#else
len = strlen(pwd.shell);
# ifndef __PASE__
@ -74,16 +74,16 @@ TEST_IMPL(get_passwd) {
/* Test uv_os_free_passwd() */
uv_os_free_passwd(&pwd);
ASSERT(pwd.username == NULL);
ASSERT(pwd.shell == NULL);
ASSERT(pwd.homedir == NULL);
ASSERT_NULL(pwd.username);
ASSERT_NULL(pwd.shell);
ASSERT_NULL(pwd.homedir);
/* Test a double free */
uv_os_free_passwd(&pwd);
ASSERT(pwd.username == NULL);
ASSERT(pwd.shell == NULL);
ASSERT(pwd.homedir == NULL);
ASSERT_NULL(pwd.username);
ASSERT_NULL(pwd.shell);
ASSERT_NULL(pwd.homedir);
/* Test invalid input */
r = uv_os_get_passwd(NULL);

View File

@ -42,7 +42,7 @@ static void getaddrinfo_fail_cb(uv_getaddrinfo_t* req,
ASSERT(fail_cb_called == 0);
ASSERT(status < 0);
ASSERT(res == NULL);
ASSERT_NULL(res);
uv_freeaddrinfo(res); /* Should not crash. */
fail_cb_called++;
}
@ -100,7 +100,7 @@ TEST_IMPL(getaddrinfo_fail) {
ASSERT(0 == uv_getaddrinfo(uv_default_loop(),
&req,
getaddrinfo_fail_cb,
"xyzzy.xyzzy.xyzzy.",
"example.invalid.",
NULL,
NULL));
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
@ -122,7 +122,7 @@ TEST_IMPL(getaddrinfo_fail_sync) {
ASSERT(0 > uv_getaddrinfo(uv_default_loop(),
&req,
NULL,
"xyzzy.xyzzy.xyzzy.",
"example.invalid.",
NULL,
NULL));
uv_freeaddrinfo(req.addrinfo);
@ -191,7 +191,7 @@ TEST_IMPL(getaddrinfo_concurrent) {
callback_counts[i] = 0;
data = (int*)malloc(sizeof(int));
ASSERT(data != NULL);
ASSERT_NOT_NULL(data);
*data = i;
getaddrinfo_handles[i].data = data;

View File

@ -38,10 +38,10 @@ static void getnameinfo_req(uv_getnameinfo_t* handle,
int status,
const char* hostname,
const char* service) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
ASSERT(status == 0);
ASSERT(hostname != NULL);
ASSERT(service != NULL);
ASSERT_NOT_NULL(hostname);
ASSERT_NOT_NULL(service);
}

View File

@ -116,7 +116,7 @@ static void on_connection(uv_stream_t* server, int status) {
ASSERT(status == 0);
handle = malloc(sizeof(*handle));
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
r = uv_tcp_init(loop, handle);
ASSERT(r == 0);

View File

@ -33,9 +33,9 @@ TEST_IMPL(handle_type_name) {
ASSERT(strcmp(uv_handle_type_name(UV_NAMED_PIPE), "pipe") == 0);
ASSERT(strcmp(uv_handle_type_name(UV_UDP), "udp") == 0);
ASSERT(strcmp(uv_handle_type_name(UV_FILE), "file") == 0);
ASSERT(uv_handle_type_name(UV_HANDLE_TYPE_MAX) == NULL);
ASSERT(uv_handle_type_name(UV_HANDLE_TYPE_MAX + 1) == NULL);
ASSERT(uv_handle_type_name(UV_UNKNOWN_HANDLE) == NULL);
ASSERT_NULL(uv_handle_type_name(UV_HANDLE_TYPE_MAX));
ASSERT_NULL(uv_handle_type_name(UV_HANDLE_TYPE_MAX + 1));
ASSERT_NULL(uv_handle_type_name(UV_UNKNOWN_HANDLE));
return 0;
}
@ -44,9 +44,9 @@ TEST_IMPL(req_type_name) {
ASSERT(strcmp(uv_req_type_name(UV_REQ), "req") == 0);
ASSERT(strcmp(uv_req_type_name(UV_UDP_SEND), "udp_send") == 0);
ASSERT(strcmp(uv_req_type_name(UV_WORK), "work") == 0);
ASSERT(uv_req_type_name(UV_REQ_TYPE_MAX) == NULL);
ASSERT(uv_req_type_name(UV_REQ_TYPE_MAX + 1) == NULL);
ASSERT(uv_req_type_name(UV_UNKNOWN_REQ) == NULL);
ASSERT_NULL(uv_req_type_name(UV_REQ_TYPE_MAX));
ASSERT_NULL(uv_req_type_name(UV_REQ_TYPE_MAX + 1));
ASSERT_NULL(uv_req_type_name(UV_UNKNOWN_REQ));
return 0;
}
@ -58,7 +58,7 @@ TEST_IMPL(getters_setters) {
int r;
loop = malloc(uv_loop_size());
ASSERT(loop != NULL);
ASSERT_NOT_NULL(loop);
r = uv_loop_init(loop);
ASSERT(r == 0);

View File

@ -96,6 +96,25 @@ TEST_IMPL(utf8_decode1) {
return 0;
}
TEST_IMPL(utf8_decode1_overrun) {
const char* p;
char b[1];
/* Single byte. */
p = b;
b[0] = 0x7F;
ASSERT_EQ(0x7F, uv__utf8_decode1(&p, b + 1));
ASSERT_EQ(p, b + 1);
/* Multi-byte. */
p = b;
b[0] = 0xC0;
ASSERT_EQ((unsigned) -1, uv__utf8_decode1(&p, b + 1));
ASSERT_EQ(p, b + 1);
return 0;
}
/* Doesn't work on z/OS because that platform uses EBCDIC, not ASCII. */
#ifndef __MVS__

View File

@ -66,7 +66,7 @@ static void do_write(uv_stream_t* handle) {
int r;
write_info = malloc(sizeof *write_info);
ASSERT(write_info != NULL);
ASSERT_NOT_NULL(write_info);
for (i = 0; i < BUFFERS_PER_WRITE; i++) {
memset(&write_info->buffers[i], BUFFER_CONTENT, BUFFER_SIZE);

View File

@ -203,7 +203,7 @@ static void on_read(uv_stream_t* handle,
/* Make sure that the expected data is correctly multiplexed. */
ASSERT_MEM_EQ("hello\n", buf->base, nread);
outbuf = uv_buf_init("world\n", 6);
outbuf = uv_buf_init("foobar\n", 7);
r = uv_write(&write_req, (uv_stream_t*)pipe, &outbuf, 1, NULL);
ASSERT_EQ(r, 0);
@ -693,6 +693,11 @@ static void ipc_on_connection(uv_stream_t* server, int status) {
}
static void close_and_free_cb(uv_handle_t* handle) {
close_cb_called++;
free(handle);
}
static void ipc_on_connection_tcp_conn(uv_stream_t* server, int status) {
int r;
uv_buf_t buf;
@ -721,7 +726,7 @@ static void ipc_on_connection_tcp_conn(uv_stream_t* server, int status) {
on_tcp_child_process_read);
ASSERT_EQ(r, 0);
uv_close((uv_handle_t*)conn, close_cb);
uv_close((uv_handle_t*)conn, close_and_free_cb);
}

View File

@ -116,7 +116,8 @@ TEST_DECLARE (tcp_open_bound)
TEST_DECLARE (tcp_open_connected)
TEST_DECLARE (tcp_connect_error_after_write)
TEST_DECLARE (tcp_shutdown_after_write)
TEST_DECLARE (tcp_bind_error_addrinuse)
TEST_DECLARE (tcp_bind_error_addrinuse_connect)
TEST_DECLARE (tcp_bind_error_addrinuse_listen)
TEST_DECLARE (tcp_bind_error_addrnotavail_1)
TEST_DECLARE (tcp_bind_error_addrnotavail_2)
TEST_DECLARE (tcp_bind_error_fault)
@ -205,6 +206,7 @@ TEST_DECLARE (connection_fail_doesnt_auto_close)
TEST_DECLARE (shutdown_close_tcp)
TEST_DECLARE (shutdown_close_pipe)
TEST_DECLARE (shutdown_eof)
TEST_DECLARE (shutdown_simultaneous)
TEST_DECLARE (shutdown_twice)
TEST_DECLARE (callback_stack)
TEST_DECLARE (env_vars)
@ -359,6 +361,7 @@ TEST_DECLARE (fs_open_flags)
TEST_DECLARE (fs_fd_hash)
#endif
TEST_DECLARE (fs_utime)
TEST_DECLARE (fs_utime_round)
TEST_DECLARE (fs_futime)
TEST_DECLARE (fs_lutime)
TEST_DECLARE (fs_file_open_append)
@ -451,12 +454,16 @@ TEST_DECLARE (poll_nested_epoll)
#ifdef UV_HAVE_KQUEUE
TEST_DECLARE (poll_nested_kqueue)
#endif
TEST_DECLARE (poll_multiple_handles)
TEST_DECLARE (ip4_addr)
TEST_DECLARE (ip6_addr_link_local)
TEST_DECLARE (poll_close_doesnt_corrupt_stack)
TEST_DECLARE (poll_closesocket)
TEST_DECLARE (close_fd)
TEST_DECLARE (closed_fd_events)
TEST_DECLARE (spawn_fs_open)
#ifdef _WIN32
TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows)
#if !defined(USING_UV_SHARED)
@ -471,8 +478,6 @@ TEST_DECLARE (ipc_listen_after_bind_twice)
TEST_DECLARE (win32_signum_number)
#else
TEST_DECLARE (emfile)
TEST_DECLARE (close_fd)
TEST_DECLARE (spawn_fs_open)
TEST_DECLARE (spawn_setuid_setgid)
TEST_DECLARE (we_get_signal)
TEST_DECLARE (we_get_signals)
@ -481,7 +486,6 @@ TEST_DECLARE (we_get_signals_mixed)
TEST_DECLARE (signal_multiple_loops)
TEST_DECLARE (signal_pending_on_close)
TEST_DECLARE (signal_close_loop_alive)
TEST_DECLARE (closed_fd_events)
#endif
#ifdef __APPLE__
TEST_DECLARE (osx_select)
@ -501,6 +505,10 @@ TEST_DECLARE (handle_type_name)
TEST_DECLARE (req_type_name)
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)
#ifndef _WIN32
TEST_DECLARE (fork_timer)
TEST_DECLARE (fork_socketpair)
@ -521,6 +529,7 @@ TEST_DECLARE (fork_threadpool_queue_work_simple)
TEST_DECLARE (idna_toascii)
TEST_DECLARE (utf8_decode1)
TEST_DECLARE (utf8_decode1_overrun)
TEST_DECLARE (uname)
TEST_DECLARE (metrics_idle_time)
@ -567,7 +576,8 @@ TASK_LIST_START
#ifndef _WIN32
TEST_ENTRY (pipe_close_stdout_read_stdin)
#endif
TEST_ENTRY (pipe_set_non_blocking)
/* Seems to be either about 0.5s or 5s, depending on the OS. */
TEST_ENTRY_CUSTOM (pipe_set_non_blocking, 0, 0, 20000)
TEST_ENTRY (pipe_set_chmod)
TEST_ENTRY (tty)
#ifdef _WIN32
@ -671,7 +681,13 @@ TASK_LIST_START
TEST_HELPER (tcp_shutdown_after_write, tcp4_echo_server)
TEST_ENTRY (tcp_connect_error_after_write)
TEST_ENTRY (tcp_bind_error_addrinuse)
TEST_ENTRY (tcp_bind_error_addrinuse_connect)
/* tcp4_echo_server steals the port. It needs to be a separate process
* because libuv sets setsockopt(SO_REUSEADDR) that lets you steal an
* existing bind if it originates from the same process.
*/
TEST_HELPER (tcp_bind_error_addrinuse_connect, tcp4_echo_server)
TEST_ENTRY (tcp_bind_error_addrinuse_listen)
TEST_ENTRY (tcp_bind_error_addrnotavail_1)
TEST_ENTRY (tcp_bind_error_addrnotavail_2)
TEST_ENTRY (tcp_bind_error_fault)
@ -769,6 +785,9 @@ TASK_LIST_START
TEST_ENTRY (shutdown_eof)
TEST_HELPER (shutdown_eof, tcp4_echo_server)
TEST_ENTRY (shutdown_simultaneous)
TEST_HELPER (shutdown_simultaneous, tcp4_echo_server)
TEST_ENTRY (shutdown_twice)
TEST_HELPER (shutdown_twice, tcp4_echo_server)
@ -894,6 +913,7 @@ TASK_LIST_START
#ifdef UV_HAVE_KQUEUE
TEST_ENTRY (poll_nested_kqueue)
#endif
TEST_ENTRY (poll_multiple_handles)
TEST_ENTRY (socket_buffer_size)
@ -935,6 +955,9 @@ TASK_LIST_START
TEST_ENTRY (poll_close_doesnt_corrupt_stack)
TEST_ENTRY (poll_closesocket)
TEST_ENTRY (close_fd)
TEST_ENTRY (closed_fd_events)
TEST_ENTRY (spawn_fs_open)
#ifdef _WIN32
TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows)
#if !defined(USING_UV_SHARED)
@ -949,8 +972,6 @@ TASK_LIST_START
TEST_ENTRY (win32_signum_number)
#else
TEST_ENTRY (emfile)
TEST_ENTRY (close_fd)
TEST_ENTRY (spawn_fs_open)
TEST_ENTRY (spawn_setuid_setgid)
TEST_ENTRY (we_get_signal)
TEST_ENTRY (we_get_signals)
@ -959,7 +980,6 @@ TASK_LIST_START
TEST_ENTRY (signal_multiple_loops)
TEST_ENTRY (signal_pending_on_close)
TEST_ENTRY (signal_close_loop_alive)
TEST_ENTRY (closed_fd_events)
#endif
#ifdef __APPLE__
@ -988,6 +1008,7 @@ TASK_LIST_START
#endif
TEST_ENTRY (fs_chown)
TEST_ENTRY (fs_utime)
TEST_ENTRY (fs_utime_round)
TEST_ENTRY (fs_futime)
TEST_ENTRY (fs_lutime)
TEST_ENTRY (fs_readlink)
@ -1108,6 +1129,7 @@ TASK_LIST_START
#endif
TEST_ENTRY (utf8_decode1)
TEST_ENTRY (utf8_decode1_overrun)
TEST_ENTRY (uname)
/* Doesn't work on z/OS because that platform uses EBCDIC, not ASCII. */
@ -1115,6 +1137,13 @@ TASK_LIST_START
TEST_ENTRY (idna_toascii)
#endif
TEST_ENTRY (not_writable_after_shutdown)
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 (metrics_idle_time)
TEST_ENTRY (metrics_idle_time_thread)
TEST_ENTRY (metrics_idle_time_zero)

View File

@ -143,7 +143,7 @@ static void idle_1_cb(uv_idle_t* handle) {
fprintf(stderr, "%s", "IDLE_1_CB\n");
fflush(stderr);
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
ASSERT(idles_1_active > 0);
/* Init idle_2 and make it active */
@ -170,7 +170,7 @@ static void idle_1_close_cb(uv_handle_t* handle) {
fprintf(stderr, "%s", "IDLE_1_CLOSE_CB\n");
fflush(stderr);
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
idle_1_close_cb_called++;
}

View File

@ -32,7 +32,7 @@ static uv_tcp_t client;
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}
@ -65,7 +65,7 @@ static void start_server(void) {
static void connect_cb(uv_connect_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
free(req);
uv_close((uv_handle_t*)&client, close_cb);
@ -79,7 +79,7 @@ static void client_connect(void) {
int r;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
ASSERT(connect_req != NULL);
ASSERT_NOT_NULL(connect_req);
r = uv_tcp_init(uv_default_loop(), &client);
ASSERT(r == 0);

View File

@ -0,0 +1,104 @@
/* Copyright the 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"
static uv_loop_t loop;
static uv_tcp_t tcp_client;
static uv_connect_t connect_req;
static uv_write_t write_req;
static char reset_me_cmd[] = {'Q', 'S', 'H'};
static int connect_cb_called;
static int read_cb_called;
static int write_cb_called;
static int close_cb_called;
static void write_cb(uv_write_t* req, int status) {
write_cb_called++;
ASSERT(status == 0);
}
static void alloc_cb(uv_handle_t* handle,
size_t suggested_size,
uv_buf_t* buf) {
static char slab[64];
buf->base = slab;
buf->len = sizeof(slab);
}
static void close_cb(uv_handle_t* handle) {
close_cb_called++;
}
static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
read_cb_called++;
ASSERT((nread < 0) && (nread != UV_EOF));
ASSERT(0 == uv_is_writable(handle));
ASSERT(0 == uv_is_readable(handle));
uv_close((uv_handle_t*) handle, close_cb);
}
static void connect_cb(uv_connect_t* req, int status) {
int r;
uv_buf_t reset_me;
connect_cb_called++;
ASSERT(status == 0);
r = uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb);
ASSERT(r == 0);
reset_me = uv_buf_init(reset_me_cmd, sizeof(reset_me_cmd));
r = uv_write(&write_req,
(uv_stream_t*) &tcp_client,
&reset_me,
1,
write_cb);
ASSERT(r == 0);
}
TEST_IMPL(not_readable_nor_writable_on_read_error) {
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);
MAKE_VALGRIND_HAPPY();
return 0;
}

View File

@ -0,0 +1,103 @@
/* Copyright the 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"
static uv_loop_t loop;
static uv_tcp_t tcp_client;
static uv_connect_t connect_req;
static uv_write_t write_req;
static char close_me_cmd[] = {'Q', 'S'};
static int connect_cb_called;
static int read_cb_called;
static int write_cb_called;
static int close_cb_called;
static void write_cb(uv_write_t* req, int status) {
write_cb_called++;
ASSERT(status == 0);
}
static void alloc_cb(uv_handle_t* handle,
size_t suggested_size,
uv_buf_t* buf) {
static char slab[64];
buf->base = slab;
buf->len = sizeof(slab);
}
static void close_cb(uv_handle_t* handle) {
close_cb_called++;
}
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));
uv_close((uv_handle_t*) handle, close_cb);
}
static void connect_cb(uv_connect_t* req, int status) {
int r;
uv_buf_t close_me;
connect_cb_called++;
ASSERT(status == 0);
r = uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb);
ASSERT(r == 0);
close_me = uv_buf_init(close_me_cmd, sizeof(close_me_cmd));
r = uv_write(&write_req,
(uv_stream_t*) &tcp_client,
&close_me,
1,
write_cb);
ASSERT(r == 0);
}
TEST_IMPL(not_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);
MAKE_VALGRIND_HAPPY();
return 0;
}

View File

@ -0,0 +1,69 @@
/* Copyright the 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"
static uv_shutdown_t shutdown_req;
static void close_cb(uv_handle_t* handle) {
}
static void shutdown_cb(uv_shutdown_t* req, int status) {
uv_close((uv_handle_t*) req->handle, close_cb);
}
static void connect_cb(uv_connect_t* req, int status) {
int r;
ASSERT(status == 0);
r = uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
ASSERT(r == 0);
ASSERT(0 == uv_is_writable(req->handle));
}
TEST_IMPL(not_writable_after_shutdown) {
int r;
struct sockaddr_in addr;
uv_loop_t* loop;
uv_tcp_t socket;
uv_connect_t connect_req;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
loop = uv_default_loop();
r = uv_tcp_init(loop, &socket);
ASSERT(r == 0);
r = uv_tcp_connect(&connect_req,
&socket,
(const struct sockaddr*) &addr,
connect_cb);
ASSERT(r == 0);
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
MAKE_VALGRIND_HAPPY();
return 0;
}

View File

@ -24,6 +24,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* strlen */
static int completed_pingers = 0;
@ -33,23 +34,21 @@ static int completed_pingers = 0;
#define NUM_PINGS 1000
#endif
/* 64 bytes is enough for a pinger */
#define BUFSIZE 10240
static char PING[] = "PING\n";
static char PONG[] = "PONG\n";
static int pinger_on_connect_count;
typedef struct {
int vectored_writes;
int pongs;
int state;
unsigned pongs;
unsigned state;
union {
uv_tcp_t tcp;
uv_pipe_t pipe;
} stream;
uv_connect_t connect_req;
char read_buffer[BUFSIZE];
char* pong;
} pinger_t;
@ -59,28 +58,44 @@ static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
}
static void ponger_on_close(uv_handle_t* handle) {
if (handle->data)
free(handle->data);
else
free(handle);
}
static void pinger_on_close(uv_handle_t* handle) {
pinger_t* pinger = (pinger_t*)handle->data;
pinger_t* pinger = (pinger_t*) handle->data;
ASSERT(NUM_PINGS == pinger->pongs);
ASSERT_EQ(NUM_PINGS, pinger->pongs);
free(pinger);
if (handle == (uv_handle_t*) &pinger->stream.tcp) {
free(pinger); /* also frees handle */
} else {
uv_close((uv_handle_t*) &pinger->stream.tcp, ponger_on_close);
free(handle);
}
completed_pingers++;
}
static void pinger_after_write(uv_write_t* req, int status) {
ASSERT(status == 0);
ASSERT_EQ(status, 0);
free(req);
}
static void pinger_write_ping(pinger_t* pinger) {
uv_stream_t* stream;
uv_write_t* req;
uv_buf_t bufs[sizeof PING - 1];
int i, nbufs;
stream = (uv_stream_t*) &pinger->stream.tcp;
if (!pinger->vectored_writes) {
/* Write a single buffer. */
nbufs = 1;
@ -94,13 +109,8 @@ static void pinger_write_ping(pinger_t* pinger) {
}
req = malloc(sizeof(*req));
if (uv_write(req,
(uv_stream_t*) &pinger->stream.tcp,
bufs,
nbufs,
pinger_after_write)) {
FATAL("uv_write failed");
}
ASSERT_NOT_NULL(req);
ASSERT_EQ(0, uv_write(req, stream, bufs, nbufs, pinger_after_write));
puts("PING");
}
@ -115,20 +125,20 @@ static void pinger_read_cb(uv_stream_t* stream,
pinger = (pinger_t*) stream->data;
if (nread < 0) {
ASSERT(nread == UV_EOF);
ASSERT_EQ(nread, UV_EOF);
puts("got EOF");
free(buf->base);
uv_close((uv_handle_t*)(&pinger->stream.tcp), pinger_on_close);
uv_close((uv_handle_t*) stream, pinger_on_close);
return;
}
/* Now we count the pings */
/* Now we count the pongs */
for (i = 0; i < nread; i++) {
ASSERT(buf->base[i] == PING[pinger->state]);
pinger->state = (pinger->state + 1) % (sizeof(PING) - 1);
ASSERT_EQ(buf->base[i], pinger->pong[pinger->state]);
pinger->state = (pinger->state + 1) % strlen(pinger->pong);
if (pinger->state != 0)
continue;
@ -139,7 +149,7 @@ static void pinger_read_cb(uv_stream_t* stream,
if (pinger->pongs < NUM_PINGS) {
pinger_write_ping(pinger);
} else {
uv_close((uv_handle_t*)(&pinger->stream.tcp), pinger_on_close);
uv_close((uv_handle_t*) stream, pinger_on_close);
break;
}
}
@ -148,20 +158,53 @@ static void pinger_read_cb(uv_stream_t* stream,
}
static void ponger_read_cb(uv_stream_t* stream,
ssize_t nread,
const uv_buf_t* buf) {
uv_buf_t writebuf;
uv_write_t* req;
int i;
if (nread < 0) {
ASSERT_EQ(nread, UV_EOF);
puts("got EOF");
free(buf->base);
uv_close((uv_handle_t*) stream, ponger_on_close);
return;
}
/* Echo back */
for (i = 0; i < nread; i++) {
if (buf->base[i] == 'I')
buf->base[i] = 'O';
}
writebuf = uv_buf_init(buf->base, nread);
req = malloc(sizeof(*req));
ASSERT_NOT_NULL(req);
ASSERT_EQ(0, uv_write(req, stream, &writebuf, 1, pinger_after_write));
}
static void pinger_on_connect(uv_connect_t* req, int status) {
pinger_t* pinger = (pinger_t*)req->handle->data;
pinger_t* pinger = (pinger_t*) req->handle->data;
pinger_on_connect_count++;
ASSERT(status == 0);
ASSERT_EQ(status, 0);
ASSERT(1 == uv_is_readable(req->handle));
ASSERT(1 == uv_is_writable(req->handle));
ASSERT(0 == uv_is_closing((uv_handle_t *) req->handle));
ASSERT_EQ(1, uv_is_readable(req->handle));
ASSERT_EQ(1, uv_is_writable(req->handle));
ASSERT_EQ(0, uv_is_closing((uv_handle_t *) req->handle));
pinger_write_ping(pinger);
uv_read_start((uv_stream_t*)(req->handle), alloc_cb, pinger_read_cb);
ASSERT_EQ(0, uv_read_start((uv_stream_t*) req->handle,
alloc_cb,
pinger_read_cb));
}
@ -172,17 +215,18 @@ static void tcp_pinger_v6_new(int vectored_writes) {
pinger_t* pinger;
ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &server_addr));
ASSERT_EQ(0, uv_ip6_addr("::1", TEST_PORT, &server_addr));
pinger = malloc(sizeof(*pinger));
ASSERT(pinger != NULL);
ASSERT_NOT_NULL(pinger);
pinger->vectored_writes = vectored_writes;
pinger->state = 0;
pinger->pongs = 0;
pinger->pong = PING;
/* Try to connect to the server and do NUM_PINGS ping-pongs. */
r = uv_tcp_init(uv_default_loop(), &pinger->stream.tcp);
pinger->stream.tcp.data = pinger;
ASSERT(!r);
ASSERT_EQ(0, r);
/* We are never doing multiple reads/connects at a time anyway, so these
* handles can be pre-initialized. */
@ -190,10 +234,10 @@ static void tcp_pinger_v6_new(int vectored_writes) {
&pinger->stream.tcp,
(const struct sockaddr*) &server_addr,
pinger_on_connect);
ASSERT(!r);
ASSERT_EQ(0, r);
/* Synchronous connect callbacks are not allowed. */
ASSERT(pinger_on_connect_count == 0);
ASSERT_EQ(pinger_on_connect_count, 0);
}
@ -202,17 +246,18 @@ static void tcp_pinger_new(int vectored_writes) {
struct sockaddr_in server_addr;
pinger_t* pinger;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));
ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));
pinger = malloc(sizeof(*pinger));
ASSERT(pinger != NULL);
ASSERT_NOT_NULL(pinger);
pinger->vectored_writes = vectored_writes;
pinger->state = 0;
pinger->pongs = 0;
pinger->pong = PING;
/* Try to connect to the server and do NUM_PINGS ping-pongs. */
r = uv_tcp_init(uv_default_loop(), &pinger->stream.tcp);
pinger->stream.tcp.data = pinger;
ASSERT(!r);
ASSERT_EQ(0, r);
/* We are never doing multiple reads/connects at a time anyway, so these
* handles can be pre-initialized. */
@ -220,10 +265,10 @@ static void tcp_pinger_new(int vectored_writes) {
&pinger->stream.tcp,
(const struct sockaddr*) &server_addr,
pinger_on_connect);
ASSERT(!r);
ASSERT_EQ(0, r);
/* Synchronous connect callbacks are not allowed. */
ASSERT(pinger_on_connect_count == 0);
ASSERT_EQ(pinger_on_connect_count, 0);
}
@ -232,15 +277,16 @@ static void pipe_pinger_new(int vectored_writes) {
pinger_t* pinger;
pinger = malloc(sizeof(*pinger));
ASSERT(pinger != NULL);
ASSERT_NOT_NULL(pinger);
pinger->vectored_writes = vectored_writes;
pinger->state = 0;
pinger->pongs = 0;
pinger->pong = PING;
/* Try to connect to the server and do NUM_PINGS ping-pongs. */
r = uv_pipe_init(uv_default_loop(), &pinger->stream.pipe, 0);
pinger->stream.pipe.data = pinger;
ASSERT(!r);
ASSERT_EQ(0, r);
/* We are never doing multiple reads/connects at a time anyway, so these
* handles can be pre-initialized. */
@ -248,13 +294,86 @@ static void pipe_pinger_new(int vectored_writes) {
pinger_on_connect);
/* Synchronous connect callbacks are not allowed. */
ASSERT(pinger_on_connect_count == 0);
ASSERT_EQ(pinger_on_connect_count, 0);
}
static void socketpair_pinger_new(int vectored_writes) {
pinger_t* pinger;
uv_os_sock_t fds[2];
uv_tcp_t* ponger;
pinger = malloc(sizeof(*pinger));
ASSERT_NOT_NULL(pinger);
pinger->vectored_writes = vectored_writes;
pinger->state = 0;
pinger->pongs = 0;
pinger->pong = PONG;
/* Try to make a socketpair and do NUM_PINGS ping-pongs. */
(void)uv_default_loop(); /* ensure WSAStartup has been performed */
ASSERT_EQ(0, uv_socketpair(SOCK_STREAM, 0, fds, UV_NONBLOCK_PIPE, UV_NONBLOCK_PIPE));
#ifndef _WIN32
/* On Windows, this is actually a UV_TCP, but libuv doesn't detect that. */
ASSERT_EQ(uv_guess_handle((uv_file) fds[0]), UV_NAMED_PIPE);
ASSERT_EQ(uv_guess_handle((uv_file) fds[1]), UV_NAMED_PIPE);
#endif
ASSERT_EQ(0, uv_tcp_init(uv_default_loop(), &pinger->stream.tcp));
pinger->stream.pipe.data = pinger;
ASSERT_EQ(0, uv_tcp_open(&pinger->stream.tcp, fds[1]));
ponger = malloc(sizeof(*ponger));
ASSERT_NOT_NULL(ponger);
ponger->data = NULL;
ASSERT_EQ(0, uv_tcp_init(uv_default_loop(), ponger));
ASSERT_EQ(0, uv_tcp_open(ponger, fds[0]));
pinger_write_ping(pinger);
ASSERT_EQ(0, uv_read_start((uv_stream_t*) &pinger->stream.tcp,
alloc_cb,
pinger_read_cb));
ASSERT_EQ(0, uv_read_start((uv_stream_t*) ponger,
alloc_cb,
ponger_read_cb));
}
static void pipe2_pinger_new(int vectored_writes) {
uv_file fds[2];
pinger_t* pinger;
uv_pipe_t* ponger;
/* Try to make a pipe and do NUM_PINGS pings. */
ASSERT_EQ(0, uv_pipe(fds, UV_NONBLOCK_PIPE, UV_NONBLOCK_PIPE));
ASSERT_EQ(uv_guess_handle(fds[0]), UV_NAMED_PIPE);
ASSERT_EQ(uv_guess_handle(fds[1]), UV_NAMED_PIPE);
ponger = malloc(sizeof(*ponger));
ASSERT_NOT_NULL(ponger);
ASSERT_EQ(0, uv_pipe_init(uv_default_loop(), ponger, 0));
ASSERT_EQ(0, uv_pipe_open(ponger, fds[0]));
pinger = malloc(sizeof(*pinger));
ASSERT_NOT_NULL(pinger);
pinger->vectored_writes = vectored_writes;
pinger->state = 0;
pinger->pongs = 0;
pinger->pong = PING;
ASSERT_EQ(0, uv_pipe_init(uv_default_loop(), &pinger->stream.pipe, 0));
ASSERT_EQ(0, uv_pipe_open(&pinger->stream.pipe, fds[1]));
pinger->stream.pipe.data = pinger; /* record for close_cb */
ponger->data = pinger; /* record for read_cb */
pinger_write_ping(pinger);
ASSERT_EQ(0, uv_read_start((uv_stream_t*) ponger, alloc_cb, pinger_read_cb));
}
static int run_ping_pong_test(void) {
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(completed_pingers == 1);
ASSERT_EQ(completed_pingers, 1);
MAKE_VALGRIND_HAPPY();
return 0;
@ -263,12 +382,20 @@ static int run_ping_pong_test(void) {
TEST_IMPL(tcp_ping_pong) {
tcp_pinger_new(0);
run_ping_pong_test();
completed_pingers = 0;
socketpair_pinger_new(0);
return run_ping_pong_test();
}
TEST_IMPL(tcp_ping_pong_vec) {
tcp_pinger_new(1);
run_ping_pong_test();
completed_pingers = 0;
socketpair_pinger_new(1);
return run_ping_pong_test();
}
@ -291,11 +418,19 @@ TEST_IMPL(tcp6_ping_pong_vec) {
TEST_IMPL(pipe_ping_pong) {
pipe_pinger_new(0);
run_ping_pong_test();
completed_pingers = 0;
pipe2_pinger_new(0);
return run_ping_pong_test();
}
TEST_IMPL(pipe_ping_pong_vec) {
pipe_pinger_new(1);
run_ping_pong_test();
completed_pingers = 0;
pipe2_pinger_new(1);
return run_ping_pong_test();
}

View File

@ -36,7 +36,7 @@ static int close_cb_called = 0;
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}

View File

@ -37,7 +37,7 @@ static int connect_cb_called = 0;
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}
@ -76,6 +76,9 @@ 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;

View File

@ -42,7 +42,7 @@ static uv_connect_t conn_req;
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}

View File

@ -96,7 +96,7 @@ TEST_IMPL(pipe_getsockname) {
int r;
loop = uv_default_loop();
ASSERT(loop != NULL);
ASSERT_NOT_NULL(loop);
r = uv_pipe_init(loop, &pipe_server, 0);
ASSERT(r == 0);
@ -225,7 +225,9 @@ TEST_IMPL(pipe_getsockname_blocking) {
ASSERT(r != -1);
r = uv_pipe_open(&pipe_client, readfd);
ASSERT(r == 0);
r = uv_read_start((uv_stream_t*)&pipe_client, NULL, NULL);
r = uv_read_start((uv_stream_t*) &pipe_client,
(uv_alloc_cb) abort,
(uv_read_cb) abort);
ASSERT(r == 0);
Sleep(100);
r = uv_read_stop((uv_stream_t*)&pipe_client);
@ -236,7 +238,9 @@ TEST_IMPL(pipe_getsockname_blocking) {
ASSERT(r == 0);
ASSERT(len1 == 0); /* It's an annonymous pipe. */
r = uv_read_start((uv_stream_t*)&pipe_client, NULL, NULL);
r = uv_read_start((uv_stream_t*)&pipe_client,
(uv_alloc_cb) abort,
(uv_read_cb) abort);
ASSERT(r == 0);
Sleep(100);

View File

@ -68,7 +68,7 @@ TEST_IMPL(pipe_server_close) {
int r;
loop = uv_default_loop();
ASSERT(loop != NULL);
ASSERT_NOT_NULL(loop);
r = uv_pipe_init(loop, &pipe_server, 0);
ASSERT(r == 0);

View File

@ -16,18 +16,10 @@
#include "uv.h"
#include "task.h"
#ifdef _WIN32
TEST_IMPL(pipe_set_non_blocking) {
RETURN_SKIP("Test not implemented on Windows.");
}
#else /* !_WIN32 */
#include <string.h> /* memset */
#ifndef _WIN32
#include <unistd.h> /* close */
#include <sys/types.h>
#include <sys/socket.h>
#endif
struct thread_ctx {
uv_barrier_t barrier;
@ -54,9 +46,28 @@ static void thread_main(void* arg) {
uv_fs_req_cleanup(&req);
} while (n > 0 || (n == -1 && uv_errno == UV_EINTR));
#ifdef _WIN32
ASSERT(n == UV_EOF);
#else
ASSERT(n == 0);
#endif
}
#ifdef _WIN32
static void write_cb(uv_write_t* req, int status) {
ASSERT(status == 0);
req->handle = NULL; /* signal completion of write_cb */
}
#endif
#ifdef _WIN32
#define NWRITES (10 << 16)
#else
#define NWRITES (10 << 20)
#endif
TEST_IMPL(pipe_set_non_blocking) {
struct thread_ctx ctx;
uv_pipe_t pipe_handle;
@ -66,9 +77,12 @@ TEST_IMPL(pipe_set_non_blocking) {
uv_buf_t buf;
uv_file fd[2];
int n;
#ifdef _WIN32
uv_write_t write_req;
#endif
ASSERT(0 == uv_pipe_init(uv_default_loop(), &pipe_handle, 0));
ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, fd));
ASSERT(0 == uv_pipe(fd, 0, 0));
ASSERT(0 == uv_pipe_open(&pipe_handle, fd[1]));
ASSERT(0 == uv_stream_set_blocking((uv_stream_t*) &pipe_handle, 1));
fd[1] = -1; /* fd[1] is owned by pipe_handle now. */
@ -83,11 +97,20 @@ TEST_IMPL(pipe_set_non_blocking) {
memset(data, '.', sizeof(data));
nwritten = 0;
while (nwritten < 10 << 20) {
while (nwritten < NWRITES) {
/* The stream is in blocking mode so uv_try_write() should always succeed
* with the exact number of bytes that we wanted written.
*/
n = uv_try_write((uv_stream_t*) &pipe_handle, &buf, 1);
#ifdef _WIN32
ASSERT(n == UV_EAGAIN); /* E_NOTIMPL */
ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &pipe_handle, &buf, 1, write_cb));
ASSERT_NOT_NULL(write_req.handle);
ASSERT(1 == uv_run(uv_default_loop(), UV_RUN_ONCE)); /* queue write_cb */
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); /* process write_cb */
ASSERT_NULL(write_req.handle); /* check for signaled completion of write_cb */
n = buf.len;
#endif
ASSERT(n == sizeof(data));
nwritten += n;
}
@ -96,12 +119,14 @@ TEST_IMPL(pipe_set_non_blocking) {
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
ASSERT(0 == uv_thread_join(&thread));
#ifdef _WIN32
ASSERT(0 == _close(fd[0])); /* fd[1] is closed by uv_close(). */
#else
ASSERT(0 == close(fd[0])); /* fd[1] is closed by uv_close(). */
#endif
fd[0] = -1;
uv_barrier_destroy(&ctx.barrier);
MAKE_VALGRIND_HAPPY();
return 0;
}
#endif /* !_WIN32 */

View File

@ -155,6 +155,7 @@ TEST_IMPL(platform_output) {
printf(" username: %s\n", pwd.username);
printf(" shell: %s\n", pwd.shell);
printf(" home directory: %s\n", pwd.homedir);
uv_os_free_passwd(&pwd);
pid = uv_os_getpid();
ASSERT(pid > 0);

View File

@ -0,0 +1,99 @@
/* 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 <errno.h>
#ifndef _WIN32
# include <fcntl.h>
# include <sys/socket.h>
# include <unistd.h>
#endif
#include "uv.h"
#include "task.h"
static int close_cb_called = 0;
static void close_cb(uv_handle_t* handle) {
close_cb_called++;
}
static void poll_cb(uv_poll_t* handle, int status, int events) {
/* Not a bound socket, linux immediately reports UV_READABLE, other OS do not */
ASSERT(events == UV_READABLE);
}
TEST_IMPL(poll_multiple_handles) {
uv_os_sock_t sock;
uv_poll_t first_poll_handle, second_poll_handle;
#ifdef _WIN32
{
struct WSAData wsa_data;
int r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
ASSERT(r == 0);
}
#endif
sock = socket(AF_INET, SOCK_STREAM, 0);
#ifdef _WIN32
ASSERT(sock != INVALID_SOCKET);
#else
ASSERT(sock != -1);
#endif
ASSERT(0 == uv_poll_init_socket(uv_default_loop(), &first_poll_handle, sock));
ASSERT(0 == uv_poll_init_socket(uv_default_loop(), &second_poll_handle, sock));
ASSERT(0 == uv_poll_start(&first_poll_handle, UV_READABLE, poll_cb));
/* We may not start polling while another polling handle is active
* on that fd.
*/
#ifndef _WIN32
/* We do not track handles in an O(1) lookupable way on Windows,
* so not checking that here.
*/
ASSERT(uv_poll_start(&second_poll_handle, UV_READABLE, poll_cb) == UV_EEXIST);
#endif
/* After stopping the other polling handle, we now should be able to poll */
ASSERT(0 == uv_poll_stop(&first_poll_handle));
ASSERT(0 == uv_poll_start(&second_poll_handle, UV_READABLE, poll_cb));
/* Closing an already stopped polling handle is safe in any case */
uv_close((uv_handle_t*) &first_poll_handle, close_cb);
uv_unref((uv_handle_t*) &second_poll_handle);
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
ASSERT(close_cb_called == 1);
uv_ref((uv_handle_t*) &second_poll_handle);
ASSERT(uv_is_active((uv_handle_t*) &second_poll_handle));
uv_close((uv_handle_t*) &second_poll_handle, close_cb);
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
ASSERT(close_cb_called == 2);
MAKE_VALGRIND_HAPPY();
return 0;
}

View File

@ -147,7 +147,7 @@ static connection_context_t* create_connection_context(
connection_context_t* context;
context = (connection_context_t*) malloc(sizeof *context);
ASSERT(context != NULL);
ASSERT_NOT_NULL(context);
context->sock = sock;
context->is_server_connection = is_server_connection;
@ -464,7 +464,7 @@ static server_context_t* create_server_context(
server_context_t* context;
context = (server_context_t*) malloc(sizeof *context);
ASSERT(context != NULL);
ASSERT_NOT_NULL(context);
context->sock = sock;
context->connections = 0;

View File

@ -154,7 +154,7 @@ TEST_IMPL(check_ref) {
static void prepare_cb(uv_prepare_t* h) {
ASSERT(h != NULL);
ASSERT_NOT_NULL(h);
uv_unref((uv_handle_t*)h);
}

View File

@ -89,7 +89,13 @@ static void connect_cb(uv_connect_t *req, int status) {
ASSERT(req == &connect_req);
/* Start reading from our connection so we can receive the EOF. */
uv_read_start((uv_stream_t*)&tcp, alloc_cb, read_cb);
ASSERT_EQ(0, uv_read_start((uv_stream_t*)&tcp, alloc_cb, read_cb));
/* Check error handling. */
ASSERT_EQ(UV_EALREADY, uv_read_start((uv_stream_t*)&tcp, alloc_cb, read_cb));
ASSERT_EQ(UV_EINVAL, uv_read_start(NULL, alloc_cb, read_cb));
ASSERT_EQ(UV_EINVAL, uv_read_start((uv_stream_t*)&tcp, NULL, read_cb));
ASSERT_EQ(UV_EINVAL, uv_read_start((uv_stream_t*)&tcp, alloc_cb, NULL));
/*
* Write the letter 'Q' to gracefully kill the echo-server. This will not

View File

@ -0,0 +1,135 @@
/* 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>
static uv_tcp_t tcp;
static uv_connect_t connect_req;
static uv_shutdown_t shutdown_req;
static uv_buf_t qbuf;
static int got_q;
static int got_eof;
static int called_connect_cb;
static int called_shutdown_cb;
static int called_tcp_close_cb;
static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
buf->base = malloc(size);
buf->len = size;
}
static void shutdown_cb(uv_shutdown_t *req, int status) {
ASSERT_PTR_EQ(req, &shutdown_req);
ASSERT_EQ(called_connect_cb, 1);
ASSERT_EQ(called_tcp_close_cb, 0);
}
static void read_cb(uv_stream_t* t, ssize_t nread, const uv_buf_t* buf) {
ASSERT_PTR_EQ((uv_tcp_t*)t, &tcp);
if (nread == 0) {
free(buf->base);
return;
}
if (!got_q) {
ASSERT_EQ(nread, 4);
ASSERT_EQ(got_eof, 0);
ASSERT_MEM_EQ(buf->base, "QQSS", 4);
free(buf->base);
got_q = 1;
puts("got QQSS");
/* Shutdown our end of the connection simultaneously */
uv_shutdown(&shutdown_req, (uv_stream_t*) &tcp, shutdown_cb);
called_shutdown_cb++;
} else {
ASSERT_EQ(nread, UV_EOF);
if (buf->base) {
free(buf->base);
}
got_eof = 1;
puts("got EOF");
}
}
static void connect_cb(uv_connect_t *req, int status) {
ASSERT_EQ(status, 0);
ASSERT_PTR_EQ(req, &connect_req);
/* Start reading from our connection so we can receive the EOF. */
ASSERT_EQ(0, uv_read_start((uv_stream_t*)&tcp, alloc_cb, read_cb));
/* Check error handling. */
ASSERT_EQ(UV_EALREADY, uv_read_start((uv_stream_t*)&tcp, alloc_cb, read_cb));
ASSERT_EQ(UV_EINVAL, uv_read_start(NULL, alloc_cb, read_cb));
ASSERT_EQ(UV_EINVAL, uv_read_start((uv_stream_t*)&tcp, NULL, read_cb));
ASSERT_EQ(UV_EINVAL, uv_read_start((uv_stream_t*)&tcp, alloc_cb, NULL));
/*
* Write the letter 'Q' and 'QSS` to gracefully kill the echo-server. This
* will not effect our connection.
*/
ASSERT_EQ(qbuf.len, uv_try_write((uv_stream_t*) &tcp, &qbuf, 1));
called_connect_cb++;
ASSERT_EQ(called_shutdown_cb, 0);
}
/*
* This test has a client which connects to the echo_server and immediately
* issues a shutdown. We check that this does not cause libuv to hang.
*/
TEST_IMPL(shutdown_simultaneous) {
struct sockaddr_in server_addr;
int r;
qbuf.base = "QQSS";
qbuf.len = 4;
ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));
r = uv_tcp_init(uv_default_loop(), &tcp);
ASSERT_EQ(r, 0);
r = uv_tcp_connect(&connect_req,
&tcp,
(const struct sockaddr*) &server_addr,
connect_cb);
ASSERT_EQ(r, 0);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT_EQ(called_connect_cb, 1);
ASSERT_EQ(called_shutdown_cb, 1);
ASSERT_EQ(got_eof, 1);
ASSERT_EQ(got_q, 1);
MAKE_VALGRIND_HAPPY();
return 0;
}

View File

@ -170,7 +170,7 @@ static void loop_creating_worker(void* context) {
int r;
loop = malloc(sizeof(*loop));
ASSERT(loop != NULL);
ASSERT_NOT_NULL(loop);
ASSERT(0 == uv_loop_init(loop));
r = uv_signal_init(loop, &signal);

View File

@ -49,7 +49,7 @@ static void close_cb(uv_handle_t *handle) {
static void write_cb(uv_write_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == UV_EPIPE);
free(buf);
uv_close((uv_handle_t *) &pipe_hdl, close_cb);
@ -76,7 +76,7 @@ TEST_IMPL(signal_pending_on_close) {
/* Write data large enough so it needs loop iteration */
buf = malloc(1<<24);
ASSERT(buf != NULL);
ASSERT_NOT_NULL(buf);
memset(buf, '.', 1<<24);
buffer = uv_buf_init(buf, 1<<24);

View File

@ -29,11 +29,9 @@
#include <string.h>
#ifdef _WIN32
# if defined(__MINGW32__)
# include <basetyps.h>
# endif
# include <shellapi.h>
# include <wchar.h>
typedef BOOL (WINAPI *sCompareObjectHandles)(_In_ HANDLE, _In_ HANDLE);
#else
# include <unistd.h>
# include <sys/wait.h>
@ -49,9 +47,7 @@ static char exepath[1024];
static size_t exepath_size = 1024;
static char* args[5];
static int no_term_signal;
#ifndef _WIN32
static int timer_counter;
#endif
static uv_tcp_t tcp_server;
#define OUTPUT_SIZE 1024
@ -140,12 +136,10 @@ static void on_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
}
#ifndef _WIN32
static void on_read_once(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
uv_read_stop(tcp);
on_read(tcp, nread, buf);
}
#endif
static void write_cb(uv_write_t* req, int status) {
@ -154,6 +148,11 @@ static void write_cb(uv_write_t* req, int status) {
}
static void write_null_cb(uv_write_t* req, int status) {
ASSERT(status == 0);
}
static void init_process_options(char* test, uv_exit_cb exit_cb) {
/* Note spawn_helper1 defined in test/run-tests.c */
int r = uv_exepath(exepath, &exepath_size);
@ -177,11 +176,9 @@ static void timer_cb(uv_timer_t* handle) {
}
#ifndef _WIN32
static void timer_counter_cb(uv_timer_t* handle) {
++timer_counter;
}
#endif
TEST_IMPL(spawn_fails) {
@ -1179,7 +1176,7 @@ TEST_IMPL(argument_escaping) {
WCHAR* non_verbatim_output;
test_output = calloc(count, sizeof(WCHAR*));
ASSERT(test_output != NULL);
ASSERT_NOT_NULL(test_output);
for (i = 0; i < count; ++i) {
test_output[i] = calloc(2 * (wcslen(test_str[i]) + 2), sizeof(WCHAR));
quote_cmd_arg(test_str[i], test_output[i]);
@ -1188,7 +1185,7 @@ TEST_IMPL(argument_escaping) {
total_size += wcslen(test_output[i]) + 1;
}
command_line = calloc(total_size + 1, sizeof(WCHAR));
ASSERT(command_line != NULL);
ASSERT_NOT_NULL(command_line);
for (i = 0; i < count; ++i) {
wcscat(command_line, test_output[i]);
wcscat(command_line, L" ");
@ -1328,9 +1325,8 @@ TEST_IMPL(environment_creation) {
found = 1;
}
}
if (prev) { /* verify sort order -- requires Vista */
#if _WIN32_WINNT >= 0x0600 && \
(!defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR))
if (prev) { /* verify sort order */
#if !defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR)
ASSERT(CompareStringOrdinal(prev, -1, str, -1, TRUE) == 1);
#endif
}
@ -1355,7 +1351,7 @@ TEST_IMPL(spawn_with_an_odd_path) {
char newpath[2048];
char *path = getenv("PATH");
ASSERT(path != NULL);
ASSERT_NOT_NULL(path);
snprintf(newpath, 2048, ";.;%s", path);
SetEnvironmentVariable("PATH", newpath);
@ -1389,7 +1385,7 @@ TEST_IMPL(spawn_setuid_setgid) {
/* become the "nobody" user. */
pw = getpwnam("nobody");
ASSERT(pw != NULL);
ASSERT_NOT_NULL(pw);
options.uid = pw->pw_uid;
options.gid = pw->pw_gid;
snprintf(uidstr, sizeof(uidstr), "%d", pw->pw_uid);
@ -1427,7 +1423,7 @@ TEST_IMPL(spawn_setuid_fails) {
if (uid == 0) {
struct passwd* pw;
pw = getpwnam("nobody");
ASSERT(pw != NULL);
ASSERT_NOT_NULL(pw);
ASSERT(0 == setgid(pw->pw_gid));
ASSERT(0 == setuid(pw->pw_uid));
}
@ -1478,7 +1474,7 @@ TEST_IMPL(spawn_setgid_fails) {
if (uid == 0) {
struct passwd* pw;
pw = getpwnam("nobody");
ASSERT(pw != NULL);
ASSERT_NOT_NULL(pw);
ASSERT(0 == setgid(pw->pw_gid));
ASSERT(0 == setuid(pw->pw_uid));
}
@ -1579,17 +1575,27 @@ TEST_IMPL(spawn_auto_unref) {
}
#ifndef _WIN32
TEST_IMPL(spawn_fs_open) {
int fd;
int r;
uv_os_fd_t fd;
uv_os_fd_t dup_fd;
uv_fs_t fs_req;
uv_pipe_t in;
uv_write_t write_req;
uv_write_t write_req2;
uv_buf_t buf;
uv_stdio_container_t stdio[1];
#ifdef _WIN32
const char dev_null[] = "NUL";
HMODULE kernelbase_module;
sCompareObjectHandles pCompareObjectHandles; /* function introduced in Windows 10 */
#else
const char dev_null[] = "/dev/null";
#endif
fd = uv_fs_open(NULL, &fs_req, "/dev/null", O_RDWR, 0, NULL);
ASSERT(fd >= 0);
r = uv_fs_open(NULL, &fs_req, dev_null, O_RDWR, 0, NULL);
ASSERT(r != -1);
fd = uv_get_osfhandle((uv_file) fs_req.result);
uv_fs_req_cleanup(&fs_req);
init_process_options("spawn_helper8", exit_cb);
@ -1601,13 +1607,28 @@ TEST_IMPL(spawn_fs_open) {
options.stdio[0].data.stream = (uv_stream_t*) &in;
options.stdio_count = 1;
/* make an inheritable copy */
#ifdef _WIN32
ASSERT(0 != DuplicateHandle(GetCurrentProcess(), fd, GetCurrentProcess(), &dup_fd,
0, /* inherit */ TRUE, DUPLICATE_SAME_ACCESS));
kernelbase_module = GetModuleHandleA("kernelbase.dll");
pCompareObjectHandles = (sCompareObjectHandles)
GetProcAddress(kernelbase_module, "CompareObjectHandles");
ASSERT(pCompareObjectHandles == NULL || pCompareObjectHandles(fd, dup_fd));
#else
dup_fd = dup(fd);
#endif
ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options));
buf = uv_buf_init((char*) &fd, sizeof(fd));
ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb));
ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_null_cb));
buf = uv_buf_init((char*) &dup_fd, sizeof(fd));
ASSERT(0 == uv_write(&write_req2, (uv_stream_t*) &in, &buf, 1, write_cb));
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
ASSERT(0 == uv_fs_close(NULL, &fs_req, fd, NULL));
ASSERT(0 == uv_fs_close(NULL, &fs_req, r, NULL));
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 2); /* One for `in`, one for process */
@ -1615,17 +1636,20 @@ TEST_IMPL(spawn_fs_open) {
MAKE_VALGRIND_HAPPY();
return 0;
}
#endif /* !_WIN32 */
#ifndef _WIN32
TEST_IMPL(closed_fd_events) {
uv_stdio_container_t stdio[3];
uv_pipe_t pipe_handle;
int fd[2];
uv_fs_t req;
uv_buf_t bufs[1];
uv_file fd[2];
bufs[0] = uv_buf_init("", 1);
/* create a pipe and share it with a child process */
ASSERT(0 == pipe(fd));
ASSERT(0 == uv_pipe(fd, 0, 0));
ASSERT(fd[0] > 2);
ASSERT(fd[1] > 2);
/* spawn_helper4 blocks indefinitely. */
init_process_options("spawn_helper4", exit_cb);
@ -1642,12 +1666,18 @@ TEST_IMPL(closed_fd_events) {
/* read from the pipe with uv */
ASSERT(0 == uv_pipe_init(uv_default_loop(), &pipe_handle, 0));
ASSERT(0 == uv_pipe_open(&pipe_handle, fd[0]));
/* uv_pipe_open() takes ownership of the file descriptor. */
fd[0] = -1;
ASSERT(0 == uv_read_start((uv_stream_t*) &pipe_handle, on_alloc, on_read_once));
ASSERT(1 == write(fd[1], "", 1));
ASSERT(1 == uv_fs_write(NULL, &req, fd[1], bufs, 1, -1, NULL));
ASSERT(req.result == 1);
uv_fs_req_cleanup(&req);
#ifdef _WIN32
ASSERT(1 == uv_run(uv_default_loop(), UV_RUN_ONCE));
#endif
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
/* should have received just one byte */
@ -1656,7 +1686,9 @@ TEST_IMPL(closed_fd_events) {
/* close the pipe and see if we still get events */
uv_close((uv_handle_t*) &pipe_handle, close_cb);
ASSERT(1 == write(fd[1], "", 1));
ASSERT(1 == uv_fs_write(NULL, &req, fd[1], bufs, 1, -1, NULL));
ASSERT(req.result == 1);
uv_fs_req_cleanup(&req);
ASSERT(0 == uv_timer_init(uv_default_loop(), &timer));
ASSERT(0 == uv_timer_start(&timer, timer_counter_cb, 10, 0));
@ -1669,13 +1701,17 @@ TEST_IMPL(closed_fd_events) {
ASSERT(timer_counter == 1);
/* cleanup */
ASSERT(0 == uv_process_kill(&process, /* SIGTERM */ 15));
ASSERT(0 == uv_process_kill(&process, SIGTERM));
#ifdef _WIN32
ASSERT(0 == _close(fd[1]));
#else
ASSERT(0 == close(fd[1]));
#endif
MAKE_VALGRIND_HAPPY();
return 0;
}
#endif /* !_WIN32 */
TEST_IMPL(spawn_reads_child_path) {
int r;
@ -1746,38 +1782,6 @@ TEST_IMPL(spawn_reads_child_path) {
return 0;
}
#ifndef _WIN32
static int mpipe(int *fds) {
if (pipe(fds) == -1)
return -1;
if (fcntl(fds[0], F_SETFD, FD_CLOEXEC) == -1 ||
fcntl(fds[1], F_SETFD, FD_CLOEXEC) == -1) {
close(fds[0]);
close(fds[1]);
return -1;
}
return 0;
}
#else
static int mpipe(int *fds) {
SECURITY_ATTRIBUTES attr;
HANDLE readh, writeh;
attr.nLength = sizeof(attr);
attr.lpSecurityDescriptor = NULL;
attr.bInheritHandle = FALSE;
if (!CreatePipe(&readh, &writeh, &attr, 0))
return -1;
fds[0] = _open_osfhandle((intptr_t)readh, 0);
fds[1] = _open_osfhandle((intptr_t)writeh, 0);
if (fds[0] == -1 || fds[1] == -1) {
CloseHandle(readh);
CloseHandle(writeh);
return -1;
}
return 0;
}
#endif /* !_WIN32 */
TEST_IMPL(spawn_inherit_streams) {
uv_process_t child_req;
uv_stdio_container_t child_stdio[2];
@ -1803,8 +1807,8 @@ TEST_IMPL(spawn_inherit_streams) {
ASSERT(uv_pipe_init(loop, &pipe_stdin_parent, 0) == 0);
ASSERT(uv_pipe_init(loop, &pipe_stdout_parent, 0) == 0);
ASSERT(mpipe(fds_stdin) != -1);
ASSERT(mpipe(fds_stdout) != -1);
ASSERT(uv_pipe(fds_stdin, 0, 0) == 0);
ASSERT(uv_pipe(fds_stdout, 0, 0) == 0);
ASSERT(uv_pipe_open(&pipe_stdin_child, fds_stdin[0]) == 0);
ASSERT(uv_pipe_open(&pipe_stdout_child, fds_stdout[1]) == 0);

View File

@ -53,7 +53,7 @@ static void conn_read_cb(uv_stream_t* stream,
ssize_t nread,
const uv_buf_t* buf) {
ASSERT(nread == UV_ENOBUFS);
ASSERT(buf->base == NULL);
ASSERT_NULL(buf->base);
ASSERT(buf->len == 0);
uv_close((uv_handle_t*) &incoming, close_cb);

View File

@ -25,16 +25,59 @@
#include <stdlib.h>
static int connect_cb_called = 0;
static int close_cb_called = 0;
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}
TEST_IMPL(tcp_bind_error_addrinuse) {
static void connect_cb(uv_connect_t* req, int status) {
ASSERT(status == UV_EADDRINUSE);
uv_close((uv_handle_t*) req->handle, close_cb);
connect_cb_called++;
}
TEST_IMPL(tcp_bind_error_addrinuse_connect) {
struct sockaddr_in addr;
int addrlen;
uv_connect_t req;
uv_tcp_t conn;
/* 127.0.0.1:<TEST_PORT> is already taken by tcp4_echo_server running in
* another process. uv_tcp_bind() and uv_tcp_connect() should still succeed
* (greatest common denominator across platforms) but the connect callback
* should receive an UV_EADDRINUSE error.
*/
ASSERT(0 == uv_tcp_init(uv_default_loop(), &conn));
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
ASSERT(0 == uv_tcp_bind(&conn, (const struct sockaddr*) &addr, 0));
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT + 1, &addr));
ASSERT(0 == uv_tcp_connect(&req,
&conn,
(const struct sockaddr*) &addr,
connect_cb));
addrlen = sizeof(addr);
ASSERT(UV_EADDRINUSE == uv_tcp_getsockname(&conn,
(struct sockaddr*) &addr,
&addrlen));
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
ASSERT(connect_cb_called == 1);
ASSERT(close_cb_called == 1);
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(tcp_bind_error_addrinuse_listen) {
struct sockaddr_in addr;
uv_tcp_t server1, server2;
int r;
@ -240,7 +283,9 @@ TEST_IMPL(tcp_bind_writable_flags) {
ASSERT(r == UV_EPIPE);
r = uv_shutdown(&shutdown_req, (uv_stream_t*) &server, NULL);
ASSERT(r == UV_ENOTCONN);
r = uv_read_start((uv_stream_t*) &server, NULL, NULL);
r = uv_read_start((uv_stream_t*) &server,
(uv_alloc_cb) abort,
(uv_read_cb) abort);
ASSERT(r == UV_ENOTCONN);
uv_close((uv_handle_t*)&server, close_cb);

View File

@ -29,7 +29,7 @@ static int close_cb_called = 0;
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}

View File

@ -46,7 +46,7 @@ static void connect_cb(uv_connect_t* conn_req, int status) {
buf = uv_buf_init("PING", 4);
for (i = 0; i < NUM_WRITE_REQS; i++) {
req = malloc(sizeof *req);
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
r = uv_write(req, (uv_stream_t*)&tcp_handle, &buf, 1, write_cb);
ASSERT(r == 0);

View File

@ -31,14 +31,14 @@ static int close_cb_called = 0;
static void connect_cb(uv_connect_t* handle, int status) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
connect_cb_called++;
}
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}

View File

@ -111,7 +111,7 @@ static int is_supported_system(void) {
if (cnt != 3) {
return 0;
}
// relase >= 10.0.16299
/* relase >= 10.0.16299 */
for (cnt = 0; cnt < 3; ++cnt) {
if (semver[cnt] > min_semver[cnt])
return 1;

View File

@ -30,13 +30,13 @@ static int close_cb_called = 0;
static void connect_cb(uv_connect_t* handle, int status) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
connect_cb_called++;
}
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}

View File

@ -44,7 +44,7 @@ static void on_connection(uv_stream_t* server, int status) {
ASSERT(status == 0);
handle = malloc(sizeof(*handle));
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
r = uv_tcp_init_ex(server->loop, handle, AF_INET);
ASSERT(r == 0);

View File

@ -96,7 +96,7 @@ static void alloc_cb(uv_handle_t* handle,
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}
@ -111,7 +111,7 @@ static void shutdown_cb(uv_shutdown_t* req, int status) {
static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
ASSERT(tcp != NULL);
ASSERT_NOT_NULL(tcp);
if (nread >= 0) {
ASSERT(nread == 4);
@ -126,7 +126,7 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
static void read1_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
int i;
ASSERT(tcp != NULL);
ASSERT_NOT_NULL(tcp);
if (nread >= 0) {
for (i = 0; i < nread; ++i)
@ -140,7 +140,7 @@ static void read1_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
static void write_cb(uv_write_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
if (status) {
fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));
@ -155,7 +155,7 @@ static void write1_cb(uv_write_t* req, int status) {
uv_buf_t buf;
int r;
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
if (status) {
ASSERT(shutdown_cb_called);
return;
@ -237,6 +237,7 @@ TEST_IMPL(tcp_open) {
struct sockaddr_in addr;
uv_os_sock_t sock;
int r;
uv_tcp_t client2;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
@ -257,8 +258,6 @@ TEST_IMPL(tcp_open) {
#ifndef _WIN32
{
uv_tcp_t client2;
r = uv_tcp_init(uv_default_loop(), &client2);
ASSERT(r == 0);
@ -267,7 +266,9 @@ TEST_IMPL(tcp_open) {
uv_close((uv_handle_t*) &client2, NULL);
}
#endif /* !_WIN32 */
#else /* _WIN32 */
(void)client2;
#endif
uv_run(uv_default_loop(), UV_RUN_DEFAULT);

View File

@ -52,13 +52,13 @@ static void close_socket(uv_tcp_t* sock) {
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}
static void write_cb(uv_write_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status != 0);
fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));

View File

@ -110,7 +110,7 @@ TEST_IMPL(tcp_write_to_half_open_connection) {
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
loop = uv_default_loop();
ASSERT(loop != NULL);
ASSERT_NOT_NULL(loop);
r = uv_tcp_init(loop, &tcp_server);
ASSERT(r == 0);

View File

@ -57,7 +57,7 @@ static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}
@ -82,7 +82,7 @@ static void shutdown_cb(uv_shutdown_t* req, int status) {
static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
ASSERT(tcp != NULL);
ASSERT_NOT_NULL(tcp);
if (nread >= 0) {
bytes_received_done += nread;
@ -98,7 +98,7 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
static void write_cb(uv_write_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
if (status) {
fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));
@ -152,7 +152,7 @@ TEST_IMPL(tcp_writealot) {
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
send_buffer = calloc(1, TOTAL_BYTES);
ASSERT(send_buffer != NULL);
ASSERT_NOT_NULL(send_buffer);
r = uv_tcp_init(uv_default_loop(), &client);
ASSERT(r == 0);

View File

@ -194,11 +194,11 @@ TEST_IMPL(threadpool_multiple_event_loops) {
static void tls_thread(void* arg) {
ASSERT(NULL == uv_key_get(&tls_key));
ASSERT_NULL(uv_key_get(&tls_key));
uv_key_set(&tls_key, arg);
ASSERT(arg == uv_key_get(&tls_key));
uv_key_set(&tls_key, NULL);
ASSERT(NULL == uv_key_get(&tls_key));
ASSERT_NULL(uv_key_get(&tls_key));
}
@ -206,7 +206,7 @@ TEST_IMPL(thread_local_storage) {
char name[] = "main";
uv_thread_t threads[2];
ASSERT(0 == uv_key_create(&tls_key));
ASSERT(NULL == uv_key_get(&tls_key));
ASSERT_NULL(uv_key_get(&tls_key));
uv_key_set(&tls_key, name);
ASSERT(name == uv_key_get(&tls_key));
ASSERT(0 == uv_thread_create(threads + 0, tls_thread, threads + 0));

View File

@ -98,7 +98,7 @@ static void getaddrinfo_cb(uv_getaddrinfo_t* req,
int status,
struct addrinfo* res) {
ASSERT(status == UV_EAI_CANCELED);
ASSERT(res == NULL);
ASSERT_NULL(res);
uv_freeaddrinfo(res); /* Should not crash. */
}
@ -108,8 +108,8 @@ static void getnameinfo_cb(uv_getnameinfo_t* handle,
const char* hostname,
const char* service) {
ASSERT(status == UV_EAI_CANCELED);
ASSERT(hostname == NULL);
ASSERT(service == NULL);
ASSERT_NULL(hostname);
ASSERT_NULL(service);
}

View File

@ -35,7 +35,7 @@ static uint64_t start_time;
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}

View File

@ -37,7 +37,7 @@ static uv_timer_t huge_timer2;
static void once_close_cb(uv_handle_t* handle) {
printf("ONCE_CLOSE_CB\n");
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
ASSERT(0 == uv_is_active(handle));
once_close_cb_called++;
@ -47,7 +47,7 @@ static void once_close_cb(uv_handle_t* handle) {
static void once_cb(uv_timer_t* handle) {
printf("ONCE_CB %d\n", once_cb_called);
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
ASSERT(0 == uv_is_active((uv_handle_t*) handle));
once_cb_called++;
@ -62,7 +62,7 @@ static void once_cb(uv_timer_t* handle) {
static void repeat_close_cb(uv_handle_t* handle) {
printf("REPEAT_CLOSE_CB\n");
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
repeat_close_cb_called++;
}
@ -71,7 +71,7 @@ static void repeat_close_cb(uv_handle_t* handle) {
static void repeat_cb(uv_timer_t* handle) {
printf("REPEAT_CB\n");
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
ASSERT(1 == uv_is_active((uv_handle_t*) handle));
repeat_cb_called++;

View File

@ -55,7 +55,7 @@ static void print_err_msg(const char* expect, ssize_t expect_len,
static void tty_alloc(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
buf->base = malloc(size);
ASSERT(buf->base != NULL);
ASSERT_NOT_NULL(buf->base);
buf->len = size;
}

View File

@ -212,9 +212,9 @@ static void capture_screen(uv_tty_t* tty_out, struct captured_screen* cs) {
origin.X = 0;
origin.Y = cs->si.csbi.srWindow.Top;
cs->text = malloc(cs->si.length * sizeof(*cs->text));
ASSERT(cs->text != NULL);
ASSERT_NOT_NULL(cs->text);
cs->attributes = (WORD*) malloc(cs->si.length * sizeof(*cs->attributes));
ASSERT(cs->attributes != NULL);
ASSERT_NOT_NULL(cs->attributes);
ASSERT(ReadConsoleOutputCharacter(
tty_out->handle, cs->text, cs->si.length, origin, &length));
ASSERT((unsigned int) cs->si.length == length);

View File

@ -426,6 +426,9 @@ TEST_IMPL(tty_pty) {
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
#if defined(__ASAN__)
RETURN_SKIP("Test does not currently work in ASAN");
#endif
#if defined(__APPLE__) || \
defined(__DragonFly__) || \

View File

@ -83,7 +83,7 @@ static void cl_recv_cb(uv_udp_t* handle,
static void cl_send_cb(uv_udp_send_t* req, int status) {
int r;
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
CHECK_HANDLE(req->handle);
@ -95,7 +95,7 @@ static void cl_send_cb(uv_udp_send_t* req, int status) {
static void sv_send_cb(uv_udp_send_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
CHECK_HANDLE(req->handle);
@ -121,14 +121,14 @@ static void sv_recv_cb(uv_udp_t* handle,
if (nread == 0) {
/* Returning unused buffer. Don't count towards sv_recv_cb_called */
ASSERT(addr == NULL);
ASSERT_NULL(addr);
return;
}
CHECK_HANDLE(handle);
ASSERT(flags == 0);
ASSERT(addr != NULL);
ASSERT_NOT_NULL(addr);
ASSERT(nread == 4);
ASSERT(!memcmp("PING", rcvbuf->base, nread));
@ -136,7 +136,7 @@ static void sv_recv_cb(uv_udp_t* handle,
ASSERT(r == 0);
req = malloc(sizeof *req);
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
sndbuf = uv_buf_init("PONG", 4);
r = uv_udp_send(req, handle, &sndbuf, 1, addr, sv_send_cb);

View File

@ -61,7 +61,7 @@ static void close_cb(uv_handle_t* handle) {
static void cl_send_cb(uv_udp_send_t* req, int status) {
int r;
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
CHECK_HANDLE(req->handle);
if (++cl_send_cb_called == 1) {
@ -87,7 +87,7 @@ static void sv_recv_cb(uv_udp_t* handle,
unsigned flags) {
if (nread > 0) {
ASSERT(nread == 4);
ASSERT(addr != NULL);
ASSERT_NOT_NULL(addr);
ASSERT(memcmp("EXIT", rcvbuf->base, nread) == 0);
if (++sv_recv_cb_called == 4) {
uv_close((uv_handle_t*) &server, close_cb);
@ -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 wih 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

View File

@ -54,7 +54,7 @@ static void alloc_cb(uv_handle_t* handle,
/* Actually malloc to exercise free'ing the buffer later */
buf->base = malloc(buffer_size);
ASSERT(buf->base != NULL);
ASSERT_NOT_NULL(buf->base);
buf->len = buffer_size;
alloc_cb_called++;
}
@ -77,13 +77,13 @@ static void recv_cb(uv_udp_t* handle,
/* free and return if this is a mmsg free-only callback invocation */
if (flags & UV_UDP_MMSG_FREE) {
ASSERT_EQ(nread, 0);
ASSERT(addr == NULL);
ASSERT_NULL(addr);
free(rcvbuf->base);
return;
}
ASSERT_EQ(nread, 4);
ASSERT(addr != NULL);
ASSERT_NOT_NULL(addr);
ASSERT_MEM_EQ("PING", rcvbuf->base, nread);
recv_cb_called++;

View File

@ -43,7 +43,7 @@ static void close_cb(uv_handle_t* handle) {
static void sv_send_cb(uv_udp_send_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0 || status == UV_ENETUNREACH || status == UV_EPERM);
CHECK_HANDLE(req->handle);

View File

@ -43,7 +43,7 @@ static void close_cb(uv_handle_t* handle) {
static void sv_send_cb(uv_udp_send_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
CHECK_HANDLE(req->handle);

View File

@ -60,7 +60,7 @@ static void close_cb(uv_handle_t* handle) {
static void sv_send_cb(uv_udp_send_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
CHECK_HANDLE(req->handle);
@ -103,11 +103,11 @@ static void cl_recv_cb(uv_udp_t* handle,
if (nread == 0) {
/* Returning unused buffer. Don't count towards cl_recv_cb_called */
ASSERT(addr == NULL);
ASSERT_NULL(addr);
return;
}
ASSERT(addr != NULL);
ASSERT_NOT_NULL(addr);
ASSERT(nread == 4);
ASSERT(!memcmp("PING", buf->base, nread));

View File

@ -72,7 +72,7 @@ static void close_cb(uv_handle_t* handle) {
static void sv_send_cb(uv_udp_send_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
CHECK_HANDLE(req->handle);
@ -115,11 +115,11 @@ static void cl_recv_cb(uv_udp_t* handle,
if (nread == 0) {
/* Returning unused buffer. Don't count towards cl_recv_cb_called */
ASSERT(addr == NULL);
ASSERT_NULL(addr);
return;
}
ASSERT(addr != NULL);
ASSERT_NOT_NULL(addr);
ASSERT(nread == 4);
ASSERT(!memcmp("PING", buf->base, nread));

View File

@ -43,7 +43,7 @@ static void close_cb(uv_handle_t* handle) {
static void sv_send_cb(uv_udp_send_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0 || status == UV_ENETUNREACH || status == UV_EPERM);
CHECK_HANDLE(req->handle);

View File

@ -91,7 +91,7 @@ static void alloc_cb(uv_handle_t* handle,
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
ASSERT_NOT_NULL(handle);
close_cb_called++;
}
@ -109,13 +109,13 @@ static void recv_cb(uv_udp_t* handle,
if (nread == 0) {
/* Returning unused buffer. Don't count towards sv_recv_cb_called */
ASSERT(addr == NULL);
ASSERT_NULL(addr);
return;
}
ASSERT(flags == 0);
ASSERT(addr != NULL);
ASSERT_NOT_NULL(addr);
ASSERT(nread == 4);
ASSERT(memcmp("PING", buf->base, nread) == 0);
@ -127,7 +127,7 @@ static void recv_cb(uv_udp_t* handle,
static void send_cb(uv_udp_send_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
send_cb_called++;
@ -138,7 +138,7 @@ static void send_cb(uv_udp_send_t* req, int status) {
TEST_IMPL(udp_open) {
struct sockaddr_in addr;
uv_buf_t buf = uv_buf_init("PING", 4);
uv_udp_t client;
uv_udp_t client, client2;
uv_os_sock_t sock;
int r;
@ -169,8 +169,6 @@ TEST_IMPL(udp_open) {
#ifndef _WIN32
{
uv_udp_t client2;
r = uv_udp_init(uv_default_loop(), &client2);
ASSERT(r == 0);
@ -179,7 +177,9 @@ TEST_IMPL(udp_open) {
uv_close((uv_handle_t*) &client2, NULL);
}
#endif /* !_WIN32 */
#else /* _WIN32 */
(void)client2;
#endif
uv_run(uv_default_loop(), UV_RUN_DEFAULT);

View File

@ -73,11 +73,11 @@ static void cl_recv_cb(uv_udp_t* handle,
if (nread == 0) {
/* Returning unused buffer. Don't count towards cl_recv_cb_called */
ASSERT(addr == NULL);
ASSERT_NULL(addr);
return;
}
ASSERT(addr != NULL);
ASSERT_NOT_NULL(addr);
ASSERT(nread == 4);
ASSERT(!memcmp("PONG", buf->base, nread));
@ -90,7 +90,7 @@ static void cl_recv_cb(uv_udp_t* handle,
static void cl_send_cb(uv_udp_send_t* req, int status) {
int r;
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
CHECK_HANDLE(req->handle);
@ -102,7 +102,7 @@ static void cl_send_cb(uv_udp_send_t* req, int status) {
static void sv_send_cb(uv_udp_send_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
CHECK_HANDLE(req->handle);
@ -128,14 +128,14 @@ static void sv_recv_cb(uv_udp_t* handle,
if (nread == 0) {
/* Returning unused buffer. Don't count towards sv_recv_cb_called */
ASSERT(addr == NULL);
ASSERT_NULL(addr);
return;
}
CHECK_HANDLE(handle);
ASSERT(flags == 0);
ASSERT(addr != NULL);
ASSERT_NOT_NULL(addr);
ASSERT(nread == 4);
ASSERT(!memcmp("PING", rcvbuf->base, nread));
@ -147,7 +147,7 @@ static void sv_recv_cb(uv_udp_t* handle,
ASSERT(r == 0);
req = malloc(sizeof *req);
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
sndbuf = uv_buf_init("PONG", 4);
r = uv_udp_send(req, handle, &sndbuf, 1, addr, sv_send_cb);

View File

@ -44,7 +44,7 @@ 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);
ASSERT_NULL(send_req.handle);
CHECK_OBJECT(handle, uv_idle_t, idle_handle);
ASSERT(0 == uv_idle_stop(handle));
@ -66,7 +66,7 @@ static void idle_cb(uv_idle_t* handle) {
static void send_cb(uv_udp_send_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0 || status == UV_ENETUNREACH);
CHECK_OBJECT(req->handle, uv_udp_t, client);
CHECK_OBJECT(req, uv_udp_send_t, send_req);

View File

@ -56,7 +56,7 @@ static void close_cb(uv_handle_t* handle) {
static void cl_send_cb(uv_udp_send_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
CHECK_HANDLE(req->handle);
@ -75,14 +75,14 @@ static void sv_recv_cb(uv_udp_t* handle,
if (nread == 0) {
/* Returning unused buffer. Don't count towards sv_recv_cb_called */
ASSERT(addr == NULL);
ASSERT_NULL(addr);
return;
}
CHECK_HANDLE(handle);
ASSERT(flags == 0);
ASSERT(addr != NULL);
ASSERT_NOT_NULL(addr);
ASSERT(nread == 4);
ASSERT(memcmp("PING", rcvbuf->base, nread) == 0 ||
memcmp("PANG", rcvbuf->base, nread) == 0);

View File

@ -27,9 +27,10 @@
#include <string.h>
#define CHECK_HANDLE(handle) \
ASSERT((uv_udp_t*)(handle) == &client)
ASSERT((uv_udp_t*)(handle) == &client || (uv_udp_t*)(handle) == &client2)
static uv_udp_t client;
static uv_udp_t client2;
static uv_timer_t timer;
static int send_cb_called;
@ -37,6 +38,7 @@ static int recv_cb_called;
static int close_cb_called;
static int alloc_cb_called;
static int timer_cb_called;
static int can_recverr;
static void alloc_cb(uv_handle_t* handle,
@ -44,7 +46,7 @@ static void alloc_cb(uv_handle_t* handle,
uv_buf_t* buf) {
static char slab[65536];
CHECK_HANDLE(handle);
ASSERT(suggested_size <= sizeof(slab));
ASSERT_LE(suggested_size, sizeof(slab));
buf->base = slab;
buf->len = sizeof(slab);
alloc_cb_called++;
@ -52,18 +54,25 @@ static void alloc_cb(uv_handle_t* handle,
static void close_cb(uv_handle_t* handle) {
ASSERT(1 == uv_is_closing(handle));
ASSERT_EQ(1, uv_is_closing(handle));
close_cb_called++;
}
static void send_cb(uv_udp_send_t* req, int status) {
ASSERT(req != NULL);
ASSERT_NOT_NULL(req);
ASSERT(status == 0);
ASSERT_EQ(status, 0);
CHECK_HANDLE(req->handle);
send_cb_called++;
}
static void send_cb_recverr(uv_udp_send_t* req, int status) {
ASSERT_PTR_NE(req, NULL);
ASSERT(status == 0 || status == UV_ECONNREFUSED);
CHECK_HANDLE(req->handle);
send_cb_called++;
}
static void recv_cb(uv_udp_t* handle,
ssize_t nread,
@ -77,17 +86,19 @@ static void recv_cb(uv_udp_t* handle,
ASSERT(0 && "unexpected error");
} else if (nread == 0) {
/* Returning unused buffer */
ASSERT(addr == NULL);
ASSERT_NULL(addr);
} else {
ASSERT(addr != NULL);
ASSERT_NOT_NULL(addr);
}
}
static void timer_cb(uv_timer_t* h) {
ASSERT(h == &timer);
ASSERT_PTR_EQ(h, &timer);
timer_cb_called++;
uv_close((uv_handle_t*) &client, close_cb);
if (can_recverr)
uv_close((uv_handle_t*) &client2, close_cb);
uv_close((uv_handle_t*) h, close_cb);
}
@ -95,27 +106,33 @@ static void timer_cb(uv_timer_t* h) {
TEST_IMPL(udp_send_unreachable) {
struct sockaddr_in addr;
struct sockaddr_in addr2;
uv_udp_send_t req1, req2;
struct sockaddr_in addr3;
uv_udp_send_t req1, req2, req3, req4;
uv_buf_t buf;
int r;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT_2, &addr2));
#ifdef __linux__
can_recverr = 1;
#endif
ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT_2, &addr2));
ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT_3, &addr3));
r = uv_timer_init( uv_default_loop(), &timer );
ASSERT(r == 0);
ASSERT_EQ(r, 0);
r = uv_timer_start( &timer, timer_cb, 1000, 0 );
ASSERT(r == 0);
ASSERT_EQ(r, 0);
r = uv_udp_init(uv_default_loop(), &client);
ASSERT(r == 0);
ASSERT_EQ(r, 0);
r = uv_udp_bind(&client, (const struct sockaddr*) &addr2, 0);
ASSERT(r == 0);
ASSERT_EQ(r, 0);
r = uv_udp_recv_start(&client, alloc_cb, recv_cb);
ASSERT(r == 0);
ASSERT_EQ(r, 0);
/* client sends "PING", then "PANG" */
buf = uv_buf_init("PING", 4);
@ -126,7 +143,7 @@ TEST_IMPL(udp_send_unreachable) {
1,
(const struct sockaddr*) &addr,
send_cb);
ASSERT(r == 0);
ASSERT_EQ(r, 0);
buf = uv_buf_init("PANG", 4);
@ -136,14 +153,48 @@ TEST_IMPL(udp_send_unreachable) {
1,
(const struct sockaddr*) &addr,
send_cb);
ASSERT(r == 0);
ASSERT_EQ(r, 0);
if (can_recverr) {
r = uv_udp_init(uv_default_loop(), &client2);
ASSERT_EQ(r, 0);
r = uv_udp_bind(&client2,
(const struct sockaddr*) &addr3,
UV_UDP_LINUX_RECVERR);
ASSERT_EQ(r, 0);
r = uv_udp_recv_start(&client2, alloc_cb, recv_cb);
ASSERT_EQ(r, 0);
/* client sends "PING", then "PANG" */
buf = uv_buf_init("PING", 4);
r = uv_udp_send(&req3,
&client2,
&buf,
1,
(const struct sockaddr*) &addr,
send_cb_recverr);
ASSERT_EQ(r, 0);
buf = uv_buf_init("PANG", 4);
r = uv_udp_send(&req4,
&client2,
&buf,
1,
(const struct sockaddr*) &addr,
send_cb_recverr);
ASSERT_EQ(r, 0);
}
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(send_cb_called == 2);
ASSERT(recv_cb_called == alloc_cb_called);
ASSERT(timer_cb_called == 1);
ASSERT(close_cb_called == 2);
ASSERT_EQ(send_cb_called, (long)(can_recverr ? 4 : 2));
ASSERT_EQ(recv_cb_called, alloc_cb_called);
ASSERT_EQ(timer_cb_called, 1);
ASSERT_EQ(close_cb_called, (long)(can_recverr ? 3 : 2));
MAKE_VALGRIND_HAPPY();
return 0;

View File

@ -63,12 +63,12 @@ static void sv_recv_cb(uv_udp_t* handle,
ASSERT(nread > 0);
if (nread == 0) {
ASSERT(addr == NULL);
ASSERT_NULL(addr);
return;
}
ASSERT(nread == 4);
ASSERT(addr != NULL);
ASSERT_NOT_NULL(addr);
ASSERT(memcmp("EXIT", rcvbuf->base, nread) == 0);
uv_close((uv_handle_t*) handle, close_cb);