#include "uv.h"
#include "task.h"
#include <stdio.h>
#include <stdlib.h>
static
int
close_cb_called = 0;
static
void
close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
close_cb_called++;
}
TEST_IMPL(tcp_bind_error_addrinuse) {
struct
sockaddr_in addr;
uv_tcp_t server1, server2;
int
r;
ASSERT(0 == uv_ip4_addr(
"0.0.0.0"
, TEST_PORT, &addr));
r = uv_tcp_init(uv_default_loop(), &server1);
ASSERT(r == 0);
r = uv_tcp_bind(&server1, (
const
struct
sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_tcp_init(uv_default_loop(), &server2);
ASSERT(r == 0);
r = uv_tcp_bind(&server2, (
const
struct
sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&server1, 128, NULL);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&server2, 128, NULL);
ASSERT(r == UV_EADDRINUSE);
uv_close((uv_handle_t*)&server1, close_cb);
uv_close((uv_handle_t*)&server2, close_cb);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 2);
MAKE_VALGRIND_HAPPY();
return
0;
}
TEST_IMPL(tcp_bind_error_addrnotavail_1) {
struct
sockaddr_in addr;
uv_tcp_t server;
int
r;
ASSERT(0 == uv_ip4_addr(
"127.255.255.255"
, TEST_PORT, &addr));
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind(&server, (
const
struct
sockaddr*) &addr, 0);
ASSERT(r == 0 || r == UV_EADDRNOTAVAIL);
uv_close((uv_handle_t*)&server, close_cb);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
MAKE_VALGRIND_HAPPY();
return
0;
}
TEST_IMPL(tcp_bind_error_addrnotavail_2) {
struct
sockaddr_in addr;
uv_tcp_t server;
int
r;
ASSERT(0 == uv_ip4_addr(
"4.4.4.4"
, TEST_PORT, &addr));
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind(&server, (
const
struct
sockaddr*) &addr, 0);
ASSERT(r == UV_EADDRNOTAVAIL);
uv_close((uv_handle_t*)&server, close_cb);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
MAKE_VALGRIND_HAPPY();
return
0;
}
TEST_IMPL(tcp_bind_error_fault) {
char
garbage[] =
"blah blah blah blah blah blah blah blah blah blah blah blah"
;
struct
sockaddr_in* garbage_addr;
uv_tcp_t server;
int
r;
garbage_addr = (
struct
sockaddr_in*) &garbage;
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind(&server, (
const
struct
sockaddr*) garbage_addr, 0);
ASSERT(r == UV_EINVAL);
uv_close((uv_handle_t*)&server, close_cb);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
MAKE_VALGRIND_HAPPY();
return
0;
}
TEST_IMPL(tcp_bind_error_inval) {
struct
sockaddr_in addr1;
struct
sockaddr_in addr2;
uv_tcp_t server;
int
r;
ASSERT(0 == uv_ip4_addr(
"0.0.0.0"
, TEST_PORT, &addr1));
ASSERT(0 == uv_ip4_addr(
"0.0.0.0"
, TEST_PORT_2, &addr2));
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind(&server, (
const
struct
sockaddr*) &addr1, 0);
ASSERT(r == 0);
r = uv_tcp_bind(&server, (
const
struct
sockaddr*) &addr2, 0);
ASSERT(r == UV_EINVAL);
uv_close((uv_handle_t*)&server, close_cb);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
MAKE_VALGRIND_HAPPY();
return
0;
}
TEST_IMPL(tcp_bind_localhost_ok) {
struct
sockaddr_in addr;
uv_tcp_t server;
int
r;
ASSERT(0 == uv_ip4_addr(
"127.0.0.1"
, TEST_PORT, &addr));
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind(&server, (
const
struct
sockaddr*) &addr, 0);
ASSERT(r == 0);
MAKE_VALGRIND_HAPPY();
return
0;
}
TEST_IMPL(tcp_bind_invalid_flags) {
struct
sockaddr_in addr;
uv_tcp_t server;
int
r;
ASSERT(0 == uv_ip4_addr(
"127.0.0.1"
, TEST_PORT, &addr));
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind(&server, (
const
struct
sockaddr*) &addr, UV_TCP_IPV6ONLY);
ASSERT(r == UV_EINVAL);
MAKE_VALGRIND_HAPPY();
return
0;
}
TEST_IMPL(tcp_listen_without_bind) {
int
r;
uv_tcp_t server;
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&server, 128, NULL);
ASSERT(r == 0);
MAKE_VALGRIND_HAPPY();
return
0;
}
TEST_IMPL(tcp_bind_writable_flags) {
struct
sockaddr_in addr;
uv_tcp_t server;
uv_buf_t buf;
uv_write_t write_req;
uv_shutdown_t shutdown_req;
int
r;
ASSERT(0 == uv_ip4_addr(
"0.0.0.0"
, TEST_PORT, &addr));
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind(&server, (
const
struct
sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&server, 128, NULL);
ASSERT(r == 0);
ASSERT(0 == uv_is_writable((uv_stream_t*) &server));
ASSERT(0 == uv_is_readable((uv_stream_t*) &server));
buf = uv_buf_init(
"PING"
, 4);
r = uv_write(&write_req, (uv_stream_t*) &server, &buf, 1, NULL);
ASSERT(r == UV_EPIPE);
r = uv_shutdown(&shutdown_req, (uv_stream_t*) &server, NULL);
#ifdef _WIN32
ASSERT(r == UV_EPIPE);
#else
ASSERT(r == UV_ENOTCONN);
#endif
r = uv_read_start((uv_stream_t*) &server, NULL, NULL);
ASSERT(r == UV_ENOTCONN);
uv_close((uv_handle_t*)&server, close_cb);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
MAKE_VALGRIND_HAPPY();
return
0;
}