Skip to content

Commit 1e1c771

Browse files
authored
wasip2: Improve runtime of sockets-related tests (#653)
Don't unconditionally sleep for a second during tests to wait for a server to come online. Given that tests also are required to run serially this causes tests to take quite a long time to run. Instead bake into tests the ability to do a sort sleep but otherwise try to connect in a loop.
1 parent 93b429a commit 1e1c771

10 files changed

+126
-49
lines changed

test/socket-test.cmake

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
# stdout of each command is piped to the stdin of the next command. Tests print
33
# to stdout so that's not the behavior we want, so use `bash` to redirect stdout
44
# onto stderr.
5-
#
6-
# Also issue a `sleep 1` as a bit of a kludge to wait for the server to come
7-
# online at this time.
85

96
set(CLIENTS)
107

@@ -13,11 +10,11 @@ if (NOT NCLIENTS)
1310
endif()
1411

1512
foreach(i RANGE 1 ${NCLIENTS})
16-
list(APPEND CLIENTS COMMAND bash -c "sleep 1 && ${ENGINE} -Sinherit-network ${CLIENT} 1>&2")
13+
list(APPEND CLIENTS COMMAND bash -c "exec ${ENGINE} -Sinherit-network ${CLIENT} 1>&2")
1714
endforeach()
1815

1916
execute_process(
20-
COMMAND bash -c "${ENGINE} -Sinherit-network ${SERVER} 1>&2"
17+
COMMAND bash -c "exec ${ENGINE} -Sinherit-network ${SERVER} 1>&2"
2118
${CLIENTS}
2219
TIMEOUT 5
2320
COMMAND_ERROR_IS_FATAL ANY

test/src/sockets-client-handle-hangups.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,24 @@
1818

1919
int BUFSIZE = 256;
2020

21+
static int wait_for_server(struct sockaddr_in *addr) {
22+
for (int attempt = 0; attempt < 200; attempt++) {
23+
int fd = socket(AF_INET, SOCK_STREAM, 0);
24+
TEST(fd != -1);
25+
if (connect(fd, (struct sockaddr *)addr, sizeof(*addr)) != -1)
26+
return fd;
27+
close(fd);
28+
usleep(5000); // sleep for 5ms
29+
}
30+
return -1;
31+
}
32+
2133
// Server must be running already as a separate executable
2234
// (except when testing the case where connect() fails)
2335
void test_tcp_client() {
2436
// Prepare server socket
2537
int server_port = 4001;
2638

27-
// Prepare client socket
28-
// Use blocking sockets
29-
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
30-
TEST(socket_fd != -1);
31-
3239
// Prepare sockaddr_in for client
3340
struct sockaddr_in sockaddr_in;
3441
sockaddr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -40,11 +47,9 @@ void test_tcp_client() {
4047
int len = strlen(message);
4148
char client_buffer[BUFSIZE];
4249

43-
int connect_result = connect(socket_fd, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in));
44-
if (connect_result == -1) {
45-
close(socket_fd);
50+
int socket_fd = wait_for_server(&sockaddr_in);
51+
if (socket_fd == -1)
4652
return;
47-
}
4853

4954
// Client writes a message to server
5055
// This should succeed even in the presence of hangups,
@@ -53,8 +58,8 @@ void test_tcp_client() {
5358

5459
// Set timeout for recv
5560
struct timeval tv;
56-
tv.tv_sec = 3;
57-
tv.tv_usec = 0;
61+
tv.tv_sec = 0;
62+
tv.tv_usec = 500000; // 500 milliseconds
5863
setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv));
5964

6065
// Client reads from server

test/src/sockets-client-hangup-after-connect.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,33 @@
1818

1919
int BUFSIZE = 256;
2020

21+
static int wait_for_server(struct sockaddr_in *addr) {
22+
for (int attempt = 0; attempt < 200; attempt++) {
23+
int fd = socket(AF_INET, SOCK_STREAM, 0);
24+
TEST(fd != -1);
25+
if (connect(fd, (struct sockaddr *)addr, sizeof(*addr)) != -1)
26+
return fd;
27+
close(fd);
28+
usleep(5000); // sleep for 5ms
29+
}
30+
t_error("server didn't come online within 1 second (errno = %d)\n", errno); \
31+
return -1;
32+
}
33+
2134
// Server must be running already as a separate executable
2235
// (except when testing the case where connect() fails)
2336
void test_tcp_client() {
2437
// Prepare server socket
2538
int server_port = 4001;
2639

27-
// Prepare client socket
28-
// Use blocking sockets
29-
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
30-
TEST(socket_fd != -1);
31-
3240
// Prepare sockaddr_in for client
3341
struct sockaddr_in sockaddr_in;
3442
sockaddr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3543
sockaddr_in.sin_family = AF_INET;
3644
sockaddr_in.sin_port = htons(server_port);
3745

3846
// Connect from client
39-
int connect_result = connect(socket_fd, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in));
47+
int socket_fd = wait_for_server(&sockaddr_in);
4048

4149
// Hang up immediately
4250
close(socket_fd);

test/src/sockets-client-hangup-after-sending.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,24 @@
1818

1919
int BUFSIZE = 256;
2020

21+
static int wait_for_server(struct sockaddr_in *addr) {
22+
for (int attempt = 0; attempt < 200; attempt++) {
23+
int fd = socket(AF_INET, SOCK_STREAM, 0);
24+
TEST(fd != -1);
25+
if (connect(fd, (struct sockaddr *)addr, sizeof(*addr)) != -1)
26+
return fd;
27+
close(fd);
28+
usleep(5000); // sleep for 5ms
29+
}
30+
t_error("server didn't come online within 1 second (errno = %d)\n", errno); \
31+
return -1;
32+
}
33+
2134
// See sockets-server.c -- must be running already as a separate executable
2235
void test_tcp_client() {
2336
// Prepare server socket
2437
int server_port = 4001;
2538

26-
// Prepare client socket
27-
// Use blocking sockets
28-
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
29-
TEST(socket_fd != -1);
30-
3139
// Prepare sockaddr_in for client
3240
struct sockaddr_in sockaddr_in;
3341
sockaddr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -39,7 +47,7 @@ void test_tcp_client() {
3947
int len = strlen(message);
4048
char client_buffer[BUFSIZE];
4149

42-
TEST(connect(socket_fd, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in)) != -1);
50+
int socket_fd = wait_for_server(&sockaddr_in);
4351

4452
// Client writes a message to server
4553
TEST(send(socket_fd, message, len, 0) == len);

test/src/sockets-client-hangup-while-receiving.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,24 @@
1818

1919
int BUFSIZE = 256;
2020

21+
static int wait_for_server(struct sockaddr_in *addr) {
22+
for (int attempt = 0; attempt < 200; attempt++) {
23+
int fd = socket(AF_INET, SOCK_STREAM, 0);
24+
TEST(fd != -1);
25+
if (connect(fd, (struct sockaddr *)addr, sizeof(*addr)) != -1)
26+
return fd;
27+
close(fd);
28+
usleep(5000); // sleep for 5ms
29+
}
30+
t_error("server didn't come online within 1 second (errno = %d)\n", errno); \
31+
return -1;
32+
}
33+
2134
// See sockets-server.c -- must be running already as a separate executable
2235
void test_tcp_client() {
2336
// Prepare server socket
2437
int server_port = 4001;
2538

26-
// Prepare client socket
27-
// Use blocking sockets
28-
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
29-
TEST(socket_fd != -1);
30-
3139
// Prepare sockaddr_in for client
3240
struct sockaddr_in sockaddr_in;
3341
sockaddr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -39,7 +47,7 @@ void test_tcp_client() {
3947
int len = strlen(message);
4048
char client_buffer[BUFSIZE];
4149

42-
TEST(connect(socket_fd, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in)) != -1);
50+
int socket_fd = wait_for_server(&sockaddr_in);
4351

4452
// Client writes a message to server
4553
TEST(send(socket_fd, message, len, 0) == len);

test/src/sockets-client-hangup-while-sending.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,24 @@
1818

1919
int BUFSIZE = 256;
2020

21+
static int wait_for_server(struct sockaddr_in *addr) {
22+
for (int attempt = 0; attempt < 200; attempt++) {
23+
int fd = socket(AF_INET, SOCK_STREAM, 0);
24+
TEST(fd != -1);
25+
if (connect(fd, (struct sockaddr *)addr, sizeof(*addr)) != -1)
26+
return fd;
27+
close(fd);
28+
usleep(5000); // sleep for 5ms
29+
}
30+
t_error("server didn't come online within 1 second (errno = %d)\n", errno); \
31+
return -1;
32+
}
33+
2134
// See sockets-server.c -- must be running already as a separate executable
2235
void test_tcp_client() {
2336
// Prepare server socket
2437
int server_port = 4001;
2538

26-
// Prepare client socket
27-
// Use blocking sockets
28-
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
29-
TEST(socket_fd != -1);
30-
3139
// Prepare sockaddr_in for client
3240
struct sockaddr_in sockaddr_in;
3341
sockaddr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -39,7 +47,7 @@ void test_tcp_client() {
3947
int len = strlen(message);
4048
char client_buffer[BUFSIZE];
4149

42-
TEST(connect(socket_fd, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in)) != -1);
50+
int socket_fd = wait_for_server(&sockaddr_in);
4351

4452
// Set the timeout to 2 us so that it should time out while sending
4553
struct timeval tv = { .tv_sec = 0, .tv_usec = 2 };

test/src/sockets-client-udp-blocking.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@
1818

1919
int BUFSIZE = 256;
2020

21+
static int wait_for_server(struct sockaddr_in *addr) {
22+
for (int attempt = 0; attempt < 200; attempt++) {
23+
int fd = socket(AF_INET, SOCK_STREAM, 0);
24+
TEST(fd != -1);
25+
if (connect(fd, (struct sockaddr *)addr, sizeof(*addr)) != -1)
26+
return fd;
27+
close(fd);
28+
usleep(5000); // sleep for 5ms
29+
}
30+
t_error("server didn't come online within 1 second (errno = %d)\n", errno); \
31+
return -1;
32+
}
33+
2134
// See sockets-server-udp-blocking.c -- must be running already as a separate executable
2235
void test_udp_client() {
2336
// Prepare server socket
@@ -34,6 +47,10 @@ void test_udp_client() {
3447
sockaddr_in.sin_family = AF_INET;
3548
sockaddr_in.sin_port = htons(server_port);
3649

50+
// Synchronize the UDP port being bound by waiting for a TCP connection to
51+
// go through.
52+
close(wait_for_server(&sockaddr_in));
53+
3754
// Connect from client
3855
char message[] = "There's gonna be a party when the wolf comes home";
3956
int len = strlen(message);

test/src/sockets-client.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,26 @@
1818

1919
int BUFSIZE = 256;
2020

21+
static int wait_for_server(struct sockaddr_in *addr) {
22+
for (int attempt = 0; attempt < 200; attempt++) {
23+
int fd = socket(AF_INET, SOCK_STREAM, 0);
24+
TEST(fd != -1);
25+
if (connect(fd, (struct sockaddr *)addr, sizeof(*addr)) != -1)
26+
return fd;
27+
close(fd);
28+
usleep(5000); // sleep for 5ms
29+
}
30+
t_error("server didn't come online within 1 second (errno = %d)\n", errno); \
31+
return -1;
32+
}
33+
2134
// See sockets-server.c -- must be running already as a separate executable
2235
void test_tcp_client() {
2336
// Prepare server socket
2437
int server_port = 4001;
2538

2639
// Prepare client socket
2740
// Use blocking sockets
28-
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
29-
TEST(socket_fd != -1);
3041

3142
// Prepare sockaddr_in for client
3243
struct sockaddr_in sockaddr_in;
@@ -39,7 +50,7 @@ void test_tcp_client() {
3950
int len = strlen(message);
4051
char client_buffer[BUFSIZE];
4152

42-
TEST(connect(socket_fd, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in)) != -1);
53+
int socket_fd = wait_for_server(&sockaddr_in);
4354

4455
// Client writes a message to server
4556
TEST(send(socket_fd, message, len, 0) == len);

test/src/sockets-multiple-client.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,24 @@
1818

1919
int BUFSIZE = 256;
2020

21+
static int wait_for_server(struct sockaddr_in *addr) {
22+
for (int attempt = 0; attempt < 200; attempt++) {
23+
int fd = socket(AF_INET, SOCK_STREAM, 0);
24+
TEST(fd != -1);
25+
if (connect(fd, (struct sockaddr *)addr, sizeof(*addr)) != -1)
26+
return fd;
27+
close(fd);
28+
usleep(5000); // sleep for 5ms
29+
}
30+
t_error("server didn't come online within 1 second (errno = %d)\n", errno); \
31+
return -1;
32+
}
33+
2134
// See sockets-multiple-server.c -- must be running already as a separate executable
2235
void test_tcp_client() {
2336
// Prepare server socket
2437
int server_port = 4001;
2538

26-
// Prepare client socket
27-
// Use blocking sockets
28-
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
29-
TEST(socket_fd != -1);
30-
3139
// Prepare sockaddr_in for client
3240
struct sockaddr_in sockaddr_in;
3341
sockaddr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -44,7 +52,7 @@ void test_tcp_client() {
4452
int len = strlen(message);
4553
char client_buffer[BUFSIZE];
4654

47-
TEST(connect(socket_fd, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in)) != -1);
55+
int socket_fd = wait_for_server(&sockaddr_in);
4856

4957
// Client writes a message to server
5058
TEST(send(socket_fd, message, len, 0) == len);

test/src/sockets-server-udp-blocking.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ void run_udp_server() {
3636
struct sockaddr_in client_address;
3737
socklen_t address_len = sizeof(client_address);
3838

39+
// Bind a TCP socket as well which the client will connect to as a
40+
// synchronization mechanism to ensure the above UDP port is bound.
41+
int tcp_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
42+
TEST(bind(tcp_socket_fd, (struct sockaddr*)&server_address, sizeof(server_address)) != -1);
43+
TEST(listen(tcp_socket_fd, 1) != -1);
44+
3945
// Server waits for input and echoes message back to client
4046
// The server shuts down after the client closes the connection
4147
int bytes_read = 0;
@@ -50,6 +56,7 @@ void run_udp_server() {
5056
TEST(bytes_read > 0);
5157

5258
close(server_socket_fd);
59+
close(tcp_socket_fd);
5360
}
5461

5562
int main()

0 commit comments

Comments
 (0)