From 712261c89b18c87595db61f377bfd1075160a6e0 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Mon, 8 Jun 2020 23:02:26 +0200 Subject: [PATCH] shtests: More speedups; also fix xtrace (re: 734e5953) This reduces a bunch more unnecessarily long sleeps to give asynchronous processes time to run, etc. (No, we don't need to be compatible anymore with your cool 1985 Intel 80386DX 16 MHz battlestation...) Running the test suite is almost tolerable now, making me much more likely to actually run the regression test suite and catch my own regressions. In addition, there are various fixes to make the test suite compatible with 'set -x' ('set -o xtrace') so that you can now actually *use* the documented 'bin/shtests -x' option. Recommend combining with '-p' to avoid tracing everything three times. I've also added a really useful $PS4 trace prompt to shtests that traces pretty much everything there is to trace. (It does use expansions that modify ${.sh.match}, which affected several tests, particularly in tests/substring.sh; for those we need to set a temporary simpler $PS4.) (cherry picked from commit c3a5d47cfe880b526cabb5370ddaced0e8626acd) --- src/cmd/ksh93/tests/basic.sh | 56 ++++++++++++++++++-------------- src/cmd/ksh93/tests/bracket.sh | 6 ++-- src/cmd/ksh93/tests/builtins.sh | 2 +- src/cmd/ksh93/tests/coprocess.sh | 36 ++++++++++---------- src/cmd/ksh93/tests/functions.sh | 7 ++++ src/cmd/ksh93/tests/io.sh | 39 ++++++++++++---------- src/cmd/ksh93/tests/locale.sh | 6 ++-- src/cmd/ksh93/tests/options.sh | 12 +++---- src/cmd/ksh93/tests/path.sh | 2 +- src/cmd/ksh93/tests/shtests | 2 +- src/cmd/ksh93/tests/sigchld.sh | 24 +++++++------- src/cmd/ksh93/tests/signal.sh | 6 ++-- src/cmd/ksh93/tests/subshell.sh | 47 ++++++++++++++------------- src/cmd/ksh93/tests/substring.sh | 41 ++++++++++++++++++++--- src/cmd/ksh93/tests/variables.sh | 12 ++++--- 15 files changed, 178 insertions(+), 120 deletions(-) diff --git a/src/cmd/ksh93/tests/basic.sh b/src/cmd/ksh93/tests/basic.sh index 33b8d64f5..b73ec9474 100755 --- a/src/cmd/ksh93/tests/basic.sh +++ b/src/cmd/ksh93/tests/basic.sh @@ -38,6 +38,13 @@ tmp=$( trap 'cd / && rm -rf "$tmp"' EXIT bincat=$(whence -p cat) binecho=$(whence -p echo) +# make an external 'sleep' command that supports fractional seconds +binsleep=$tmp/.sleep.sh # hide to exclude from simple wildcard expansion +cat >"$binsleep" < $tmp/foobar & @@ -294,7 +301,7 @@ if [[ $(for i in foo bar then err_exit 'for loop subshell optimizer bug' fi unset a1 -optbug() +function optbug { set -A a1 foo bar bam integer i @@ -307,15 +314,15 @@ optbug() done return 1 } -optbug || err_exit 'array size optimzation bug' +optbug || err_exit 'array size optimization bug' wait # not running --pipefail which would interfere with subsequent tests : $(jobs -p) # required to clear jobs for next jobs -p (interactive side effect) -sleep 20 & +sleep 2 & pids=$! if [[ $(jobs -p) != $! ]] then err_exit 'jobs -p not reporting a background job' fi -sleep 20 & +sleep 2 & pids="$pids $!" foo() { @@ -325,8 +332,8 @@ foo() foo kill $pids -[[ $( (trap 'print alarm' ALRM; sleep 4) & sleep 2; kill -ALRM $!; sleep 2; wait) == alarm ]] || err_exit 'ALRM signal not working' -[[ $($SHELL -c 'trap "" HUP; $SHELL -c "(sleep 2;kill -HUP $$)& sleep 4;print done"') != done ]] && err_exit 'ignored traps not being ignored' +[[ $( (trap 'print alarm' ALRM; sleep .4) & sleep .2; kill -ALRM $!; sleep .2; wait) == alarm ]] || err_exit 'ALRM signal not working' +[[ $($SHELL -c 'trap "" HUP; $SHELL -c "(sleep .2;kill -HUP $$)& sleep .4;print done"') != done ]] && err_exit 'ignored traps not being ignored' [[ $($SHELL -c 'o=foobar; for x in foo bar; do (o=save);print $o;done' 2> /dev/null ) == $'foobar\nfoobar' ]] || err_exit 'for loop optimization subshell bug' command exec 3<> /dev/null if cat /dev/fd/3 >/dev/null 2>&1 || whence mkfifo > /dev/null @@ -372,9 +379,9 @@ chmod +x $tmp/scriptx cat > $tmp/scriptx <<- \EOF myfilter() { x=$(print ok | cat); print -r -- $SECONDS;} set -o pipefail - sleep 3 | myfilter + sleep .3 | myfilter EOF -(( $($SHELL $tmp/scriptx) > 2.0 )) && err_exit 'command substitution causes pipefail option to hang' +(( $($SHELL $tmp/scriptx) > .2 )) && err_exit 'command substitution causes pipefail option to hang' exec 3<&- ( typeset -r foo=bar) 2> /dev/null || err_exit 'readonly variables set in a subshell cannot unset' $SHELL -c 'x=${ print hello;}; [[ $x == hello ]]' 2> /dev/null || err_exit '${ command;} not supported' @@ -418,7 +425,7 @@ unset foo unset foo foo=$(false) > /dev/null && err_exit 'failed command substitution with redirection not returning false' expected=foreback -got=$(print -n fore; (sleep 2;print back)&) +got=$(print -n fore; (sleep .2;print back)&) [[ $got == $expected ]] || err_exit "command substitution background process output error -- got '$got', expected '$expected'" binfalse=$(whence -p false) @@ -430,19 +437,20 @@ done if env x-a=y >/dev/null 2>&1 then [[ $(env 'x-a=y' $SHELL -c 'env | grep x-a') == *x-a=y* ]] || err_exit 'invalid environment variables not preserved' fi + float s=SECONDS -sleep=$(whence -p sleep) -for i in 1 2 +for i in .1 .2 do print $i -done | while read sec; do ( $sleep $sec; $sleep $sec) done -(( (SECONDS-s) < 4)) && err_exit '"command | while read...done" finishing too fast' +done | while read sec; do ( "$binsleep" "$sec"; "$binsleep" "$sec") done +(( (SECONDS-s) < .4)) && err_exit '"command | while read...done" finishing too fast' s=SECONDS set -o pipefail for ((i=0; i < 30; i++)) do print hello 2>/dev/null - sleep .1 -done | $sleep 1 -(( (SECONDS-s) < 2 )) || err_exit 'early termination not causing broken pipe' + sleep .01 +done | "$binsleep" .1 +(( (SECONDS-s) < .2 )) || err_exit 'early termination not causing broken pipe' + [[ $({ trap 'print trap' 0; print -n | $(whence -p cat); } & wait $!) == trap ]] || err_exit 'trap on exit not getting triggered' var=$({ trap 'print trap' ERR; print -n | $binfalse; } & wait $!) [[ $var == trap ]] || err_exit 'trap on ERR not getting triggered' @@ -479,28 +487,28 @@ set -o pipefail float start=$SECONDS end for ((i=0; i < 2; i++)) do print foo 2>/dev/null - sleep 1.5 + sleep .15 done | { read; $bintrue; end=$SECONDS ;} -(( (SECONDS-start) < 1 )) && err_exit "pipefail not waiting for pipe to finish" +(( (SECONDS-start) < .1 )) && err_exit "pipefail not waiting for pipe to finish" set +o pipefail -(( (SECONDS-end) > 2 )) && err_exit "pipefail causing $bintrue to wait for other end of pipe" +(( (SECONDS-end) > .2 )) && err_exit "pipefail causing $bintrue to wait for other end of pipe" { env A__z=C+SHLVL $SHELL -c : ;} 2> /dev/null || err_exit "SHLVL with wrong attribute fails" if [[ $bintrue ]] then float t0=SECONDS - { time sleep 1.5 | $bintrue ;} 2> /dev/null - (( (SECONDS-t0) < 1 )) && err_exit 'time not waiting for pipeline to complete' + { time sleep .15 | $bintrue ;} 2> /dev/null + (( (SECONDS-t0) < .1 )) && err_exit 'time not waiting for pipeline to complete' fi cat > $tmp/foo.sh <<- \EOF eval "cat > /dev/null < /dev/null" - sleep 1 + sleep .1 EOF float sec=SECONDS . $tmp/foo.sh | cat > /dev/null -(( (SECONDS-sec) < .7 )) && err_exit '. script does not restore output redirection with eval' +(( (SECONDS-sec) < .07 )) && err_exit '. script does not restore output redirection with eval' file=$tmp/foobar builtin cat diff --git a/src/cmd/ksh93/tests/bracket.sh b/src/cmd/ksh93/tests/bracket.sh index ff1f331d4..46238036c 100755 --- a/src/cmd/ksh93/tests/bracket.sh +++ b/src/cmd/ksh93/tests/bracket.sh @@ -130,7 +130,7 @@ fi if [[ ! -w /dev/fd/2 ]] then err_exit "/dev/fd/2 not open for writing" fi -sleep 1 +sleep .01 > $newer_file if [[ ! $file -ot $newer_file ]] then err_exit "$file should be older than $newer_file" @@ -235,10 +235,10 @@ done rm -rf $file { [[ -N $file ]] && err_exit 'test -N $tmp/*: st_mtime>st_atime after creat' -sleep 2 +sleep .02 print 'hello world' [[ -N $file ]] || err_exit 'test -N $tmp/*: st_mtime<=st_atime after write' -sleep 2 +sleep .02 read [[ -N $file ]] && err_exit 'test -N $tmp/*: st_mtime>st_atime after read' } > $file < $file diff --git a/src/cmd/ksh93/tests/builtins.sh b/src/cmd/ksh93/tests/builtins.sh index a8fe9dd66..2f43aab5f 100755 --- a/src/cmd/ksh93/tests/builtins.sh +++ b/src/cmd/ksh93/tests/builtins.sh @@ -385,7 +385,7 @@ do arg=$1 val=$2 code=$3 shift 3 for fmt in '%d' '%g' do out=$(printf "$fmt" "$arg" 2>/dev/null) - err=$(printf "$fmt" "$arg" 2>&1 >/dev/null) + err=$(set +x; printf "$fmt" "$arg" 2>&1 >/dev/null) printf "$fmt" "$arg" >/dev/null 2>&1 ret=$? [[ $out == $val ]] || err_exit "printf $fmt $arg failed -- expected '$val', got '$out'" diff --git a/src/cmd/ksh93/tests/coprocess.sh b/src/cmd/ksh93/tests/coprocess.sh index 0764f9e77..1cc473334 100755 --- a/src/cmd/ksh93/tests/coprocess.sh +++ b/src/cmd/ksh93/tests/coprocess.sh @@ -109,7 +109,7 @@ do $cat |& ! chmod +x $file - sleep 10 |& + sleep 1 |& $file 2> /dev/null || err_exit "parent $cat coprocess prevents script coprocess" exec 5<&p 6>&p exec 5<&- 6>&- @@ -119,15 +119,15 @@ do cop=$! exp=Done print -p $'print hello | '$cat$'\nprint '$exp - read -t 5 -p - read -t 5 -p + read -t 1 -p + read -t 1 -p got=$REPLY if [[ $got != $exp ]] then err_exit "${SHELL-ksh} $cat coprocess io failed -- got '$got', expected '$exp'" fi exec 5<&p 6>&p exec 5<&- 6>&- - { sleep 4; kill $cop; } 2>/dev/null & + { sleep .4; kill $cop; } 2>/dev/null & spy=$! if wait $cop 2>/dev/null then kill $spy 2>/dev/null @@ -140,15 +140,15 @@ do echo line2 | grep 'line1' } |& SECONDS=0 count=0 - while read -p -t 10 line + while read -p -t 1 line do ((count++)) done - if (( SECONDS > 8 )) + if (( SECONDS > .8 )) then err_exit "$cat coprocess read -p hanging (SECONDS=$SECONDS count=$count)" fi wait $! - ( sleep 3 |& sleep 1 && kill $!; sleep 1; sleep 3 |& sleep 1 && kill $! ) || + ( sleep .3 |& sleep .1 && kill $!; sleep .1; sleep .3 |& sleep .1 && kill $! ) || err_exit "$cat coprocess cleanup not working correctly" { : |& } 2>/dev/null || err_exit "subshell $cat coprocess lingers in parent" @@ -166,7 +166,7 @@ do wait $! done print - ) 2>/dev/null | read -t 10 r + ) 2>/dev/null | read -t 1 r [[ $r == $e ]] || err_exit "$cat coprocess timing bug -- expected $e, got '$r'" r= @@ -174,21 +174,21 @@ do integer i for ((i = 1; i <= N; i++)) do print $i |& - sleep 0.01 + sleep 0.001 r=$r$($cat <&p) wait $! done print $r - ) 2>/dev/null | read -t 10 r + ) 2>/dev/null | read -t 1 r [[ $r == $e ]] || err_exit "$cat coprocess command substitution bug -- expected $e, got '$r'" ( $cat |& - sleep 0.01 + sleep 0.001 exec 6>&p print -u6 ok exec 6>&- - sleep 2 + sleep .2 kill $! 2> /dev/null ) && err_exit "$cat coprocess with subshell would hang" for sig in IOT ABRT @@ -198,12 +198,12 @@ do pid=\$! trap "print TRAP" \$sig ( - sleep 2 + sleep .2 kill -\$sig \$\$ - sleep 2 + sleep .2 kill -\$sig \$\$ kill \$pid - sleep 2 + sleep .2 kill \$\$ ) & while read -p || ((\$? > 256)) @@ -218,7 +218,7 @@ do done trap 'sleep_pid=; kill $pid; err_exit "$cat coprocess 1 hung"' TERM - { sleep 5; kill $$; } & + { sleep .5; kill $$; } & sleep_pid=$! $cat |& pid=$! @@ -232,7 +232,7 @@ do [[ $sleep_pid ]] && kill $sleep_pid trap 'sleep_pid=; kill $pid; err_exit "$cat coprocess 2 hung"' TERM - { sleep 5; kill $$; } & + { sleep .5; kill $$; } & sleep_pid=$! $cat |& pid=$! @@ -244,7 +244,7 @@ do [[ $sleep_pid ]] && kill $sleep_pid trap 'sleep_pid=; kill $pid; err_exit "$cat coprocess 3 hung"' TERM - { sleep 5; kill $$; } & + { sleep .5; kill $$; } & sleep_pid=$! $cat |& pid=$! diff --git a/src/cmd/ksh93/tests/functions.sh b/src/cmd/ksh93/tests/functions.sh index 83df8f10d..562821000 100755 --- a/src/cmd/ksh93/tests/functions.sh +++ b/src/cmd/ksh93/tests/functions.sh @@ -981,10 +981,17 @@ function _Dbg_debug_trap_handler done } +( +: 'Disabling xtrace while running _Dbg_* functions' +set +x # TODO: the _Dbg_* functions are incompatible with xtrace. To expose the regression + # test failures, run 'bin/shtests -x -p functions'. Is this a bug in ksh? ((baseline=LINENO+2)) trap '_Dbg_debug_trap_handler' DEBUG . $tmp/debug foo bar trap '' DEBUG +exit $Errors +) +Errors=$? caller() { integer .level=.sh.level .max=.sh.level-1 diff --git a/src/cmd/ksh93/tests/io.sh b/src/cmd/ksh93/tests/io.sh index d84491247..8b2721604 100755 --- a/src/cmd/ksh93/tests/io.sh +++ b/src/cmd/ksh93/tests/io.sh @@ -99,6 +99,7 @@ fi # 2004-11-25 ancient /dev/fd/N redirection bug fix got=$( + set +x { print -n 1 print -n 2 > ${FDFS[fdfs].dir}/2 @@ -338,16 +339,16 @@ read -n3 a </dev/null |read -n3 a +(print -n a; sleep .1; print -n bcde) 2>/dev/null |read -n3 a [[ $a == a ]] || err_exit 'read -n3 from pipe not working' if mkfifo $tmp/fifo 2> /dev/null -then (print -n a; sleep 2; print -n bcde) > $tmp/fifo & +then (print -n a; sleep .2; print -n bcde) > $tmp/fifo & { - read -u5 -n3 -t3 a || err_exit 'read -n3 from fifo timed out' - read -u5 -n1 -t3 b || err_exit 'read -n1 from fifo timed out' + read -u5 -n3 -t1 a || err_exit 'read -n3 from fifo timed out' + read -u5 -n1 -t1 b || err_exit 'read -n1 from fifo timed out' } 5< $tmp/fifo exp=a got=$a @@ -358,10 +359,10 @@ then (print -n a; sleep 2; print -n bcde) > $tmp/fifo & rm -f $tmp/fifo wait mkfifo $tmp/fifo 2> /dev/null - (print -n a; sleep 2; print -n bcde) > $tmp/fifo & + (print -n a; sleep .2; print -n bcde) > $tmp/fifo & { - read -u5 -N3 -t3 a || err_exit 'read -N3 from fifo timed out' - read -u5 -N1 -t3 b || err_exit 'read -N1 from fifo timed out' + read -u5 -N3 -t1 a || err_exit 'read -N3 from fifo timed out' + read -u5 -N1 -t1 b || err_exit 'read -N1 from fifo timed out' } 5< $tmp/fifo exp=abc got=$a @@ -373,16 +374,16 @@ then (print -n a; sleep 2; print -n bcde) > $tmp/fifo & fi ( print -n 'prompt1: ' - sleep .1 + sleep .01 print line2 - sleep .1 + sleep .01 print -n 'prompt2: ' - sleep .1 + sleep .01 ) | { - read -t2 -n 1000 line1 - read -t2 -n 1000 line2 - read -t2 -n 1000 line3 - read -t2 -n 1000 line4 + read -t1 -n 1000 line1 + read -t1 -n 1000 line2 + read -t1 -n 1000 line3 + read -t1 -n 1000 line4 } [[ $? == 0 ]] && err_exit 'should have timed out' [[ $line1 == 'prompt1: ' ]] || err_exit "line1 should be 'prompt1: '" @@ -410,7 +411,7 @@ do a=$1 shift 4 for ((i = 0; i < 2; i++)) do for lc_all in C $lc_utf8 - do g=$(LC_ALL=$lc_all $SHELL -c "{ print -n '$a'; sleep 0.2; print -n '$b'; sleep 0.2; } | { read ${o[i]} a; print -n \$a; read a; print -n \ \$a; }") + do g=$(LC_ALL=$lc_all $SHELL -c "{ print -n '$a'; sleep .02; print -n '$b'; sleep .02; } | { read ${o[i]} a; print -n \$a; read a; print -n \ \$a; }") [[ $g == "${e[i]}" ]] || err_exit "LC_ALL=$lc_all read ${o[i]} from pipe '$a $b' failed -- expected '${e[i]}', got '$g'" done done @@ -437,12 +438,14 @@ then export LC_ALL=$lc_utf8 fi fi -exec 3<&2 file=$tmp/file +( +: disabling xtrace so we can redirect stderr for this test +set +x redirect 5>$file 2>&5 print -u5 -f 'This is a test\n' print -u2 OK -exec 2<&3 +) exp=$'This is a test\nOK' got=$(< $file) [[ $got == $exp ]] || err_exit "output garbled when stderr is duped -- expected $(printf %q "$exp"), got $(printf %q "$got")" diff --git a/src/cmd/ksh93/tests/locale.sh b/src/cmd/ksh93/tests/locale.sh index c95635910..b43a5f2cb 100755 --- a/src/cmd/ksh93/tests/locale.sh +++ b/src/cmd/ksh93/tests/locale.sh @@ -200,11 +200,11 @@ got="$(&1) +got=$(set +x; LC_ALL=C.UTF-8 $SHELL -c $'\u[5929]=OK; print ${\u[5929]}' 2>&1) [[ $got == "$exp" ]] || err_exit "multibyte variable definition/expansion failed -- expected '$exp', got '$got'" -got=$(LC_ALL=C.UTF-8 $SHELL -c $'function \u[5929]\n{\nprint OK;\n}; \u[5929]' 2>&1) +got=$(set +x; LC_ALL=C.UTF-8 $SHELL -c $'function \u[5929]\n{\nprint OK;\n}; \u[5929]' 2>&1) [[ $got == "$exp" ]] || err_exit "multibyte ksh function definition/execution failed -- expected '$exp', got '$got'" -got=$(LC_ALL=C.UTF-8 $SHELL -c $'\u[5929]()\n{\nprint OK;\n}; \u[5929]' 2>&1) +got=$(set +x; LC_ALL=C.UTF-8 $SHELL -c $'\u[5929]()\n{\nprint OK;\n}; \u[5929]' 2>&1) [[ $got == "$exp" ]] || err_exit "multibyte posix function definition/execution failed -- expected '$exp', got '$got'" # this locale is supported by ast on all platforms diff --git a/src/cmd/ksh93/tests/options.sh b/src/cmd/ksh93/tests/options.sh index a8abb2d86..95a467530 100755 --- a/src/cmd/ksh93/tests/options.sh +++ b/src/cmd/ksh93/tests/options.sh @@ -73,7 +73,7 @@ then got=$(printf %q "$got") err_exit "\$ENV file &>/dev/null does not redirect stdout -- expected '', got $got" fi - got=$($SHELL -E -c : 2>&1 >/dev/null) + got=$(set +x; $SHELL -E -c : 2>&1 >/dev/null) if [[ $got != *nonstandard* || $got == *$'\n'* ]] then got=$(printf %q "$got") @@ -151,11 +151,11 @@ then else [[ $(print env_hit | HOME=$tmp $SHELL 2>&1) == "OK" ]] && err_exit 'nointeractive shell reads $HOME/.kshrc file' - [[ $(print env_hit | HOME=$tmp $SHELL -E 2>&1) == "OK" ]] || + [[ $(set +x; print env_hit | HOME=$tmp $SHELL -E 2>&1) == "OK" ]] || err_exit '-E ignores $HOME/.kshrc file' [[ $(print env_hit | HOME=$tmp $SHELL +E 2>&1) == "OK" ]] && err_exit '+E reads $HOME/.kshrc file' - [[ $(print env_hit | HOME=$tmp $SHELL --rc 2>&1) == "OK" ]] || + [[ $(set +x; print env_hit | HOME=$tmp $SHELL --rc 2>&1) == "OK" ]] || err_exit '--rc ignores $HOME/.kshrc file' [[ $(print env_hit | HOME=$tmp $SHELL --norc 2>&1) == "OK" ]] && err_exit '--norc reads $HOME/.kshrc file' @@ -368,7 +368,7 @@ pipeline=( ( nopipefail=1 pipefail=1 command='true|true|false' ) ( nopipefail=1 pipefail=1 command='false|false|false' ) ( nopipefail=0 pipefail=0 command='true|true|true' ) - ( nopipefail=0 pipefail=0 command='print hi|(sleep 1;"$bincat")>/dev/null' ) + ( nopipefail=0 pipefail=0 command='print hi|(sleep .1;"$bincat")>/dev/null' ) ) set --nopipefail for ((i = 0; i < ${#pipeline[@]}; i++ )) @@ -443,10 +443,10 @@ export ENV= PS1="(:$$:)" histfile=$tmp/history exp=$(HISTFILE=$histfile $SHELL -c $'function foo\n{\ncat\n}\ntype foo') for var in HISTSIZE HISTFILE -do got=$( ( HISTFILE=$histfile $SHELL +E -ic $'unset '$var$'\nfunction foo\n{\ncat\n}\ntype foo\nexit' ) 2>&1 ) +do got=$( set +x; ( HISTFILE=$histfile $SHELL +E -ic $'unset '$var$'\nfunction foo\n{\ncat\n}\ntype foo\nexit' ) 2>&1 ) got=${got##*"$PS1"} [[ $got == "$exp" ]] || err_exit "function definition inside (...) with $var unset fails -- got '$got', expected '$exp'" - got=$( { HISTFILE=$histfile $SHELL +E -ic $'unset '$var$'\nfunction foo\n{\ncat\n}\ntype foo\nexit' ;} 2>&1 ) + got=$( set +x; { HISTFILE=$histfile $SHELL +E -ic $'unset '$var$'\nfunction foo\n{\ncat\n}\ntype foo\nexit' ;} 2>&1 ) got=${got##*"$PS1"} [[ $got == "$exp" ]] || err_exit "function definition inside {...;} with $var unset fails -- got '$got', expected '$exp'" done diff --git a/src/cmd/ksh93/tests/path.sh b/src/cmd/ksh93/tests/path.sh index 8c37e3a71..70d0b0cad 100755 --- a/src/cmd/ksh93/tests/path.sh +++ b/src/cmd/ksh93/tests/path.sh @@ -342,7 +342,7 @@ function foo # whence -q bug fix $SHELL -c 'whence -q cat' & pid=$! -sleep 3 +sleep .1 kill $! 2> /dev/null && err_exit 'whence -q appears to be hung' FPATH=$PWD diff --git a/src/cmd/ksh93/tests/shtests b/src/cmd/ksh93/tests/shtests index 138be48f0..fdbcccf96 100755 --- a/src/cmd/ksh93/tests/shtests +++ b/src/cmd/ksh93/tests/shtests @@ -207,7 +207,7 @@ done shift $OPTIND-1 if (( debug )) || [[ $trace ]] -then export PS4=':$LINENO: ' +then export PS4='+ [${SECONDS:+${SECONDS%????}s|}${.sh.subshell:+S${.sh.subshell},}${.sh.file:+${.sh.file#${.sh.file%/*/*}/},}${.sh.fun:+${.sh.fun},}${LINENO:+L$LINENO,}e$?] ' if (( debug )) then set -x fi diff --git a/src/cmd/ksh93/tests/sigchld.sh b/src/cmd/ksh93/tests/sigchld.sh index 3b352652c..30ba7637d 100755 --- a/src/cmd/ksh93/tests/sigchld.sh +++ b/src/cmd/ksh93/tests/sigchld.sh @@ -26,7 +26,7 @@ function err_exit alias err_exit='err_exit $LINENO' -float DELAY=${1:-0.2} +float DELAY=${1:-0.02} integer FOREGROUND=10 BACKGROUND=2 Errors=0 tmp=$( @@ -82,7 +82,7 @@ then integer running=0 maxrunning=0 trap "((running--))" CHLD for ((i=0; i maxrunning)) then ((maxrunning=running)) fi @@ -101,13 +101,13 @@ then unset proc[\$!] " CHLD - { sleep 3; print a; exit 1; } & + { sleep .3; print a; exit 1; } & proc[$!]=( name=a status=1 ) - { sleep 2; print b; exit 2; } & + { sleep .2; print b; exit 2; } & proc[$!]=( name=b status=2 ) - { sleep 1; print c; exit 3; } & + { sleep .1; print c; exit 3; } & proc[$!]=( name=c status=3 ) while (( ${#proc[@]} )) @@ -120,8 +120,8 @@ then fi { -got=$( ( sleep 1;print $'\n') | $SHELL -c 'function handler { : ;} - trap handler CHLD; sleep .3 & IFS= read; print good') +got=$( ( sleep .1;print $'\n') | $SHELL -c 'function handler { : ;} + trap handler CHLD; sleep .03 & IFS= read; print good') } 2> /dev/null [[ $got == good ]] || err_exit 'SIGCLD handler effects read behavior' @@ -129,9 +129,9 @@ set -- $( ( $SHELL -xc $' trap \'wait $!; print $! $?\' CHLD - { sleep 0.1; exit 9; } & + { sleep 0.01; exit 9; } & print $! - sleep 0.5 + sleep 0.05 ' ) 2>/dev/null; print $? ) @@ -155,11 +155,11 @@ done (( d==2000 )) || err_exit "trap '' CHLD causes side effects d=$d" trap - CHLD -x=$($SHELL 2> /dev/null -ic '/dev/null/notfound; sleep .5 & sleep 1;jobs') +x=$($SHELL 2> /dev/null -ic '/dev/null/notfound; sleep .05 & sleep .1;jobs') [[ $x == *Done* ]] || err_exit 'SIGCHLD blocked after notfound' -x=$($SHELL 2> /dev/null -ic 'kill -0 12345678901234567876; sleep .5 & sleep 1;jobs') +x=$($SHELL 2> /dev/null -ic 'kill -0 12345678901234567876; sleep .05 & sleep .1;jobs') [[ $x == *Done* ]] || err_exit 'SIGCHLD blocked after error message' -print 'set -o monitor;sleep .5 & sleep 1;jobs' > $tmp/foobar +print 'set -o monitor;sleep .05 & sleep .1;jobs' > $tmp/foobar chmod +x $tmp/foobar x=$($SHELL -c "echo | $tmp/foobar") [[ $x == *Done* ]] || err_exit 'SIGCHLD blocked for script at end of pipeline' diff --git a/src/cmd/ksh93/tests/signal.sh b/src/cmd/ksh93/tests/signal.sh index ae6021c12..260ef7918 100755 --- a/src/cmd/ksh93/tests/signal.sh +++ b/src/cmd/ksh93/tests/signal.sh @@ -56,7 +56,8 @@ do if ! n=$(kill -l $s 2>/dev/null) done ( - set --pipefail + : disabling xtrace for this test + set +x --pipefail { $SHELL 2> out2 <<- \EOF g=false @@ -67,6 +68,7 @@ done EOF } | head > /dev/null (( $? == 0)) || err_exit "SIGPIPE with wrong error code $?" + # The below is kind of bogus as the err_exit from a bg job is never counterd. But see extra check below. [[ $(/dev/null then kill $spy 2>/dev/null -else err_exit "pipe with --pipefail PIPE trap hangs" +else err_exit "pipe with --pipefail PIPE trap hangs or produced an error" fi wait rm -f out2 diff --git a/src/cmd/ksh93/tests/subshell.sh b/src/cmd/ksh93/tests/subshell.sh index a393b8db5..37da42fc4 100755 --- a/src/cmd/ksh93/tests/subshell.sh +++ b/src/cmd/ksh93/tests/subshell.sh @@ -19,14 +19,15 @@ ######################################################################## function err_exit { - print -u$Error_fd -n "\t" - print -u$Error_fd -r ${Command}[$1]: "${@:2}" + print -u2 -n "\t" + print -u2 -r ${Command}[$1]: "${@:2}" (( Errors+=1 )) } alias err_exit='err_exit $LINENO' Command=${0##*/} -integer Errors=0 Error_fd=2 +integer Errors=0 +typeset -F SECONDS # for fractional seconds in PS4 tmp=$( d=${TMPDIR:-/tmp}/ksh93.subshell.$$.${RANDOM:-0} @@ -40,6 +41,13 @@ trap 'cd / && rm -rf "$tmp"' EXIT builtin getconf bincat=$(PATH=$(getconf PATH) whence -p cat) binecho=$(PATH=$(getconf PATH) whence -p echo) +# make an external 'sleep' command that supports fractional seconds +binsleep=$tmp/.sleep.sh # hide to exclude from simple wildcard expansion +cat >"$binsleep" <&2 2>/dev/null" - TEST_notfound=notfound while whence $TEST_notfound >/dev/null 2>&1 do TEST_notfound=notfound-$RANDOM @@ -220,7 +225,7 @@ do for TEST_exec in '' 'exec' sleep 2 kill -KILL $$ } & - '"$TEST_test"' + { '"$TEST_test"'; } 2>/dev/null kill $! print ok ') @@ -394,7 +399,7 @@ do cat $tmp/buf $tmp/buf > $tmp/tmp wait $m h=$? kill -9 $k - wait $k + { wait $k; } 2>/dev/null # suppress 'wait: $pid: Killed' got=$(<$tmp/out) if [[ ! $got ]] && (( h )) then got=HUNG @@ -427,7 +432,7 @@ done # specifics -- there's more? { - cmd='{ exec 5>/dev/null; print "$(eval ls -d . 2>&1 1>&5)"; } >$tmp/out &' + cmd='{ exec 5>/dev/null; print "$(set +x; eval ls -d . 2>&1 1>&5)"; } >$tmp/out &' eval $cmd m=$! { sleep 4; kill -9 $m; } & @@ -447,13 +452,11 @@ then err_exit "eval '$cmd' failed -- expected '$exp', got '$got'" fi float t1=$SECONDS -sleep=$(whence -p sleep) -if [[ $sleep ]] -then - $SHELL -c "( $sleep 5 /dev/null 2>&1 & );exit 0" | cat - (( (SECONDS-t1) > 4 )) && err_exit '/bin/sleep& in subshell hanging' - ((t1=SECONDS)) -fi + +$SHELL -c '( "$1" 5 /dev/null 2>&1 & );exit 0' x "$binsleep" | cat +(( (SECONDS-t1) > 4 )) && err_exit '/bin/sleep& in subshell hanging' +((t1=SECONDS)) + $SHELL -c '( sleep 5 /dev/null 2>&1 & );exit 0' | cat (( (SECONDS-t1) > 4 )) && err_exit 'sleep& in subshell hanging' @@ -483,7 +486,7 @@ $SHELL -c 'sleep 20 & pid=$!; { x=$( ( seq 60000 ) );kill -9 $pid;}&;wait $pid' (.sh.foo=foobar) [[ ${.sh.foo} == foobar ]] && err_exit '.sh subvariables in subshells remain set' -[[ $($SHELL -c 'print 1 | : "$("$bincat" <("$bincat"))"') ]] && err_exit 'process substitution not working correctly in subshells' +[[ $(export bincat; $SHELL -c 'print 1 | : "$("$bincat" <("$bincat"))"') ]] && err_exit 'process substitution not working correctly in subshells' # config hang bug integer i @@ -542,7 +545,7 @@ $SHELL <<- \EOF (( ${#out} == 96011 )) || err_exit "\${#out} is ${#out} should be 96011" EOF } & pid=$! -$SHELL -c "{ sleep 4 && kill $pid ;}" 2> /dev/null +$SHELL -c "{ sleep .4 && kill $pid ;}" 2> /dev/null (( $? == 0 )) && err_exit 'process has hung' { @@ -613,7 +616,7 @@ $SHELL <<- \EOF wc=$(whence wc) head=$(whence head) print > /dev/null $( ( $head -c 1 /dev/zero | ( $wc -c) 3>&1 ) 3>&1) & pid=$! - sleep 2 + sleep .2 kill -9 $! 2> /dev/null && err_exit '/dev/zero in command substitution hangs' wait $! EOF @@ -685,13 +688,13 @@ expect=$'sub3\nok_nonexistent\nsub2\nsub1\nmainfunction' alias al="echo 'mainalias'" -(unalias al; alias al >/dev/null) && err_exit 'alias fails to be unset in subshell' +(unalias al; alias al 2>/dev/null) && err_exit 'alias fails to be unset in subshell' -v=$(unalias al; alias al >/dev/null) && err_exit 'alias fails to be unset in comsub' +v=$(unalias al; alias al 2>/dev/null) && err_exit 'alias fails to be unset in comsub' [[ $(eval 'al') == 'mainalias' ]] || err_exit 'main alias fails to survive unset in subshell(s)' -v=${ eval 'al'; unalias al 2>&1; } && [[ $v == 'mainalias' ]] && ! alias al >/dev/null \ +v=${ eval 'al'; unalias al 2>&1; } && [[ $v == 'mainalias' ]] && ! alias al 2>/dev/null \ || err_exit 'main shell alias wrongly survives unset within ${ ...; }' # ...alias can be redefined in subshell diff --git a/src/cmd/ksh93/tests/substring.sh b/src/cmd/ksh93/tests/substring.sh index d33b7f9a8..b74c18143 100755 --- a/src/cmd/ksh93/tests/substring.sh +++ b/src/cmd/ksh93/tests/substring.sh @@ -26,7 +26,10 @@ function err_exit alias err_exit='err_exit $LINENO' Command=${0##*/} -integer Errors=0 j=4 +integer Errors=0 +tmpPS4='+ [temp_PS4|L$LINENO|e$?] ' # used to avoid interference to ${.sh.match} from $PS4 set by shtests + +integer j=4 base=/home/dgk/foo//bar string1=$base/abcabcabc if [[ ${string1:0} != "$string1" ]] @@ -261,6 +264,9 @@ foo='foo+bar+' [[ $(print -r -- ${foo//+/"|"}) != 'foo|bar|' ]] && err_exit '${foobar//+/"|"}' [[ $(print -r -- "${foo//+/'|'}") != 'foo|bar|' ]] && err_exit '"${foobar//+/'"'|'"'}"' [[ $(print -r -- "${foo//+/"|"}") != 'foo|bar|' ]] && err_exit '"${foobar//+/"|"}"' + +( +PS4=$tmpPS4 unset x x=abcedfg : ${x%@(d)f@(g)} @@ -270,6 +276,10 @@ x=abcedfg x=abcedddfg : ${x%%+(d)f@(g)} [[ ${.sh.match[1]} == ddd ]] || err_exit '.sh.match[1] not ddd' +exit $Errors +) +Errors=$? + unset a b a='\[abc @(*) def\]' b='[abc 123 def]' @@ -296,10 +306,16 @@ integer i for((i=0; i < ${#string}; i++)) do pattern+='@(?)' done + +( +PS4=$tmpPS4 [[ $(string=$string $SHELL -c ": \${string/$pattern/}; print \${.sh.match[26]}") == Z ]] || err_exit -u2 'sh.match[26] not Z' : ${string/$pattern/} (( ${#.sh.match[@]} == 53 )) || err_exit '.sh.match has wrong number of elements' [[ ${.sh.match[@]:2:4} == 'B C D E' ]] || err_exit '${.sh.match[@]:2:4} incorrect' +exit $Errors +) +Errors=$? D=$';' E=$'\\\\' Q=$'"' S=$'\'' M='nested pattern substitution failed' @@ -497,7 +513,7 @@ pattern=00 var=100 [[ $( print $(( ${var%%00} )) ) == 1 ]] || err_exit "arithmetic with embedded patterns fails" [[ $( print $(( ${var%%$pattern} )) ) == 1 ]] || err_exit "arithmetic with embedded pattern variables fails" -if [[ ax == @(a)* ]] && [[ ${.sh.match[1]:0:${#.sh.match[1]}} != a ]] +if (PS4=$tmpPS4; [[ ax == @(a)* ]] && [[ ${.sh.match[1]:0:${#.sh.match[1]}} != a ]]) then err_exit '${.sh.match[1]:1:${#.sh.match[1]}} not expanding correctly' fi @@ -586,6 +602,9 @@ got=$($SHELL -c 'A=""; B="B"; for I in ${A[@]} ${B[@]}; do echo "\"$I\""; done') A='|' [[ $A == $A ]] || err_exit 'With A="|", [[ $A == $A ]] does not match' +( +PS4=$tmpPS4 + x="111 222 333 444 555 666" [[ $x == ~(E)(...).(...).(...) ]] [[ -v .sh.match[0] ]] || err_exit '[[ -v .sh.match[0] ]] should be true' @@ -597,6 +616,10 @@ x="foo bar" dummy=${x/~(E)(*)/} [[ ${ print -v .sh.match;} ]] && err_exit 'print -v should show .sh.match empty when there are no matches' +exit $Errors +) +Errors=$? + if $SHELL -c 'set 1 2 3 4 5 6 7 8 9 10 11 12; : ${##[0-9]}' 2>/dev/null then set 1 2 3 4 5 6 7 8 9 10 11 12 [[ ${##[0-9]} == 2 ]] || err_exit '${##[0-9]} should be 2 with $#==12' @@ -614,16 +637,21 @@ fi function foo { - typeset x="123 456 789 abc" + typeset PS4=$tmpPS4 x="123 456 789 abc" typeset dummy="${x/~(E-g)([[:digit:]][[:digit:]])((X)|([[:digit:]]))([[:blank:]])/_}" exp=$'(\n\t[0]=\'123 \'\n\t[1]=12\n\t[2]=3\n\t[4]=3\n\t[5]=\' \'\n)' [[ $(print -v .sh.match) == "$exp" ]] || err_exit '.sh.match not correct with alternations' } foo +( +PS4=$tmpPS4 x="a 1 b" d=${x/~(E)(([[:digit:]])[[:space:]]*|([[:alpha:]]))/X} [[ $(print -v .sh.match) == $'(\n\t[0]=a\n\t[1]=a\n\t[3]=a\n)' ]] || err_exit '.sh.match not sparse' +exit $Errors +) +Errors=$? unset v typeset -a arr=( 0 1 2 3 4 ) @@ -654,11 +682,16 @@ do err_exit "\${@:0:-1} should not generate ${v:-empty_string}" break done +( +PS4=$tmpPS4 unset v d v=abbbc d="${v/~(E)b{2,4}/dummy}" [[ ${.sh.match} == bbb ]] || err_exit '.sh.match wrong after ${s/~(E)b{2,4}/dummy}' [[ $d == adummyc ]] || err_exit '${s/~(E)b{2,4}/dummy} not working' +exit $Errors +) +Errors=$? - +# ====== exit $((Errors<125?Errors:125)) diff --git a/src/cmd/ksh93/tests/variables.sh b/src/cmd/ksh93/tests/variables.sh index cd7aaa364..ecf0347d2 100755 --- a/src/cmd/ksh93/tests/variables.sh +++ b/src/cmd/ksh93/tests/variables.sh @@ -47,9 +47,10 @@ if (( RANDOM==RANDOM || $RANDOM==$RANDOM )) then err_exit RANDOM variable not working fi # SECONDS -sleep 3 -if (( SECONDS < 2 )) -then err_exit SECONDS variable not working +let SECONDS=0.0 +sleep .001 +if (( SECONDS < .001 )) +then err_exit "either 'sleep' or \$SECONDS not working" fi # _ set abc def @@ -217,6 +218,7 @@ x error" then err_exit "\${#$i} not correct" fi done +kill -s 0 $! || err_exit '$! does not point to latest asynchronous process' kill $! unset x CDPATH=/ @@ -433,12 +435,12 @@ fi function foo { typeset SECONDS=0 - sleep 1.5 + sleep .002 print $SECONDS } x=$(foo) -(( x >1 && x < 2 )) +(( x >.001 && x < .01 )) ' } 2> /dev/null || err_exit 'SECONDS not working in function' cat > $tmp/script <<-\!