From 75c00c256743c50713ad25de72f15af1b59f55d6 Mon Sep 17 00:00:00 2001 From: Arshia Ghafoori Date: Thu, 27 Feb 2025 13:04:27 +0000 Subject: [PATCH] Add tests for select, recv and send over socket pairs --- tests/wasix/socket_pair/main.c | 162 ++++++++++++++++++++++++--------- tests/wasix/socket_pair/run.sh | 4 +- 2 files changed, 120 insertions(+), 46 deletions(-) diff --git a/tests/wasix/socket_pair/main.c b/tests/wasix/socket_pair/main.c index 6275c9d43..fae74ed3e 100644 --- a/tests/wasix/socket_pair/main.c +++ b/tests/wasix/socket_pair/main.c @@ -1,65 +1,141 @@ +// Note: we need this test because we're hacking around +// socket pairs and using a duplex pipe underneath, which +// creates huge potential for edge cases and errors. + #include #include #include #include #include #include +#include + +int test_communication(int from, int to) +{ + int result; + char buf[32]; + ssize_t numRead; + fd_set fdset; + struct timeval timeout = { + .tv_sec = 0, + .tv_usec = 0, + }; + + // Test 1: do it through select, with read and write + FD_ZERO(&fdset); + FD_SET(to, &fdset); + result = select(to + 1, NULL, &fdset, NULL, &timeout); + if (result < 0) + { + perror("select"); + return -1; + } + else if (result == 0) + { + printf("Timeout: nothing can be written.\n"); + return -1; + } + else + { + if (FD_ISSET(to, &fdset)) + { + int bytes_written = write(to, "foo", 3); + if (bytes_written < 0) + { + perror("write"); + return -1; + } + } + else + { + printf("Expected send socket to be ready to write to\n"); + return -1; + } + } + + FD_ZERO(&fdset); + FD_SET(from, &fdset); + result = select(from + 1, &fdset, NULL, NULL, &timeout); + if (result < 0) + { + perror("select"); + return -1; + } + else if (result == 0) + { + printf("Timeout: No data available to read.\n"); + return -1; + } + else + { + if (FD_ISSET(from, &fdset)) + { + int bytes_read = read(from, buf, sizeof(buf)); + if (bytes_read < 0) + { + perror("read"); + return -1; + } + buf[bytes_read] = 0; + if (strncmp(buf, "foo", 3) != 0) + { + printf("expected 'foo', received: %s\n", buf); + return -1; + } + } + else + { + printf("Expected recv socket to be ready to read from\n"); + return -1; + } + } + + // test 2: do it through send and recv + + int bytes_sent = send(to, "bar", 3, 0); + if (bytes_sent < 0) + { + perror("send"); + return -1; + } + + int bytes_received = recv(from, buf, sizeof(buf), 0); + if (bytes_received < 0) + { + perror("recv"); + return -1; + } + buf[bytes_received] = 0; + + if (strncmp(buf, "bar", 3) != 0) + { + printf("expected 'bar', received: %s\n", buf); + return -1; + } + + return 0; +} int main() { - int status = EXIT_FAILURE; - int socks[2]; - char buf[1024]; - ssize_t numRead; if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) == -1) { perror("socketpair"); - goto end; + return -1; } - if (write(socks[0], "foo", 3) == -1) + if (test_communication(socks[0], socks[1]) == -1) { - perror("write"); - goto end; + return -1; } - memset(buf, 0, sizeof(buf)); - numRead = read(socks[1], buf, sizeof(buf)); - if (numRead == -1) + // try it in reverse as well, since the connection should be duplex + if (test_communication(socks[1], socks[0]) == -1) { - perror("read"); - goto end; - } - if (strncmp(buf, "foo", 3) != 0) - { - printf("buf: %s\n", buf); - goto end; + return -1; } - if (write(socks[1], "bar", 3) == -1) - { - perror("write 2"); - goto end; - } - - memset(buf, 0, sizeof(buf)); - numRead = read(socks[0], buf, sizeof(buf)); - if (numRead == -1) - { - perror("read 2"); - goto end; - } - if (strncmp(buf, "bar", 3) != 0) - { - printf("buf 2: %s\n", buf); - goto end; - } - - status = EXIT_SUCCESS; - -end: - printf("%d", status); - return status; -} + return 0; +} \ No newline at end of file diff --git a/tests/wasix/socket_pair/run.sh b/tests/wasix/socket_pair/run.sh index 3e033fb89..0aa1f606b 100755 --- a/tests/wasix/socket_pair/run.sh +++ b/tests/wasix/socket_pair/run.sh @@ -1,3 +1 @@ -$WASMER -q run main.wasm > output - -printf "0" | diff -u output - 1>/dev/null \ No newline at end of file +$WASMER -q run main.wasm \ No newline at end of file