autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

parallel autotest [1/3]: Refactor testsuite driver loop.


From: Ralf Wildenhues
Subject: parallel autotest [1/3]: Refactor testsuite driver loop.
Date: Mon, 26 May 2008 07:50:05 +0200
User-agent: Mutt/1.5.17+20080114 (2008-01-14)

2008-04-13  Ralf Wildenhues  <address@hidden>

        * lib/autotest/general.m4 (AS_MESSAGE_LOG_FD): Move definition
        earlier in the file.
        (AT_INIT): Create line number cache in
        $at_suite_dir/at-source-lines.
        <at_helper_dir>: New directory at-groups below $at_suite_dir.
        (at_func_group_prepare, at_func_group_postprocess): New shell
        functions to factorize per-test group work.  Keep the actual
        test execution outside of a shell function in order to avoid
        zsh 4.x exit status bugs.
        <at_check_line_file, at_status_file, at_stdout, at_stder1>
        <at_stderr, at_test_source>: Turn these into per-group files
        below $at_helper_dir.  Also store test results there in files
        named pass, fail, xpass, xfail, skip.  Let the parent collect
        results from $at_helper_dir.  Adjust summary statistics
        computation.

diff --git a/lib/autotest/general.m4 b/lib/autotest/general.m4
index 4ce3df7..cfa18fc 100644
--- a/lib/autotest/general.m4
+++ b/lib/autotest/general.m4
@@ -215,6 +215,8 @@ m4_define([AT_groups_all], [])
 m4_define([AT_help_all], [])
 m4_foreach([AT_name], [_AT_DEFINE_INIT_LIST], [m4_popdef(m4_defn([AT_name]))])
 m4_wrap([_AT_FINISH])
+dnl Define FDs.
+m4_define([AS_MESSAGE_LOG_FD], [5])
 AS_INIT[]dnl
 m4_divert_push([DEFAULTS])dnl
 AT_COPYRIGHT(
@@ -766,18 +768,10 @@ fi
 at_suite_dir=$at_dir/$as_me.dir
 # The file containing the suite.
 at_suite_log=$at_dir/$as_me.log
-# The file containing the location of the last AT_CHECK.
-at_check_line_file=$at_suite_dir/at-check-line
-# The file containing the exit status of the last command.
-at_status_file=$at_suite_dir/at-status
-# The files containing the output of the tested commands.
-at_stdout=$at_suite_dir/at-stdout
-at_stder1=$at_suite_dir/at-stder1
-at_stderr=$at_suite_dir/at-stderr
-# The file containing the function to run a test group.
-at_test_source=$at_suite_dir/at-test-source
-# The file containing dates.
-at_times_file=$at_suite_dir/at-times
+# The directory containing helper files per test group.
+at_helper_dir=$at_suite_dir/at-groups
+# Stop file: if it exists, do not start new jobs.
+at_stop_file=$at_suite_dir/at-stop
 
 if $at_clean; then
   test -d "$at_suite_dir" &&
@@ -835,7 +829,7 @@ export PATH
 
 # Setting up the FDs.
 # 5 is the log file.  Not to be overwritten if `-d'.
-m4_define([AS_MESSAGE_LOG_FD], [5])
+dnl FDs are defined earlier in this file.
 if $at_debug_p; then
   at_suite_log=/dev/null
 else
@@ -915,12 +909,6 @@ done
 at_start_date=`date`
 at_start_time=`date +%s 2>/dev/null`
 AS_ECHO(["$as_me: starting at: $at_start_date"]) >&AS_MESSAGE_LOG_FD
-at_xpass_list=
-at_xfail_list=
-at_pass_list=
-at_fail_list=
-at_skip_list=
-at_group_count=0
 m4_divert_pop([PREPARE_TESTS])dnl
 m4_divert_push([TESTS])dnl
 
@@ -959,19 +947,47 @@ BEGIN { FS="" }
   test = substr ($ 0, 10)
   print "at_sed" test "=\"1," start "d;" (NR-1) "q\""
   if (test == "'"$at_group"'") exit
-}' "$at_myself" > "$at_test_source" &&
-. "$at_test_source" ||
+}' "$at_myself" > "$at_suite_dir/at-source-lines" &&
+. "$at_suite_dir/at-source-lines" ||
   AS_ERROR([cannot create test line number cache])
+rm -f "$at_suite_dir/at-source-lines"
 
+# Set up helper dirs.
+rm -rf "$at_helper_dir" &&
+mkdir "$at_helper_dir" &&
+cd "$at_helper_dir" &&
+{ test -z "$at_groups" || mkdir $at_groups; } ||
+AS_ERROR([testsuite directory setup failed])
+
+# Functions for running a test group.  We leave the actual
+# test group execution outside of a shell function in order
+# to avoid hitting zsh 4.x exit status bugs.
+
+# at_func_group_prepare
+# ---------------------
+# Prepare running a test group
+at_func_group_prepare ()
+{
+  # The directory for additional per-group helper files.
+  at_job_dir=$at_helper_dir/$at_group
+  # The file containing the location of the last AT_CHECK.
+  at_check_line_file=$at_job_dir/at-check-line
+  # The file containing the exit status of the last command.
+  at_status_file=$at_job_dir/at-status
+  # The files containing the output of the tested commands.
+  at_stdout=$at_job_dir/at-stdout
+  at_stder1=$at_job_dir/at-stder1
+  at_stderr=$at_job_dir/at-stderr
+  # The file containing the code for a test group.
+  at_test_source=$at_job_dir/at-test-source
+  # The file containing dates.
+  at_times_file=$at_job_dir/at-times
 
-m4_text_box([Driver loop.])
-for at_group in $at_groups
-do
   # Be sure to come back to the top test directory.
   cd "$at_suite_dir"
 
   # Clearly separate the test groups when verbose.
-  test $at_group_count != 0 && $at_verbose echo
+  $at_first || $at_verbose echo
 
   at_group_normalized=$at_group
   _AT_NORMALIZE_TEST_GROUP_NUMBER(at_group_normalized)
@@ -982,70 +998,68 @@ do
   if test -d "$at_group_dir"; then
     find "$at_group_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
     rm -fr "$at_group_dir" ||
-      AS_WARN([test directory could not be cleaned.])
+    AS_WARN([test directory for $at_group_normalized could not be cleaned.])
   fi
   # Be tolerant if the above `rm' was not able to remove the directory.
   AS_MKDIR_P(["$at_group_dir"])
-  cd "$at_group_dir"
 
   echo 0 > "$at_status_file"
 
   # In verbose mode, append to the log file *and* show on
-  # the standard output; in quiet mode only write to the log
+  # the standard output; in quiet mode only write to the log.
   if test -z "$at_verbose"; then
     at_tee_pipe='tee -a "$at_group_log"'
   else
     at_tee_pipe='cat >> "$at_group_log"'
   fi
+}
 
-  if at_func_test $at_group && . "$at_test_source"; then :; else
-    AS_ECHO(["$as_me: unable to parse test group: $at_group"]) >&2
-    at_failed=:
-  fi
-
+# at_func_group_postprocess
+# -------------------------
+at_func_group_postprocess ()
+{
   # Be sure to come back to the suite directory, in particular
   # since below we might `rm' the group directory we are in currently.
   cd "$at_suite_dir"
 
   if test ! -f "$at_check_line_file"; then
-    sed "s/^ */$as_me: warning: /" <<_ATEOF
-       A failure happened in a test group before any test could be
-       run. This means that test suite is improperly designed.  Please
-       report this failure to <AT_PACKAGE_BUGREPORT>.
+    sed "s/^ */$as_me: WARNING: /" <<_ATEOF
+      A failure happened in a test group before any test could be
+      run. This means that test suite is improperly designed.  Please
+      report this failure to <AT_PACKAGE_BUGREPORT>.
 _ATEOF
     AS_ECHO(["$at_setup_line"]) >"$at_check_line_file"
   fi
-  at_func_arith 1 + $at_group_count
-  at_group_count=$at_func_arith_result
   $at_verbose AS_ECHO_N(["$at_group. $at_setup_line: "])
   AS_ECHO_N(["$at_group. $at_setup_line: "]) >> "$at_group_log"
   case $at_xfail:$at_status in
     yes:0)
        at_msg="UNEXPECTED PASS"
-       at_xpass_list="$at_xpass_list $at_group"
+       at_res=xpass
        at_errexit=$at_errexit_p
        ;;
     no:0)
        at_msg="ok"
-       at_pass_list="$at_pass_list $at_group"
+       at_res=pass
        at_errexit=false
        ;;
     *:77)
        at_msg='skipped ('`cat "$at_check_line_file"`')'
-       at_skip_list="$at_skip_list $at_group"
+       at_res=skip
        at_errexit=false
        ;;
     yes:*)
        at_msg='expected failure ('`cat "$at_check_line_file"`')'
-       at_xfail_list="$at_xfail_list $at_group"
+       at_res=xfail
        at_errexit=false
        ;;
     no:*)
        at_msg='FAILED ('`cat "$at_check_line_file"`')'
-       at_fail_list="$at_fail_list $at_group"
+       at_res=fail
        at_errexit=$at_errexit_p
        ;;
   esac
+  echo "$at_res" > "$at_job_dir/$at_res"
   # Make sure there is a separator even with long titles.
   AS_ECHO([" $at_msg"])
   at_log_msg="$at_group. $at_desc ($at_setup_line): $at_msg"
@@ -1063,7 +1077,7 @@ _ATEOF
       AS_ECHO(["$at_log_msg"]) >&AS_MESSAGE_LOG_FD
 
       # Cleanup the group directory, unless the user wants the files.
-      if $at_debug_p ; then
+      if $at_debug_p; then
        at_func_create_debugging_script
       else
        if test -d "$at_group_dir"; then
@@ -1079,16 +1093,61 @@ _ATEOF
       # is later included in the global log.
       AS_ECHO(["$at_log_msg"]) >> "$at_group_log"
 
-      # Upon failure, keep the group directory for autopsy, and
-      # create the debugging script.
+      # Upon failure, keep the group directory for autopsy, and create
+      # the debugging script.  With -e, do not start any further tests.
       at_func_create_debugging_script
-      $at_errexit && break
+      if $at_errexit; then
+       echo stop > "$at_stop_file"
+      fi
       ;;
   esac
+}
+
+
+m4_text_box([Driver loop.])
+
+rm -f "$at_stop_file"
+at_first=:
+
+for at_group in $at_groups; do
+  at_func_group_prepare
+  if cd "$at_group_dir" &&
+     at_func_test $at_group &&
+     . "$at_test_source"; then :; else
+    AS_WARN([unable to parse test group: $at_group])
+    at_failed=:
+  fi
+  at_func_group_postprocess
+  test -f "$at_stop_file" && break
+  at_first=false
 done
 
+# Wrap up the test suite with summary statistics.
+cd "$at_helper_dir"
+
+at_pass_list=`echo */pass | sed 's,/pass,,g; s,\*,,'`
+at_xpass_list=`echo */xpass | sed 's,/xpass,,g; s,\*,,'`
+at_xfail_list=`echo */xfail | sed 's,/xfail,,g; s,\*,,'`
+at_fail_list=`echo */fail | sed 's,/fail,,g; s,\*,,'`
+at_skip_list=`echo */skip | sed 's,/skip,,g; s,\*,,'`
+
+set X $at_pass_list $at_xpass_list $at_xfail_list $at_fail_list $at_skip_list
+shift; address@hidden:@]
+set X $at_xpass_list; shift; address@hidden:@]
+set X $at_xfail_list; shift; address@hidden:@]
+set X $at_fail_list; shift; address@hidden:@]
+set X $at_skip_list; shift; address@hidden:@]
+
+at_func_arith $at_group_count - $at_skip_count
+at_run_count=$at_func_arith_result
+at_func_arith $at_xpass_count + $at_fail_count
+at_unexpected_count=$at_func_arith_result
+at_func_arith $at_xfail_count + $at_fail_count
+at_total_fail_count=$at_func_arith_result
+
 # Back to the top directory.
 cd "$at_dir"
+rm -rf "$at_helper_dir"
 
 # Compute the duration of the suite.
 at_stop_date=`date`
@@ -1111,19 +1170,6 @@ case $at_start_time,$at_stop_time in
     ;;
 esac
 
-# Wrap up the test suite with summary statistics.
-set X $at_skip_list; shift; address@hidden:@]
-set X $at_fail_list; shift; address@hidden:@]
-set X $at_xpass_list; shift; address@hidden:@]
-set X $at_xfail_list; shift; address@hidden:@]
-
-at_func_arith $at_group_count - $at_skip_count
-at_run_count=$at_func_arith_result
-at_func_arith $at_xpass_count + $at_fail_count
-at_unexpected_count=$at_func_arith_result
-at_func_arith $at_xfail_count + $at_fail_count
-at_total_fail_count=$at_func_arith_result
-
 echo
 AS_BOX([Test results.])
 echo




reply via email to

[Prev in Thread] Current Thread [Next in Thread]