stefan pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=440b7ce03f29378bf04af9ed2016049dfb8df40e

commit 440b7ce03f29378bf04af9ed2016049dfb8df40e
Author: Mike Blumenkrantz <[email protected]>
Date:   Mon Jul 30 12:50:58 2018 -0400

    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(-)

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 <sys/time.h>
 
 #ifdef HAVE_FORK
-#include <sys/types.h>
-#include <sys/wait.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+#include <signal.h>
 #include <Eina.h>
 #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 <unistd.h>
+
+#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;
+}

-- 


Reply via email to