diff options
author | Lucas De Marchi <lucas.de.marchi@gmail.com> | 2012-06-06 01:03:15 -0300 |
---|---|---|
committer | Lucas De Marchi <lucas.de.marchi@gmail.com> | 2012-06-06 01:45:30 -0300 |
commit | b8e344a6d2c9526a7476b78255185a96097f2629 (patch) | |
tree | c35769936f3a084e6aec5a76a037f8e5025d5294 | |
parent | ed8e93fd92a95d63198fc96d59053b6be40e09f8 (diff) | |
download | kmod-b8e344a6d2c9526a7476b78255185a96097f2629.tar.gz |
testsuite: add timeout for each test
Each test must run under 2 seconds. Ideally they should run in much less
than this; just give an arbitrary number so we don't wait forever in
case we reached an infinite loop somewhere.
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | testsuite/testsuite.c | 42 |
2 files changed, 37 insertions, 6 deletions
diff --git a/Makefile.am b/Makefile.am index 5751dbd..faad5b8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -169,6 +169,7 @@ testsuite_libtestsuite_la_SOURCES = testsuite/testsuite.c \ testsuite_libtestsuite_la_DEPENDENCIES = $(ROOTFS) \ $(TESTSUITE_OVERRIDE_LIBS) testsuite_libtestsuite_la_CPPFLAGS = $(TESTSUITE_CPPFLAGS) +testsuite_libtestsuite_la_LIBADD = -lrt TESTSUITE = testsuite/test-init testsuite/test-testsuite testsuite/test-loaded \ testsuite/test-modinfo testsuite/test-alias testsuite/test-new-module \ diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c index de1a0fa..14af73e 100644 --- a/testsuite/testsuite.c +++ b/testsuite/testsuite.c @@ -23,6 +23,7 @@ #include <stdarg.h> #include <stdlib.h> #include <string.h> +#include <time.h> #include <unistd.h> #include <sys/epoll.h> #include <sys/prctl.h> @@ -57,6 +58,19 @@ struct _env_config { [TC_DELETE_MODULE_RETCODES] = { S_TC_DELETE_MODULE_RETCODES, OVERRIDE_LIBDIR "delete_module.so" }, }; +#define USEC_PER_SEC 1000000ULL +#define USEC_PER_MSEC 1000ULL +#define TEST_TIMEOUT_USEC 2 * USEC_PER_SEC +static unsigned long long now_usec(void) +{ + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) + return 0; + + return ts_usec(&ts); +} + static void help(void) { const struct option *itr; @@ -251,10 +265,11 @@ static inline int test_run_child(const struct test *t, int fdout[2], } static inline bool test_run_parent_check_outputs(const struct test *t, - int fdout, int fderr, int fdmonitor) + int fdout, int fderr, int fdmonitor, pid_t child) { struct epoll_event ep_outpipe, ep_errpipe, ep_monitor; int err, fd_ep, fd_matchout = -1, fd_matcherr = -1; + unsigned long long end_usec, start_usec; fd_ep = epoll_create1(EPOLL_CLOEXEC); if (fd_ep < 0) { @@ -310,11 +325,19 @@ static inline bool test_run_parent_check_outputs(const struct test *t, goto out; } + start_usec = now_usec(); + end_usec = start_usec + TEST_TIMEOUT_USEC; + for (err = 0; fdmonitor >= 0 || fdout >= 0 || fderr >= 0;) { - int fdcount, i; + int fdcount, i, timeout; struct epoll_event ev[4]; + unsigned long long curr_usec = now_usec(); - fdcount = epoll_wait(fd_ep, ev, 4, -1); + if (curr_usec > end_usec) + break; + + timeout = (end_usec - curr_usec) / USEC_PER_MSEC; + fdcount = epoll_wait(fd_ep, ev, 4, timeout); if (fdcount < 0) { if (errno == EINTR) continue; @@ -388,8 +411,14 @@ static inline bool test_run_parent_check_outputs(const struct test *t, *fd = -1; } } + } + if (err == 0 && fdmonitor >= 0) { + err = -EINVAL; + ERR("Test '%s' timed out, killing %d\n", t->name, child); + kill(child, SIGKILL); } + out: if (fd_matchout >= 0) close(fd_matchout); @@ -401,7 +430,7 @@ out: } static inline int test_run_parent(const struct test *t, int fdout[2], - int fderr[2], int fdmonitor[2]) + int fderr[2], int fdmonitor[2], pid_t child) { pid_t pid; int err; @@ -415,7 +444,7 @@ static inline int test_run_parent(const struct test *t, int fdout[2], close(fdmonitor[1]); matchout = test_run_parent_check_outputs(t, fdout[0], fderr[0], - fdmonitor[0]); + fdmonitor[0], child); /* * break pipe on the other end: either child already closed or we want @@ -445,6 +474,7 @@ static inline int test_run_parent(const struct test *t, int fdout[2], } else if (WIFSIGNALED(err)) { ERR("'%s' [%u] terminated by signal %d (%s)\n", t->name, pid, WTERMSIG(err), strsignal(WTERMSIG(err))); + return EXIT_FAILURE; } if (t->expected_fail == false) { @@ -552,7 +582,7 @@ int test_run(const struct test *t) } if (pid > 0) - return test_run_parent(t, fdout, fderr, fdmonitor); + return test_run_parent(t, fdout, fderr, fdmonitor, pid); return test_run_child(t, fdout, fderr, fdmonitor); } |