From 440b7ce03f29378bf04af9ed2016049dfb8df40e Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Mon, 30 Jul 2018 12:50:58 -0400 Subject: [PATCH] tests: add failsafe timeout for tests running in fork mode some tests manage to deadlock themselves on travis, seemingly due to some hard to reproduce issues which are a result of the extremely low amount of resources available on travis builds this adds a simple 'timeout' process which does nothing but sleep(60); and then returns. the exiting of this process will cause the main test process to break out of the deadlock and then exit instead of timing out a ci build Differential Revision: https://phab.enlightenment.org/D6697 --- src/Makefile.am | 4 ++++ src/tests/.gitignore | 1 + src/tests/efl_check.h | 53 +++++++++++++++++++++++++++++++++++-------- src/tests/timeout.c | 15 ++++++++++++ 4 files changed, 63 insertions(+), 10 deletions(-) create mode 100644 src/tests/timeout.c diff --git a/src/Makefile.am b/src/Makefile.am index 86fb3b999b..1ab87da020 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -125,6 +125,10 @@ endif DIST_SUBDIRS += $(EXAMPLES_SUBDIRS) if EFL_ENABLE_TESTS +noinst_PROGRAMS += tests/timeout + +$(check_PROGRAMS): tests/timeout + check-build: all @$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) endif diff --git a/src/tests/.gitignore b/src/tests/.gitignore index 9b233a4f3e..db7ce40f57 100644 --- a/src/tests/.gitignore +++ b/src/tests/.gitignore @@ -4,3 +4,4 @@ check-results*.xml *_suite.trs *.node */cxx_compile_test +/timeout diff --git a/src/tests/efl_check.h b/src/tests/efl_check.h index e3218ccc29..b61bcbbdf8 100644 --- a/src/tests/efl_check.h +++ b/src/tests/efl_check.h @@ -13,8 +13,13 @@ #include #ifdef HAVE_FORK -#include -#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif +#include #include #endif @@ -55,6 +60,8 @@ struct _Efl_Test_Case void (*build)(TCase *tc); }; +static int timeout_pid = 0; + static void _efl_tests_list(const Efl_Test_Case *etc) { @@ -247,15 +254,18 @@ _efl_suite_run_end(SRunner *sr, const char *name) #ifdef HAVE_FORK EINA_UNUSED static int -_efl_suite_wait_on_fork(int *num_forks) +_efl_suite_wait_on_fork(int *num_forks, Eina_Bool *timeout) { - int status = 0, ret; - waitpid(0, &status, 0); + int status = 0, ret, pid; + pid = waitpid(0, &status, 0); if (WIFEXITED(status)) ret = WEXITSTATUS(status); else ret = 1; - (*num_forks)--; + if (pid == timeout_pid) + *timeout = EINA_TRUE; + else + (*num_forks)--; return ret; } #endif @@ -270,6 +280,7 @@ _efl_suite_build_and_run(int argc, const char **argv, const char *suite_name, co int do_fork; int num_forks = 0; int can_fork = 0; + Eina_Bool timeout_reached = EINA_FALSE; #ifdef ENABLE_TIMING_INFO double tstart, tcstart; int timing = _timing_enabled(); @@ -293,8 +304,15 @@ _efl_suite_build_and_run(int argc, const char **argv, const char *suite_name, co #ifdef HAVE_FORK if (do_fork && can_fork) { + if (!timeout_pid) + { + timeout_pid = fork(); + if (!timeout_pid) + execl("/bin/sh", "/bin/sh", "-c", PACKAGE_BUILD_DIR "/src/tests/timeout", (char *)NULL); + } if (num_forks == eina_cpu_count()) - failed_count += _efl_suite_wait_on_fork(&num_forks); + failed_count += _efl_suite_wait_on_fork(&num_forks, &timeout_reached); + if (timeout_reached) break; pid = fork(); if (pid > 0) { @@ -333,17 +351,32 @@ _efl_suite_build_and_run(int argc, const char **argv, const char *suite_name, co } #ifdef HAVE_FORK - if (num_forks) + if (num_forks && (!timeout_reached)) { do { - failed_count += _efl_suite_wait_on_fork(&num_forks); - } while (num_forks); + failed_count += _efl_suite_wait_on_fork(&num_forks, &timeout_reached); + } while (num_forks && (!timeout_reached)); + if (timeout_reached) + { + timeout_pid = 0; + printf("FAILSAFE TIMEOUT REACHED!\n"); + fflush(stdout); + failed_count++; + } } else #endif failed_count = _efl_suite_run_end(sr, NULL); +#ifdef HAVE_FORK + if (timeout_pid) + { + kill(timeout_pid, SIGKILL); + timeout_pid = 0; + } +#endif + #ifdef ENABLE_TIMING_INFO if (timing) { diff --git a/src/tests/timeout.c b/src/tests/timeout.c new file mode 100644 index 0000000000..de881535c1 --- /dev/null +++ b/src/tests/timeout.c @@ -0,0 +1,15 @@ +#include + +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wunused-parameter" +#elif (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4 +# pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + + +int +main(int arc, char *argv[]) +{ + sleep(60); + return 0; +}