On 17.03.2022 11:07, Stefano Garzarella wrote: > On Thu, Mar 17, 2022 at 05:26: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: Krasnov Arseniy Vladimirovich <AVKrasnov@xxxxxxxxxxxxxx> >> --- >> v2 -> v3: >> 1) Use 'fprintf()' instead of 'perror()' where 'errno' variable >> is not affected. >> 2) Print 'read()' overhead. >> >> tools/testing/vsock/vsock_test.c | 84 ++++++++++++++++++++++++++++++++ >> 1 file changed, 84 insertions(+) >> >> diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c >> index 2a3638c0a008..f5498de6751d 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,84 @@ 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 (errno != EAGAIN) { >> + perror("EAGAIN expected"); >> + exit(EXIT_FAILURE); >> + } > > Should this check go after read()? > > Indeed now the test fails on my environment with "EAGAIN expected" message. > > The rest LGTM :-) Oops, sorry :) > > Stefano > >> + >> + if (read(fd, &dummy, sizeof(dummy)) != -1) { >> + fprintf(stderr, >> + "expected 'dummy' read(2) failure\n"); >> + 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), %lu > %i ns\n", >> + read_overhead_ns, READ_OVERHEAD_NSEC); >> + 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 +510,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 >