On Wed, Mar 16, 2022 at 07:27:45AM +0000, Krasnov Arseniy Vladimirovich wrote:
Test for receive timeout check: connection is established,
receiver sets timeout, but sender does nothing. Receiver's
'read()' call must return EAGAIN.

Signed-off-by: Arseniy Krasnov <avkras...@sberdevices.ru>
---
v1 -> v2:
1) Check amount of time spent in 'read()'.

The patch looks correct to me, but since it's an RFC and you have to send another version anyway, here are some minor suggestions :-)


tools/testing/vsock/vsock_test.c | 79 ++++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)

diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
index 2a3638c0a008..6d7648cce5aa 100644
--- a/tools/testing/vsock/vsock_test.c
+++ b/tools/testing/vsock/vsock_test.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <time.h>

#include "timeout.h"
#include "control.h"
@@ -391,6 +392,79 @@ static void test_seqpacket_msg_trunc_server(const struct 
test_opts *opts)
        close(fd);
}

+static time_t current_nsec(void)
+{
+       struct timespec ts;
+
+       if (clock_gettime(CLOCK_REALTIME, &ts)) {
+               perror("clock_gettime(3) failed");
+               exit(EXIT_FAILURE);
+       }
+
+       return (ts.tv_sec * 1000000000ULL) + ts.tv_nsec;
+}
+
+#define RCVTIMEO_TIMEOUT_SEC 1
+#define READ_OVERHEAD_NSEC 250000000 /* 0.25 sec */
+
+static void test_seqpacket_timeout_client(const struct test_opts *opts)
+{
+       int fd;
+       struct timeval tv;
+       char dummy;
+       time_t read_enter_ns;
+       time_t read_overhead_ns;
+
+       fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
+       if (fd < 0) {
+               perror("connect");
+               exit(EXIT_FAILURE);
+       }
+
+       tv.tv_sec = RCVTIMEO_TIMEOUT_SEC;
+       tv.tv_usec = 0;
+
+       if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv)) == 
-1) {
+               perror("setsockopt 'SO_RCVTIMEO'");
+               exit(EXIT_FAILURE);
+       }
+
+       read_enter_ns = current_nsec();
+
+       if ((read(fd, &dummy, sizeof(dummy)) != -1) ||
+           (errno != EAGAIN)) {

Here we can split in 2 checks like in patch 2, since if read() return value is >= 0, errno is not set.

+               perror("EAGAIN expected");
+               exit(EXIT_FAILURE);
+       }
+
+       read_overhead_ns = current_nsec() - read_enter_ns -
+                       1000000000ULL * RCVTIMEO_TIMEOUT_SEC;
+
+       if (read_overhead_ns > READ_OVERHEAD_NSEC) {
+               fprintf(stderr,
+                       "too much time in read(2) with SO_RCVTIMEO: %lu ns\n",
+                       read_overhead_ns);

What about printing also the expected overhead?

+               exit(EXIT_FAILURE);
+       }
+
+       control_writeln("WAITDONE");
+       close(fd);
+}
+
+static void test_seqpacket_timeout_server(const struct test_opts *opts)
+{
+       int fd;
+
+       fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
+       if (fd < 0) {
+               perror("accept");
+               exit(EXIT_FAILURE);
+       }
+
+       control_expectln("WAITDONE");
+       close(fd);
+}
+
static struct test_case test_cases[] = {
        {
                .name = "SOCK_STREAM connection reset",
@@ -431,6 +505,11 @@ static struct test_case test_cases[] = {
                .run_client = test_seqpacket_msg_trunc_client,
                .run_server = test_seqpacket_msg_trunc_server,
        },
+       {
+               .name = "SOCK_SEQPACKET timeout",
+               .run_client = test_seqpacket_timeout_client,
+               .run_server = test_seqpacket_timeout_server,
+       },
        {},
};

--
2.25.1

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Reply via email to