diff options
author | Pekka Paalanen <ppaalanen@gmail.com> | 2012-04-20 14:22:51 +0300 |
---|---|---|
committer | Pekka Paalanen <ppaalanen@gmail.com> | 2012-04-20 15:06:27 +0300 |
commit | da6b1a8e4774234c2dbdd9f2875de21b41086d00 (patch) | |
tree | 66b63cf24dcdc24cfd1b1b562f788e935184ca2d /tests | |
parent | 7c0aa1a4a3aca023cbdad0a97de124a77cb98aa1 (diff) |
tests: support testing fd inheritance over exec
Add facility for testing how (many) file descriptors survive an exec.
This allows implementing O_CLOEXEC tests.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.am | 16 | ||||
-rw-r--r-- | tests/exec-fd-leak-checker.c | 75 | ||||
-rw-r--r-- | tests/sanity-test.c | 22 | ||||
-rw-r--r-- | tests/test-helpers.c | 12 | ||||
-rw-r--r-- | tests/test-runner.h | 3 |
5 files changed, 124 insertions, 4 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index 7224778..af76c5f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,7 +1,4 @@ -TESTS = $(check_PROGRAMS) - - -check_PROGRAMS = \ +my_check_programs = \ sanity-test \ array-test \ map-test \ @@ -10,6 +7,12 @@ check_PROGRAMS = \ event-loop-test \ client-test +TESTS = $(my_check_programs) + +check_PROGRAMS = \ + $(my_check_programs) \ + exec-fd-leak-checker + test_runner_src = test-runner.c test-runner.h test-helpers.c sanity_test_SOURCES = sanity-test.c $(test_runner_src) @@ -25,3 +28,8 @@ LDADD = $(top_builddir)/src/libwayland-util.la \ $(top_builddir)/src/libwayland-server.la \ -lrt -ldl $(FFI_LIBS) +exec_fd_leak_checker_SOURCES = \ + exec-fd-leak-checker.c \ + test-runner.h \ + test-helpers.c +exec_fd_leak_checker_LDADD = diff --git a/tests/exec-fd-leak-checker.c b/tests/exec-fd-leak-checker.c new file mode 100644 index 0000000..66209ad --- /dev/null +++ b/tests/exec-fd-leak-checker.c @@ -0,0 +1,75 @@ +/* + * Copyright © 2012 Collabora, Ltd. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <limits.h> + +#include "test-runner.h" + +static int +parse_count(const char *str, int *value) +{ + char *end; + long v; + + errno = 0; + v = strtol(str, &end, 0); + if ((errno == ERANGE && (v == LONG_MAX || v == LONG_MIN)) || + (errno != 0 && v == 0) || + (end == str) || + (*end != '\0')) { + return -1; + } + + if (v < 0 || v > INT_MAX) { + return -1; + } + + *value = v; + return 0; +} + +int main(int argc, char *argv[]) +{ + int expected; + + if (argc != 2) + goto help_out; + + if (parse_count(argv[1], &expected) < 0) + goto help_out; + + if (count_open_fds() == expected) + return EXIT_SUCCESS; + else + return EXIT_FAILURE; + +help_out: + fprintf(stderr, "Usage: %s N\n" + "where N is the expected number of open file descriptors.\n" + "This program exits with a failure if the number " + "does not match exactly.\n", argv[0]); + + return EXIT_FAILURE; +} diff --git a/tests/sanity-test.c b/tests/sanity-test.c index 389ee4c..65e0144 100644 --- a/tests/sanity-test.c +++ b/tests/sanity-test.c @@ -93,3 +93,25 @@ FAIL_TEST(sanity_fd_leak) /* leak 2 file descriptors */ pipe(fd); } + +FAIL_TEST(sanity_fd_leak_exec) +{ + int fd[2]; + int nr_fds = count_open_fds(); + + /* leak 2 file descriptors */ + pipe(fd); + + exec_fd_leak_check(nr_fds); +} + +TEST(sanity_fd_exec) +{ + int fd[2]; + int nr_fds = count_open_fds(); + + /* create 2 file descriptors, that should pass over exec */ + pipe(fd); + + exec_fd_leak_check(nr_fds + 2); +} diff --git a/tests/test-helpers.c b/tests/test-helpers.c index 2cc5c7d..4761b09 100644 --- a/tests/test-helpers.c +++ b/tests/test-helpers.c @@ -23,6 +23,8 @@ #include <assert.h> #include <errno.h> #include <dirent.h> +#include <stdio.h> +#include <unistd.h> #include "test-runner.h" @@ -50,3 +52,13 @@ count_open_fds(void) return count; } +void +exec_fd_leak_check(int nr_expected_fds) +{ + const char *exe = "./exec-fd-leak-checker"; + char number[16] = { 0 }; + + snprintf(number, sizeof number - 1, "%d", nr_expected_fds); + execl(exe, exe, number, (char *)NULL); + assert(0 && "execing fd leak checker failed"); +} diff --git a/tests/test-runner.h b/tests/test-runner.h index edcf592..707504c 100644 --- a/tests/test-runner.h +++ b/tests/test-runner.h @@ -34,4 +34,7 @@ struct test { int count_open_fds(void); +void +exec_fd_leak_check(int nr_expected_fds); /* never returns */ + #endif |