summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorPekka Paalanen <ppaalanen@gmail.com>2012-04-20 14:22:51 +0300
committerPekka Paalanen <ppaalanen@gmail.com>2012-04-20 15:06:27 +0300
commitda6b1a8e4774234c2dbdd9f2875de21b41086d00 (patch)
tree66b63cf24dcdc24cfd1b1b562f788e935184ca2d /tests
parent7c0aa1a4a3aca023cbdad0a97de124a77cb98aa1 (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.am16
-rw-r--r--tests/exec-fd-leak-checker.c75
-rw-r--r--tests/sanity-test.c22
-rw-r--r--tests/test-helpers.c12
-rw-r--r--tests/test-runner.h3
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