diff options
Diffstat (limited to 'tools/testing/vsock/vsock_test.c')
-rw-r--r-- | tools/testing/vsock/vsock_test.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c index 3de10dbb50f5..12b97c92fbb2 100644 --- a/tools/testing/vsock/vsock_test.c +++ b/tools/testing/vsock/vsock_test.c @@ -968,6 +968,91 @@ static void test_seqpacket_inv_buf_server(const struct test_opts *opts) test_inv_buf_server(opts, false); } +#define HELLO_STR "HELLO" +#define WORLD_STR "WORLD" + +static void test_stream_virtio_skb_merge_client(const struct test_opts *opts) +{ + ssize_t res; + int fd; + + fd = vsock_stream_connect(opts->peer_cid, 1234); + if (fd < 0) { + perror("connect"); + exit(EXIT_FAILURE); + } + + /* Send first skbuff. */ + res = send(fd, HELLO_STR, strlen(HELLO_STR), 0); + if (res != strlen(HELLO_STR)) { + fprintf(stderr, "unexpected send(2) result %zi\n", res); + exit(EXIT_FAILURE); + } + + control_writeln("SEND0"); + /* Peer reads part of first skbuff. */ + control_expectln("REPLY0"); + + /* Send second skbuff, it will be appended to the first. */ + res = send(fd, WORLD_STR, strlen(WORLD_STR), 0); + if (res != strlen(WORLD_STR)) { + fprintf(stderr, "unexpected send(2) result %zi\n", res); + exit(EXIT_FAILURE); + } + + control_writeln("SEND1"); + /* Peer reads merged skbuff packet. */ + control_expectln("REPLY1"); + + close(fd); +} + +static void test_stream_virtio_skb_merge_server(const struct test_opts *opts) +{ + unsigned char buf[64]; + ssize_t res; + int fd; + + fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL); + if (fd < 0) { + perror("accept"); + exit(EXIT_FAILURE); + } + + control_expectln("SEND0"); + + /* Read skbuff partially. */ + res = recv(fd, buf, 2, 0); + if (res != 2) { + fprintf(stderr, "expected recv(2) returns 2 bytes, got %zi\n", res); + exit(EXIT_FAILURE); + } + + control_writeln("REPLY0"); + control_expectln("SEND1"); + + res = recv(fd, buf + 2, sizeof(buf) - 2, 0); + if (res != 8) { + fprintf(stderr, "expected recv(2) returns 8 bytes, got %zi\n", res); + exit(EXIT_FAILURE); + } + + res = recv(fd, buf, sizeof(buf) - 8 - 2, MSG_DONTWAIT); + if (res != -1) { + fprintf(stderr, "expected recv(2) failure, got %zi\n", res); + exit(EXIT_FAILURE); + } + + if (memcmp(buf, HELLO_STR WORLD_STR, strlen(HELLO_STR WORLD_STR))) { + fprintf(stderr, "pattern mismatch\n"); + exit(EXIT_FAILURE); + } + + control_writeln("REPLY1"); + + close(fd); +} + static struct test_case test_cases[] = { { .name = "SOCK_STREAM connection reset", @@ -1038,6 +1123,11 @@ static struct test_case test_cases[] = { .run_client = test_seqpacket_inv_buf_client, .run_server = test_seqpacket_inv_buf_server, }, + { + .name = "SOCK_STREAM virtio skb merge", + .run_client = test_stream_virtio_skb_merge_client, + .run_server = test_stream_virtio_skb_merge_server, + }, {}, }; |