From d793dbc9485d33f069d68126b510874caec61b04 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 24 Aug 2012 15:36:17 +0930 Subject: [PATCH] Restore testframework.sh that I previously rewound. --- testframework.sh | 157 ++++++++++++++++++++++++++++------------------- 1 file changed, 94 insertions(+), 63 deletions(-) diff --git a/testframework.sh b/testframework.sh index a6d03afb..a3a19aa9 100644 --- a/testframework.sh +++ b/testframework.sh @@ -75,15 +75,15 @@ Options: # Internal utility for setting shopt variables and restoring their original # value: -# _tfw_shopt -s extglob -u extdebug +# local oo +# _tfw_shopt oo -s extglob -u extdebug # ... -# _tfw_shopt_restore +# _tfw_shopt_restore oo _tfw_shopt() { - if [ -n "$_tfw_shopt_orig" ]; then - _tfw_fatal "unrestored shopt settings: $_tfw_shopt_orig" - fi - _tfw_shopt_orig= + local _var="$1" + shift local op=s + local restore= while [ $# -ne 0 ] do case "$1" in @@ -91,24 +91,24 @@ _tfw_shopt() { -u) op=u;; *) local opt="$1" - _tfw_shopt_orig="${restore:+$restore; }shopt -$(shopt -q $opt && echo s || echo u) $opt" + restore="${restore:+$restore; }shopt -$(shopt -q $opt && echo s || echo u) $opt" shopt -$op $opt ;; esac shift done + eval $_var='"$restore"' } _tfw_shopt_restore() { - if [ -n "$_tfw_shopt_orig" ]; then - eval "$_tfw_shopt_orig" - _tfw_shopt_orig= - fi + local _var="$1" + [ -n "${!_var}" ] && eval "${!_var}" } -_tfw_shopt_orig= -declare -a _tfw_running_pids + +declare -a _tfw_running_jobs +declare -a _tfw_job_pgids # The rest of this file is parsed for extended glob patterns. -_tfw_shopt -s extglob +_tfw_shopt _tfw_orig_shopt -s extglob runTests() { _tfw_stdout=1 @@ -119,7 +119,7 @@ runTests() { _tfw_suite_name="${_tfw_invoking_script##*/}" _tfw_cwd=$(abspath "$PWD") _tfw_tmpdir="${TFW_TMPDIR:-${TMPDIR:-/tmp}}/_tfw-$$" - trap '_tfw_status=$?; rm -rf "$_tfw_tmpdir"; exit $_tfw_status' EXIT SIGHUP SIGINT SIGTERM + trap '_tfw_status=$?; _tfw_killtests; rm -rf "$_tfw_tmpdir"; exit $_tfw_status' EXIT SIGHUP SIGINT SIGTERM rm -rf "$_tfw_tmpdir" mkdir -p "$_tfw_tmpdir" || return $? _tfw_logdir="${TFW_LOGDIR:-$_tfw_cwd/testlog}/$_tfw_suite_name" @@ -131,7 +131,8 @@ runTests() { local allargs="$*" local -a filters=() local njobs=1 - _tfw_shopt -s extglob + local oo + _tfw_shopt oo -s extglob while [ $# -ne 0 ]; do case "$1" in --help) usage; exit 0;; @@ -149,7 +150,7 @@ runTests() { esac shift done - _tfw_shopt_restore + _tfw_shopt_restore oo if $_tfw_verbose && [ $njobs -ne 1 ]; then _tfw_fatal "--verbose is incompatible with --jobs=$njobs" fi @@ -161,6 +162,8 @@ runTests() { rm -f "$_tfw_logdir"/* # Enumerate all the test cases. _tfw_find_tests "${filters[@]}" + # Enable job control. + set -m # Iterate through all test cases, starting a new test whenever the number of # running tests is less than the job limit. _tfw_testcount=0 @@ -168,7 +171,8 @@ runTests() { _tfw_failcount=0 _tfw_errorcount=0 _tfw_fatalcount=0 - _tfw_running_pids=() + _tfw_running_jobs=() + _tfw_job_pgids=() _tfw_test_number_watermark=0 local testNumber local testPosition=0 @@ -178,7 +182,7 @@ runTests() { let ++testPosition let ++_tfw_testcount # Wait for any existing child process to finish. - while [ $njobs -ne 0 -a ${#_tfw_running_pids[*]} -ge $njobs ]; do + while [ $njobs -ne 0 -a ${#_tfw_running_jobs[*]} -ge $njobs ]; do _tfw_harvest_processes done [ $_tfw_fatalcount -ne 0 ] && break @@ -251,12 +255,14 @@ runTests() { fi } >"$_tfw_logdir/$testNumber.$testName.$result" exit 0 - ) & - _tfw_running_pids+=($!) - ln -s "$_tfw_results_dir/$testName" "$_tfw_results_dir/pid-$!" + ) /dev/null + done + while [ ${#_tfw_running_jobs[*]} -ne 0 ]; do + _tfw_harvest_processes + done +} + _tfw_echo_intro() { local docvar="doc_$3" echo -n "$2. ${!docvar:-$3}..." @@ -278,20 +300,26 @@ _tfw_harvest_processes() { # # This is the only way known to get the effect of a 'wait' builtin that will # return when _any_ child dies or after a one-second timeout. - trap 'kill $spid 2>/dev/null' SIGCHLD + trap 'kill -TERM $spid 2>/dev/null' SIGCHLD sleep 1 & spid=$! set -m - wait $spid 2>/dev/null + wait $spid >/dev/null 2>/dev/null trap - SIGCHLD # - local -a surviving_pids=() - local pid - for pid in ${_tfw_running_pids[*]}; do - if kill -0 $pid 2>/dev/null; then - surviving_pids+=($pid) - elif [ -s "$_tfw_results_dir/pid-$pid" ]; then - set -- $(<"$_tfw_results_dir/pid-$pid") + local -a surviving_jobs=() + local job + for job in ${_tfw_running_jobs[*]}; do + if jobs %$job >/dev/null 2>/dev/null; then + surviving_jobs+=($job) + continue + fi + # Kill any residual processes from the test case. + local pgid=${_tfw_job_pgids[$job]} + [ -n "$pgid" ] && kill -TERM -$pgid 2>/dev/null + # Report the test script outcome. + if [ -s "$_tfw_results_dir/job-$job" ]; then + set -- $(<"$_tfw_results_dir/job-$job") local testPosition="$1" local testNumber="$2" local testName="$3" @@ -332,10 +360,11 @@ _tfw_harvest_processes() { echo fi else - _tfw_echoerr "${BASH_SOURCE[1]}: child process $pid terminated without result" + _tfw_echoerr "${BASH_SOURCE[1]}: job %$job terminated without result" fi + rm -f "$_tfw_results_dir/job-$job" done - _tfw_running_pids=(${surviving_pids[*]}) + _tfw_running_jobs=(${surviving_jobs[*]}) } _tfw_echo_result() { @@ -542,26 +571,26 @@ tfw_cat() { local show_nonprinting= for file; do case $file in - --stdout) - tfw_log "#--- ${header:-stdout of ($executed)} ---" + --stdout) + tfw_log "#----- ${header:-stdout of ($executed)} -----" cat $show_nonprinting $_tfw_tmp/stdout - tfw_log "#---" + tfw_log "#-----" header= show_nonprinting= ;; - --stderr) - tfw_log "#--- ${header:-stderr of ($executed)} ---" + --stderr) + tfw_log "#----- ${header:-stderr of ($executed)} -----" cat $show_nonprinting $_tfw_tmp/stderr - tfw_log "#---" + tfw_log "#-----" header= show_nonprinting= ;; --header=*) header="${1#*=}";; -v|--show-nonprinting) show_nonprinting=-v;; *) - tfw_log "#--- ${header:-$file} ---" + tfw_log "#----- ${header:-${file#$_tfw_tmp/}} -----" cat $show_nonprinting "$file" - tfw_log "#---" + tfw_log "#-----" header= show_nonprinting= ;; @@ -573,9 +602,9 @@ tfw_core_backtrace() { local executable="$1" local corefile="$2" echo backtrace >"$_tfw_tmpdir/backtrace.gdb" - tfw_log "#--- gdb backtrace from $executable $corefile ---" + tfw_log "#----- gdb backtrace from $executable $corefile -----" gdb -n -batch -x "$_tfw_tmpdir/backtrace.gdb" "$executable" "$corefile"