| From: Wen Yang <wen.yang@linux.dev> |
| Subject: selftests: introduce additional eventfd test coverage |
| Date: Mon, 27 May 2024 08:02:00 +0800 |
| |
| Add several new test cases which assert corner cases on the eventfd |
| mechanism, for example, the supplied buffer is less than 8 bytes, |
| attempting to write a value that is too large, etc. |
| |
| ./eventfd_test |
| # Starting 9 tests from 1 test cases. |
| # RUN global.eventfd_check_flag_rdwr ... |
| # OK global.eventfd_check_flag_rdwr |
| ok 1 global.eventfd_check_flag_rdwr |
| # RUN global.eventfd_check_flag_cloexec ... |
| # OK global.eventfd_check_flag_cloexec |
| ok 2 global.eventfd_check_flag_cloexec |
| # RUN global.eventfd_check_flag_nonblock ... |
| # OK global.eventfd_check_flag_nonblock |
| ok 3 global.eventfd_check_flag_nonblock |
| # RUN global.eventfd_chek_flag_cloexec_and_nonblock ... |
| # OK global.eventfd_chek_flag_cloexec_and_nonblock |
| ok 4 global.eventfd_chek_flag_cloexec_and_nonblock |
| # RUN global.eventfd_check_flag_semaphore ... |
| # OK global.eventfd_check_flag_semaphore |
| ok 5 global.eventfd_check_flag_semaphore |
| # RUN global.eventfd_check_write ... |
| # OK global.eventfd_check_write |
| ok 6 global.eventfd_check_write |
| # RUN global.eventfd_check_read ... |
| # OK global.eventfd_check_read |
| ok 7 global.eventfd_check_read |
| # RUN global.eventfd_check_read_with_nonsemaphore ... |
| # OK global.eventfd_check_read_with_nonsemaphore |
| ok 8 global.eventfd_check_read_with_nonsemaphore |
| # RUN global.eventfd_check_read_with_semaphore ... |
| # OK global.eventfd_check_read_with_semaphore |
| ok 9 global.eventfd_check_read_with_semaphore |
| # PASSED: 9 / 9 tests passed. |
| # Totals: pass:9 fail:0 xfail:0 xpass:0 skip:0 error:0 |
| |
| Link: https://lkml.kernel.org/r/20240527000200.5615-1-wen.yang@linux.dev |
| Signed-off-by: Wen Yang <wen.yang@linux.dev> |
| Cc: Shuah Khan <shuah@kernel.org> |
| Cc: Christian Brauner <brauner@kernel.org> |
| Cc: Andrei Vagin <avagin@google.com> |
| Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
| Cc: Steven Rostedt <rostedt@goodmis.org> |
| Cc: Dave Young <dyoung@redhat.com> |
| Cc: Tim Bird <tim.bird@sony.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| tools/testing/selftests/filesystems/eventfd/eventfd_test.c | 136 +++++++++- |
| 1 file changed, 131 insertions(+), 5 deletions(-) |
| |
| --- a/tools/testing/selftests/filesystems/eventfd/eventfd_test.c~selftests-introduce-additional-eventfd-test-coverage |
| +++ a/tools/testing/selftests/filesystems/eventfd/eventfd_test.c |
| @@ -13,6 +13,8 @@ |
| #include <sys/eventfd.h> |
| #include "../../kselftest_harness.h" |
| |
| +#define EVENTFD_TEST_ITERATIONS 100000UL |
| + |
| struct error { |
| int code; |
| char msg[512]; |
| @@ -40,7 +42,7 @@ static inline int sys_eventfd2(unsigned |
| return syscall(__NR_eventfd2, count, flags); |
| } |
| |
| -TEST(eventfd01) |
| +TEST(eventfd_check_flag_rdwr) |
| { |
| int fd, flags; |
| |
| @@ -54,7 +56,7 @@ TEST(eventfd01) |
| close(fd); |
| } |
| |
| -TEST(eventfd02) |
| +TEST(eventfd_check_flag_cloexec) |
| { |
| int fd, flags; |
| |
| @@ -68,7 +70,7 @@ TEST(eventfd02) |
| close(fd); |
| } |
| |
| -TEST(eventfd03) |
| +TEST(eventfd_check_flag_nonblock) |
| { |
| int fd, flags; |
| |
| @@ -83,7 +85,7 @@ TEST(eventfd03) |
| close(fd); |
| } |
| |
| -TEST(eventfd04) |
| +TEST(eventfd_chek_flag_cloexec_and_nonblock) |
| { |
| int fd, flags; |
| |
| @@ -161,7 +163,7 @@ static int verify_fdinfo(int fd, struct |
| return 0; |
| } |
| |
| -TEST(eventfd05) |
| +TEST(eventfd_check_flag_semaphore) |
| { |
| struct error err = {0}; |
| int fd, ret; |
| @@ -182,5 +184,129 @@ TEST(eventfd05) |
| |
| close(fd); |
| } |
| + |
| +/* |
| + * A write(2) fails with the error EINVAL if the size of the supplied buffer |
| + * is less than 8 bytes, or if an attempt is made to write the value |
| + * 0xffffffffffffffff. |
| + */ |
| +TEST(eventfd_check_write) |
| +{ |
| + uint64_t value = 1; |
| + ssize_t size; |
| + int fd; |
| + |
| + fd = sys_eventfd2(0, 0); |
| + ASSERT_GE(fd, 0); |
| + |
| + size = write(fd, &value, sizeof(int)); |
| + EXPECT_EQ(size, -1); |
| + EXPECT_EQ(errno, EINVAL); |
| + |
| + size = write(fd, &value, sizeof(value)); |
| + EXPECT_EQ(size, sizeof(value)); |
| + |
| + value = (uint64_t)-1; |
| + size = write(fd, &value, sizeof(value)); |
| + EXPECT_EQ(size, -1); |
| + EXPECT_EQ(errno, EINVAL); |
| + |
| + close(fd); |
| +} |
| + |
| +/* |
| + * A read(2) fails with the error EINVAL if the size of the supplied buffer is |
| + * less than 8 bytes. |
| + */ |
| +TEST(eventfd_check_read) |
| +{ |
| + uint64_t value; |
| + ssize_t size; |
| + int fd; |
| + |
| + fd = sys_eventfd2(1, 0); |
| + ASSERT_GE(fd, 0); |
| + |
| + size = read(fd, &value, sizeof(int)); |
| + EXPECT_EQ(size, -1); |
| + EXPECT_EQ(errno, EINVAL); |
| + |
| + size = read(fd, &value, sizeof(value)); |
| + EXPECT_EQ(size, sizeof(value)); |
| + EXPECT_EQ(value, 1); |
| + |
| + close(fd); |
| +} |
| + |
| + |
| +/* |
| + * If EFD_SEMAPHORE was not specified and the eventfd counter has a nonzero |
| + * value, then a read(2) returns 8 bytes containing that value, and the |
| + * counter's value is reset to zero. |
| + * If the eventfd counter is zero at the time of the call to read(2), then the |
| + * call fails with the error EAGAIN if the file descriptor has been made nonblocking. |
| + */ |
| +TEST(eventfd_check_read_with_nonsemaphore) |
| +{ |
| + uint64_t value; |
| + ssize_t size; |
| + int fd; |
| + int i; |
| + |
| + fd = sys_eventfd2(0, EFD_NONBLOCK); |
| + ASSERT_GE(fd, 0); |
| + |
| + value = 1; |
| + for (i = 0; i < EVENTFD_TEST_ITERATIONS; i++) { |
| + size = write(fd, &value, sizeof(value)); |
| + EXPECT_EQ(size, sizeof(value)); |
| + } |
| + |
| + size = read(fd, &value, sizeof(value)); |
| + EXPECT_EQ(size, sizeof(uint64_t)); |
| + EXPECT_EQ(value, EVENTFD_TEST_ITERATIONS); |
| + |
| + size = read(fd, &value, sizeof(value)); |
| + EXPECT_EQ(size, -1); |
| + EXPECT_EQ(errno, EAGAIN); |
| + |
| + close(fd); |
| +} |
| + |
| +/* |
| + * If EFD_SEMAPHORE was specified and the eventfd counter has a nonzero value, |
| + * then a read(2) returns 8 bytes containing the value 1, and the counter's |
| + * value is decremented by 1. |
| + * If the eventfd counter is zero at the time of the call to read(2), then the |
| + * call fails with the error EAGAIN if the file descriptor has been made nonblocking. |
| + */ |
| +TEST(eventfd_check_read_with_semaphore) |
| +{ |
| + uint64_t value; |
| + ssize_t size; |
| + int fd; |
| + int i; |
| + |
| + fd = sys_eventfd2(0, EFD_SEMAPHORE|EFD_NONBLOCK); |
| + ASSERT_GE(fd, 0); |
| + |
| + value = 1; |
| + for (i = 0; i < EVENTFD_TEST_ITERATIONS; i++) { |
| + size = write(fd, &value, sizeof(value)); |
| + EXPECT_EQ(size, sizeof(value)); |
| + } |
| + |
| + for (i = 0; i < EVENTFD_TEST_ITERATIONS; i++) { |
| + size = read(fd, &value, sizeof(value)); |
| + EXPECT_EQ(size, sizeof(value)); |
| + EXPECT_EQ(value, 1); |
| + } |
| + |
| + size = read(fd, &value, sizeof(value)); |
| + EXPECT_EQ(size, -1); |
| + EXPECT_EQ(errno, EAGAIN); |
| + |
| + close(fd); |
| +} |
| |
| TEST_HARNESS_MAIN |
| _ |