X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=tests%2Funit%2Ftest_utils_compat_poll.c;h=0cb7b23872908e2b0305db0144a26d75f9159464;hp=24a74d76f753018b6599161070b1c1d5725588e5;hb=c26ada1f972a9f76ec75daf036e31bf05e1bfa7f;hpb=41b42b3b7f1d94d5caff7e6ecf1a8b3f1f1441ae diff --git a/tests/unit/test_utils_compat_poll.c b/tests/unit/test_utils_compat_poll.c index 24a74d76f..0cb7b2387 100644 --- a/tests/unit/test_utils_compat_poll.c +++ b/tests/unit/test_utils_compat_poll.c @@ -5,14 +5,8 @@ * * Copyright (C) 2019 Yannick Lamarre * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by as - * published by the Free Software Foundation; only version 2 of the License. + * SPDX-License-Identifier: GPL-2.0-only * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. */ #include @@ -27,6 +21,8 @@ #include #include +#include +#include /* Verification without trashing test order in the child process */ #define childok(e, test, ...) do { \ @@ -49,9 +45,9 @@ int lttng_opt_mi; #define MAGIC_VALUE ((char) 0x5A) #ifdef HAVE_EPOLL -#define NUM_TESTS 46 +#define NUM_TESTS 48 #else -#define NUM_TESTS 45 +#define NUM_TESTS 47 #endif #ifdef HAVE_EPOLL @@ -61,6 +57,7 @@ int lttng_opt_mi; #define CLOE_VALUE FD_CLOEXEC #endif +static void test_epoll_compat(void) { /* @@ -71,7 +68,7 @@ void test_epoll_compat(void) } #endif -void test_alloc(void) +static void test_alloc(void) { struct lttng_poll_event poll_events; @@ -92,7 +89,7 @@ void test_alloc(void) } /* Tests stuff related to what would be handled with epoll_ctl. */ -void test_add_del(void) +static void test_add_del(void) { struct lttng_poll_event poll_events; @@ -101,7 +98,7 @@ void test_add_del(void) ok(lttng_poll_add(&poll_events, 1, LPOLLIN) != 0, "Adding to uninitialized structure fails"); ok(lttng_poll_add(&poll_events, -1, LPOLLIN) != 0, "Adding invalid FD fails"); - lttng_poll_create(&poll_events, 1, 0); + ok(lttng_poll_create(&poll_events, 1, 0) == 0, "Create a poll set succeeds"); ok(LTTNG_POLL_GETNB(&poll_events) == 0, "Set created empty"); ok(lttng_poll_add(NULL, 1, LPOLLIN) != 0, "Adding to NULL set fails"); @@ -130,7 +127,7 @@ void test_add_del(void) lttng_poll_clean(&poll_events); } -void test_mod_wait(void) +static void test_mod_wait(void) { struct lttng_poll_event poll_events; struct lttng_poll_event cpoll_events; @@ -186,7 +183,124 @@ void test_mod_wait(void) } } -void test_func_def(void) +static void destroy_pipe(void *pipe) +{ + lttng_pipe_destroy(pipe); +} + +static int run_active_set_combination(unsigned int fd_count, + unsigned int active_fds_mask) +{ + int ret = 0; + unsigned int i; + const unsigned int active_fds_count = __builtin_popcount(active_fds_mask); + struct lttng_poll_event poll_events; + struct lttng_dynamic_pointer_array pipes; + struct lttng_pipe *pipe = NULL; + + lttng_poll_init(&poll_events); + lttng_dynamic_pointer_array_init(&pipes, destroy_pipe); + + ret = lttng_poll_create(&poll_events, fd_count, 0); + if (ret) { + diag("Failed to create poll set for %u file descriptors", + fd_count); + goto end; + } + + for (i = 0; i < fd_count; i++) { + pipe = lttng_pipe_open(0); + + if (!pipe) { + diag("Failed to allocate pipe"); + ret = -1; + goto end; + } + + ret = lttng_poll_add(&poll_events, lttng_pipe_get_readfd(pipe), + LPOLLIN); + if (ret) { + diag("Failed to add file descriptor to poll set"); + ret = -1; + goto end; + } + + ret = lttng_dynamic_pointer_array_add_pointer(&pipes, pipe); + if (ret) { + diag("Failed to add pipe to pipes array"); + ret = -1; + goto end; + } + + /* Ownership transferred to the pointer array. */ + pipe = NULL; + } + + /* Write one byte for all active fds that should be active. */ + for (i = 0; i < fd_count; i++) { + struct lttng_pipe *borrowed_pipe; + + /* Should this fd be made active? */ + if (!(active_fds_mask & (1 << i))) { + continue; + } + + borrowed_pipe = lttng_dynamic_pointer_array_get_pointer( + &pipes, i); + + ret = lttng_pipe_write( + borrowed_pipe, &(char){'a'}, sizeof(char)); + if (ret != sizeof(char)) { + diag("Failed to write to pipe"); + ret = -1; + goto end; + } + } + + ret = lttng_poll_wait(&poll_events, 0); + if (ret != active_fds_count) { + diag("lttng_poll_wait returned %d, expected %u active file descriptors", + ret, active_fds_count); + ret = -1; + goto end; + } else { + /* Success! */ + ret = 0; + } + +end: + lttng_dynamic_pointer_array_reset(&pipes); + lttng_poll_clean(&poll_events); + lttng_pipe_destroy(pipe); + return ret; +} + +static void test_active_set_combinations(unsigned int fd_count) +{ + unsigned int i, all_active_mask = 0; + + /* Do you really want to test more than 4,294,967,295 combinations? */ + assert(fd_count <= 32); + + for (i = 0; i < fd_count; i++) { + all_active_mask |= (1 << i); + } + + for (i = 0; i <= all_active_mask; i++) { + const int ret = run_active_set_combination(fd_count, i); + + if (ret) { + goto fail; + } + } + + pass("Test all combinations of active file descriptors for %u file descriptors", fd_count); + return; +fail: + fail("Test all combinations of active file descriptors for %u file descriptors", fd_count); +} + +static void test_func_def(void) { #ifdef LTTNG_POLL_GETFD #define PASS_GETFD 1 @@ -230,5 +344,6 @@ int main(void) test_alloc(); test_add_del(); test_mod_wait(); + test_active_set_combinations(8); return exit_status(); }