[Top][All Lists]
[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