mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Solaris, Illumos distributions, and NetBSD need LDFLAGS set to link explicitly to libm, otherwise, due to as-yet unknown reasons, the src/lib/libdll/features/dll fails to write a valid header file and compilation fails due to unknown identifiers such as Dllscan_t. This commit adds the flag on those systems. NixOS is a Linux distro that uses very different paths from the usual Unix conventions (though it's POSIX compliant), and the regression tests still needed a lot of tweaks to be compatible. src/cmd/INIT/package.sh, bin/package: - On SunOS (Solaris and illumos distros) and NetBSD, add '-lm' to LDFLAGS before compiling. src/cmd/INIT/mamprobe.sh, bin/mamprobe, src/cmd/INIT/execrate.sh, bin/execrate: - Instead of only in /bin, /usr/bin, /sbin and /usr/sbin, search utilities in the path given by the OS 'getconf PATH', and use the user's original $PATH as a fallback. src/cmd/ksh93/tests/*.sh: - Miscellaneous portability fixes, mainly elimination of unportable hardcoded paths to commands. - basic.sh: Remove test for 'time' keyword millisecond precision. It was racy and could fail depending on system and system load.
439 lines
10 KiB
Text
Executable file
439 lines
10 KiB
Text
Executable file
: ksh regression test harness :
|
|
|
|
USAGE_LICENSE="[-author?David Korn <dgk@research.att.com>][-author?Glenn Fowler <gsf@research.att.com>][-copyright?Copyright (c) 2000-2012 AT&T Intellectual Property][-license?http://www.eclipse.org/org/documents/epl-v10.html]"
|
|
|
|
command=shtests
|
|
|
|
setslocale='*@(locale).sh'
|
|
timesensitive='*@(options|sigchld|subshell).sh'
|
|
valgrindflags='--xml=yes --log-file=/dev/null --track-origins=yes --read-var-info=yes'
|
|
|
|
USAGE=$'
|
|
[-s8?
|
|
@(#)$Id: shtests (AT&T Research/ksh93) 2020-07-04 $
|
|
]
|
|
'$USAGE_LICENSE$'
|
|
[+NAME?shtests - ksh regression test harness]
|
|
[+DESCRIPTION?\bshtests\b is the \bksh\b(1) regression test harness for
|
|
\b$SHELL\b or \bksh\b if \bSHELL\b is not defined and exported. If
|
|
none of the \b--posix --utf8 --compile\b options are specified then
|
|
all three are enabled.]
|
|
[+INPUT FILES?\bshtests\b regression test files are shell scripts that
|
|
run in an environment controlled by \bshtests\b. An identification
|
|
message is printed before and after each test on the standard output.
|
|
The default environment settings are:]
|
|
{
|
|
[+unset LANG]
|
|
[+unset LC_ALL]
|
|
[+LC_NUMERIC=C?\b.\b radix point assumed by all test scripts.]
|
|
[+VMALLOC_OPTIONS=abort?\bvmalloc\b(1) arena checking enabled
|
|
with \babort(2)\b on error.]
|
|
}
|
|
[c:compile?Run test scripts using \bshcomp\b(1).]
|
|
[d:debug?Enable \bshtests\b execution trace.]
|
|
[k:keep?Keep temporary files after test run; shtests will report the location.]
|
|
[l:locale?Disable \b--utf8\b and run the \b--posix\b and \b--compile\b
|
|
tests, if enabled, in the locale of the caller. This may cause invalid
|
|
regressions, especially for locales where \b.\b is not the radix
|
|
point.]
|
|
[p:posix?Run the test scripts in the posix/C locale.]
|
|
[t!:time?Include the current date/time in the test identification
|
|
messages.]
|
|
[u:utf8?Run the test scripts in the ast-specific C.UTF-8 locale.]
|
|
[v!:vmalloc_options?Run tests with \bVMALLOC_OPTIONS=abort\b. Test
|
|
script names matching \b'$timesensitive$'\b are run with
|
|
\bVMALLOC_OPTIONS\b unset.]
|
|
[V:valgrind?Set \b--novmalloc_options\b and run the test scripts with
|
|
\bvalgrind\b(1) on \bksh\b. If \b$SHELL-g\b exists and is executable,
|
|
then it is used instead of \b$SHELL\b.]
|
|
[x:trace?Enable script execution trace.]
|
|
|
|
[ test.sh ... ] [ name=value ... ]
|
|
|
|
[+SEE ALSO?\bksh\b(1), \bregress\b(1), \brt\b(1)]
|
|
'
|
|
|
|
function usage
|
|
{
|
|
OPTIND=0
|
|
getopts -a $command "$USAGE" OPT '--??long'
|
|
exit 2
|
|
}
|
|
|
|
function valxml
|
|
{
|
|
typeset state=INIT data dir file fn line what
|
|
integer errors=0
|
|
|
|
#print === $1 ===; cat $1; print === ===
|
|
while read data
|
|
do case $state in
|
|
INIT) case $data in
|
|
'<error>')
|
|
state=ERROR
|
|
;;
|
|
esac
|
|
;;
|
|
ERROR) case $data in
|
|
'<kind>'Leak*'</kind>')
|
|
state=SKIP
|
|
;;
|
|
'<kind>'*'</kind>')
|
|
state=KEEP
|
|
what=UNKNOWN
|
|
;;
|
|
esac
|
|
;;
|
|
FRAME) case $data in
|
|
'<dir>'*'</dir>')
|
|
dir=${data#'<dir>'}
|
|
dir=${dir%'</dir>'}
|
|
;;
|
|
'<file>'*'</file>')
|
|
file=${data#'<file>'}
|
|
file=${file%'</file>'}
|
|
;;
|
|
'<fn>'*'</fn>')
|
|
fn=${data#'<fn>'}
|
|
fn=${fn%'</fn>'}
|
|
;;
|
|
'<line>'*'</line>')
|
|
line=${data#'<line>'}
|
|
line=${line%'</line>'}
|
|
;;
|
|
'</frame>')
|
|
[[ $dir ]] && dir+=/
|
|
dir+=$file
|
|
[[ $dir ]] && dir+=:
|
|
[[ $line ]] && dir+=$line:
|
|
[[ $fn ]] && dir+=$fn
|
|
[[ $dir ]] && echo $'\t '$dir
|
|
state=KEEP
|
|
;;
|
|
esac
|
|
;;
|
|
KEEP) case $data in
|
|
'<auxwhat>'*'</auxwhat>')
|
|
what=${data#'<auxwhat>'}
|
|
what=${what%'</auxwhat>'}
|
|
echo $'\t'"$what"
|
|
;;
|
|
'<frame>')
|
|
state=FRAME
|
|
dir=
|
|
file=
|
|
fn=
|
|
line=
|
|
;;
|
|
'<what>Syscall param mount(type) points to unaddressable byte(s)</what>')
|
|
state=SKIP
|
|
;;
|
|
'<what>'*'</what>')
|
|
(( errors++ ))
|
|
what=${data#'<what>'}
|
|
what=${what%'</what>'}
|
|
echo $'\n\t'"$what"
|
|
;;
|
|
'<xwhat>')
|
|
state=WHAT
|
|
;;
|
|
'</error>')
|
|
state=INIT
|
|
;;
|
|
esac
|
|
;;
|
|
SKIP) case $data in
|
|
'</error>')
|
|
state=INIT
|
|
;;
|
|
esac
|
|
;;
|
|
WHAT) case $data in
|
|
'<text>'*'</text>')
|
|
(( errors++ ))
|
|
what=${data#'<text>'}
|
|
what=${what%'</text>'}
|
|
echo $'\n\t'"$what"
|
|
;;
|
|
'</xwhat>')
|
|
state=KEEP
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
done < "$1"
|
|
(( errors )) && echo
|
|
return $errors
|
|
}
|
|
|
|
unset DISPLAY FIGNORE HISTFILE
|
|
export ENV=/./dev/null
|
|
trap + PIPE # unadvertized -- set SIGPIPE to SIG_DFL #
|
|
|
|
integer compile=-1 posix=-1 utf8=-1
|
|
integer debug=0 keep=0 locale=0 time=1
|
|
typeset vmalloc_options=abort trace= valgrind=
|
|
vmalloc_options= #XXX# until multi-region vmalloc trace fixed #XXX#
|
|
|
|
while getopts -a $command "$USAGE" OPT
|
|
do case $OPT in
|
|
c) if (( $OPTARG ))
|
|
then compile=2
|
|
else compile=0
|
|
fi
|
|
;;
|
|
d) debug=$OPTARG
|
|
;;
|
|
k) keep=$OPTARG
|
|
;;
|
|
l) locale=$OPTARG
|
|
;;
|
|
p) posix=$OPTARG
|
|
;;
|
|
t) time=$OPTARG
|
|
;;
|
|
u) utf8=$OPTARG
|
|
;;
|
|
v) if (( OPTARG ))
|
|
then vmalloc_options=abort
|
|
else vmalloc_options=
|
|
fi
|
|
;;
|
|
V) valgrind="${VALGRIND:-valgrind} ${VALGRINDFLAGS:-$valgrindflags}"
|
|
vmalloc_options=
|
|
;;
|
|
x) trace=-x
|
|
;;
|
|
*) usage
|
|
;;
|
|
esac
|
|
done
|
|
shift $OPTIND-1
|
|
|
|
if (( debug )) || [[ $trace ]]
|
|
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
|
|
fi
|
|
|
|
while [[ $1 == *=* ]]
|
|
do eval export "$1"
|
|
shift
|
|
done
|
|
|
|
if (( compile <= 0 && posix <= 0 && utf8 <= 0 ))
|
|
then (( compile )) && compile=1
|
|
(( posix )) && posix=1
|
|
(( utf8 )) && utf8=1
|
|
fi
|
|
(( compile < 0 )) && compile=0
|
|
(( posix < 0 )) && posix=0
|
|
(( utf8 < 0 )) && utf8=0
|
|
if (( locale ))
|
|
then utf8=0
|
|
if [[ $LC_ALL ]]
|
|
then export LANG=$LC_ALL
|
|
fi
|
|
else unset LANG LC_ALL
|
|
export LC_NUMERIC=C
|
|
fi
|
|
if [[ $VMALLOC_OPTIONS ]]
|
|
then vmalloc_options=$VMALLOC_OPTIONS
|
|
else VMALLOC_OPTIONS=$vmalloc_options
|
|
fi
|
|
[[ $VMALLOC_OPTIONS ]] || timesensitive=.
|
|
export PATH PWD SHCOMP SHELL VMALLOC_OPTIONS
|
|
PWD=$(pwd)
|
|
SHELL=${SHELL-ksh}
|
|
case $0 in
|
|
/*) d=$(dirname $0);;
|
|
*/*) d=$PWD/$(dirname $0);;
|
|
*) d=$PWD;;
|
|
esac
|
|
case $SHELL in
|
|
/*) ;;
|
|
*/*) SHELL=$d/$SHELL;;
|
|
*) SHELL=$(whence $SHELL);;
|
|
esac
|
|
PATH=$(
|
|
PATH=/run/current-system/sw/bin:/usr/xpg7/bin:/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin:$PATH
|
|
getconf PATH 2>/dev/null || { builtin getconf 2>/dev/null && getconf PATH; }
|
|
) || PATH=/bin:/usr/bin
|
|
if [[ -d /usr/ucb ]]
|
|
then PATH=$PATH:/usr/ucb
|
|
fi
|
|
PATH=$PATH:$d
|
|
if [[ $INSTALLROOT && -r $INSTALLROOT/bin/.paths ]]
|
|
then PATH=$INSTALLROOT/bin:$PATH
|
|
fi
|
|
if [[ ${SHELL%/*} != $INSTALLROOT/bin ]]
|
|
then PATH=${SHELL%/*}:$PATH
|
|
fi
|
|
if [[ ! $SHCOMP ]]
|
|
then s=${SHELL:##*sh}
|
|
s=${SHELL:%/*}/shcomp$s
|
|
if [[ -x $s ]]
|
|
then SHCOMP=$s
|
|
elif [[ -x ${s%-g} ]]
|
|
then SHCOMP=${s%-g}
|
|
else SHCOMP=shcomp
|
|
fi
|
|
fi
|
|
|
|
tmp=$(
|
|
d=${TMPDIR:-/tmp}/ksh93.shtests.$$.${RANDOM:-0}
|
|
mkdir -m700 -- "$d" && CDPATH= cd -P -- "$d" && pwd
|
|
) || {
|
|
echo 'mkdir failed' >&2
|
|
exit 1
|
|
}
|
|
if (( keep ))
|
|
then trap 'printf "\nTemporary files left in: %s\n" "$tmp"' EXIT
|
|
else trap 'cd / && rm -rf "$tmp"' EXIT
|
|
fi
|
|
|
|
if (( compile ))
|
|
then if whence $SHCOMP > /dev/null
|
|
then :
|
|
elif (( compile > 1 ))
|
|
then echo $0: --compile: $SHCOMP not found >&2
|
|
exit 1
|
|
else compile=0
|
|
fi
|
|
fi
|
|
if [[ $valgrind ]]
|
|
then if [[ -x $SHELL-g ]]
|
|
then SHELL=$SHELL-g
|
|
fi
|
|
valxml=$tmp/valgrind.xml
|
|
valgrind+=" --xml-file=$valxml"
|
|
fi
|
|
typeset -A tests
|
|
typeset -i total_e=0
|
|
for i in ${*-*.sh}
|
|
do [[ $i == *.sh ]] || i+='.sh'
|
|
if [[ ! -r $i ]]
|
|
then echo $0: $i: not found >&2
|
|
(( ++total_e ))
|
|
continue
|
|
fi
|
|
t=$(grep -c err_exit $i)
|
|
if (( t > 2 ))
|
|
then (( t = t - 2 ))
|
|
fi
|
|
tests[$i]=$t
|
|
T=test
|
|
if (( t != 1 ))
|
|
then T=${T}s
|
|
fi
|
|
u=${i##*/}
|
|
u=${u%.sh}
|
|
if [[ $i == $timesensitive ]]
|
|
then VMALLOC_OPTIONS=
|
|
fi
|
|
if (( posix || utf8 ))
|
|
then locales=
|
|
(( posix )) && locales+=" ${LANG:-C}"
|
|
[[ $utf8 == 0 || $i == $setslocale ]] || locales+=" C.UTF-8"
|
|
for lang in $locales
|
|
do o=$u
|
|
tmp_s=$tmp/$u.$lang
|
|
mkdir -m700 "$tmp_s" || exit
|
|
if [[ $lang == C ]]
|
|
then lang=
|
|
else o="$o($lang)"
|
|
lang=LANG=$lang
|
|
fi
|
|
echo test $o begins ${time:+"at $(date +%Y-%m-%d+%H:%M:%S)"}
|
|
(
|
|
export ${lang:+"$lang"} "tmp=$tmp_s"
|
|
$valgrind $SHELL $trace $i
|
|
)
|
|
e=$?
|
|
if (( !keep ))
|
|
then rm -rf "$tmp_s"
|
|
fi
|
|
if [[ $valgrind ]]
|
|
then valxml $valxml
|
|
(( e += $? ))
|
|
fi
|
|
if (( e > 128 && ++total_e ))
|
|
then E="(killed by SIG$(kill -l "$e"))"
|
|
elif (( e == 1 && ++total_e ))
|
|
then E="1 error"
|
|
else E="$e errors"
|
|
(( total_e += e ))
|
|
fi
|
|
if (( e == 0 ))
|
|
then echo test $o passed ${time:+"at $(date +%Y-%m-%d+%H:%M:%S)"} "[ $t $T $E ]"
|
|
else echo test $o failed ${time:+"at $(date +%Y-%m-%d+%H:%M:%S)"} with exit code $e "[ $t $T $E ]"
|
|
fi
|
|
case $E in
|
|
*INT\)) kill -s INT $$ ;; # if test was ^C'd, don't keep going but pass down SIGINT
|
|
esac
|
|
done
|
|
fi
|
|
if (( compile ))
|
|
then c=$tmp/shcomp-$u.ksh
|
|
o="$u(shcomp)"
|
|
echo test $o begins ${time:+"at $(date +%Y-%m-%d+%H:%M:%S)"}
|
|
tmp_s=$tmp/$u.shcomp
|
|
mkdir -m700 "$tmp_s" || exit
|
|
if $SHCOMP $i > $c
|
|
then if tmp=$tmp_s $valgrind $SHELL $trace $c
|
|
then echo test $o passed ${time:+"at $(date +%Y-%m-%d+%H:%M:%S)"} "[ $t $T 0 errors ]"
|
|
else e=$?
|
|
if (( e > 128 && ++total_e ))
|
|
then E="(killed by SIG$(kill -l "$e"))"
|
|
elif (( e == 1 && ++total_e ))
|
|
then E="1 error"
|
|
else E="$e errors"
|
|
(( total_e += e ))
|
|
fi
|
|
echo test $o failed ${time:+"at $(date +%Y-%m-%d+%H:%M:%S)"} with exit code $e "[ $t $T $E ]"
|
|
case $E in
|
|
*INT\)) kill -s INT $$ ;; # if test was ^C'd, don't keep going but pass down SIGINT
|
|
esac
|
|
fi
|
|
else e=$?
|
|
(( ++total_e ))
|
|
echo test $o failed to compile ${time:+"at $(date +%Y-%m-%d+%H:%M:%S)"} with exit code $e "[ 1 test 1 error ]"
|
|
fi
|
|
if (( !keep ))
|
|
then rm -rf "$tmp_s" "$c"
|
|
fi
|
|
if [[ $i == $timesensitive ]]
|
|
then VMALLOC_OPTIONS=$vmalloc_options
|
|
fi
|
|
fi
|
|
done
|
|
print "Total errors: $total_e"
|
|
|
|
# This test harness should continue to work with old and buggy versions of ksh93, so check
|
|
# if we have the 'times' builtin and can use process substitution with output redirection.
|
|
# See: https://github.com/ksh93/ksh/commit/65d363fd
|
|
# https://github.com/ksh93/ksh/issues/2
|
|
if ( ulimit -t unlimited # fork to circumvent old ksh bugs
|
|
unalias times
|
|
PATH=/dev/null whence -q times || exit
|
|
cd "$tmp" || exit
|
|
echo ok > >(cat > procsubst_test)
|
|
wait
|
|
[[ $(< procsubst_test) == ok ]]
|
|
) 2>/dev/null
|
|
then # Transforming 'times' output requires a process substitution.
|
|
# A regular 'times | ...' pipeline would cause 'times' to be
|
|
# run in a subshell, which would reset all the times to zero.
|
|
times > >(
|
|
t[0]='CPU time' t[1]='user:' t[2]='system:'
|
|
t[3]='main:'; read t[4] t[5]
|
|
t[6]='tests:'; read t[7] t[8]
|
|
printf '%-8s%12s %12s\n' "${t[@]}"
|
|
)
|
|
wait "$!" # process substitutions are executed asynchronously
|
|
else # No pretty-printing.
|
|
times
|
|
fi
|
|
|
|
exit $((total_e > 125 ? 125 : total_e))
|