From 45426a7604e05eb8f322e7728680b29eafdfcc3f Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Sun, 13 Dec 2009 14:14:38 -0800 Subject: [PATCH] Run each testsuite test with a timeout. --- .gitignore | 1 + Makefile.in | 7 +++++-- runtests.sh | 2 +- testrun.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 testrun.c diff --git a/.gitignore b/.gitignore index 76693bb4..805af45e 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ config.status /tests-dont-exist /testtmp /tls +/testrun /trimslash /t_unsafe /wildtest diff --git a/Makefile.in b/Makefile.in index 826cf1f5..6285666e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -47,12 +47,12 @@ TLS_OBJ = tls.o syscall.o lib/compat.o lib/snprintf.o lib/permstring.o lib/sysxa # Programs we must have to run the test cases CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) getfsdev$(EXEEXT) \ - trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(EXEEXT) + testrun$(EXEEXT) trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(EXEEXT) CHECK_SYMLINKS = testsuite/chown-fake.test testsuite/devices-fake.test # Objects for CHECK_PROGS to clean -CHECK_OBJS=tls.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.o wildtest.o +CHECK_OBJS=tls.o testrun.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.o wildtest.o # note that the -I. is needed to handle config.h when using VPATH .c.o: @@ -102,6 +102,9 @@ rounding.h: rounding.c rsync.h tls$(EXEEXT): $(TLS_OBJ) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TLS_OBJ) $(LIBS) +testrun$(EXEEXT): testrun.o + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ testrun.o + getgroups$(EXEEXT): getgroups.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ getgroups.o $(LIBS) diff --git a/runtests.sh b/runtests.sh index 41d566bf..db95d8f7 100755 --- a/runtests.sh +++ b/runtests.sh @@ -262,7 +262,7 @@ do prep_scratch set +e - sh $RUNSHFLAGS "$testscript" >"$scratchdir/test.log" 2>&1 + "$TOOLDIR/"testrun $RUNSHFLAGS "$testscript" >"$scratchdir/test.log" 2>&1 result=$? set -e diff --git a/testrun.c b/testrun.c new file mode 100644 index 00000000..e1f08318 --- /dev/null +++ b/testrun.c @@ -0,0 +1,54 @@ +/* Run a testsuite script with a timeout. */ + +#include "rsync.h" + +#define MAX_TEST_SECONDS (3*60) + + int main(int argc, char *argv[]) +{ + pid_t pid; + int status, slept = 0; + + if (argc < 2) { + fprintf(stderr, "Usage: testrun [SHELL_OPTIONS] TESTSUITE_SCRIPT [ARGS]\n"); + exit(1); + } + + if ((pid = fork()) < 0) { + fprintf(stderr, "TESTRUN ERROR: fork failed: %s\n", strerror(errno)); + exit(1); + } + + if (pid == 0) { + argv[0] = "sh"; + execvp(argv[0], argv); + fprintf(stderr, "TESTRUN ERROR: failed to exec %s: %s\n", argv[0], strerror(errno)); + _exit(1); + } + + while (1) { + int ret = waitpid(pid, &status, WNOHANG); + if (ret > 0) + break; + if (ret < 0) { + if (errno == EINTR) + continue; + fprintf(stderr, "TESTRUN ERROR: waitpid failed: %s\n", strerror(errno)); + exit(1); + } + if (slept++ > MAX_TEST_SECONDS) { + fprintf(stderr, "TESTRUN TIMEOUT: test took over %d seconds.\n", MAX_TEST_SECONDS); + if (kill(pid, SIGTERM) < 0) + fprintf(stderr, "TESTRUN ERROR: failed to kill pid %ld: %s\n", (long)pid, strerror(errno)); + else + fprintf(stderr, "TESTRUN INFO: killed pid %ld\n", (long)pid); + exit(1); + } + sleep(1); + } + + if (!WIFEXITED(status)) + exit(255); + + return WEXITSTATUS(status); +} -- 2.34.1