TS_TOPDIR=$(cd ${0%/*} && pwd)
SUBTESTS=
+EXCLUDETESTS=
OPTS=
+SYSCOMMANDS=
top_srcdir=
top_builddir=
+paraller_jobs=1
+has_asan_opt=
+
+function num_cpus()
+{
+ local num
+
+ # coreutils
+ if num=$(nproc 2>/dev/null); then
+ :
+ # BSD, OSX
+ elif num=$(sysctl -n hw.ncpu 2>/dev/null); then
+ :
+ else
+ num=$(grep -c "^processor" /proc/cpuinfo 2>/dev/null)
+ fi
+
+ # translate garbage output to "1"
+ if test "$num" -gt "0" 2>/dev/null ;then
+ echo "$num"
+ else
+ echo 1
+ fi
+}
+
+function find_test_scripts()
+{
+ local searchdir="$1"
+ find "$searchdir" -type f -regex ".*/[^\.~]*" \
+ \( -perm -u=x -o -perm -g=x -o -perm -o=x \)
+}
while [ -n "$1" ]; do
case "$1" in
- --force)
- OPTS="$OPTS --force"
+ --force |\
+ --fake |\
+ --memcheck-valgrind |\
+ --nolocks |\
+ --show-diff |\
+ --verbose |\
+ --skip-loopdevs |\
+ --noskip-commands |\
+ --parsable)
+ # these options are simply forwarded to the test scripts
+ OPTS="$OPTS $1"
;;
- --fake)
- OPTS="$OPTS --fake"
+ --memcheck-asan)
+ OPTS="$OPTS $1"
+ has_asan_opt="yes"
;;
- --memcheck)
- OPTS="$OPTS --memcheck"
- ;;
- --verbose)
- OPTS="$OPTS --verbose"
+ --use-system-commands)
+ OPTS="$OPTS $1"
+ SYSCOMMANDS="yes"
;;
+
--nonroot)
if [ $(id -ru) -eq 0 ]; then
- echo "Ignore utils-linux test suite [non-root UID expected]."
+ echo "Ignore util-linux test suite [non-root UID expected]."
exit 0
fi
;;
--builddir=*)
top_builddir="${1##--builddir=}"
;;
+ --parallel=*)
+ paraller_jobs="${1##--parallel=}"
+ if [ "$paraller_jobs" = "none" ]; then
+ paraller_jobs=1
+ elif ! [ "$paraller_jobs" -ge 0 ] 2>/dev/null; then
+ echo "invalid argument '$paraller_jobs' for --parallel="
+ exit 1
+ fi
+ ;;
+ --parallel)
+ paraller_jobs=$(num_cpus)
+ ;;
+ --exclude=*)
+ EXCLUDETESTS="${1##--exclude=}"
+ ;;
--*)
echo "Unknown option $1"
echo "Usage: "
echo " $(basename $0) [options] [<component> ...]"
echo "Options:"
- echo " --force execute demanding tests"
- echo " --fake do not run, setup tests only"
- echo " --memcheck run with valgrind"
- echo " --verbose verbose mode"
- echo " --nonroot ignore test suite if user is root"
- echo " --srcdir=<path> autotools top source directory"
- echo " --builddir=<path> autotools top build directory"
+ echo " --force execute demanding tests"
+ echo " --fake do not run, setup tests only"
+ echo " --memcheck-valgrind run with valgrind"
+ echo " --memcheck-asan enable ASAN (requires ./configure --enable-asan)"
+ echo " --nolocks don't use flock to lock resources"
+ echo " --verbose verbose mode"
+ echo " --show-diff show diff from failed tests"
+ echo " --nonroot ignore test suite if user is root"
+ echo " --use-system-commands use PATH rather than builddir"
+ echo " --noskip-commands fail on missing commands"
+ echo " --srcdir=<path> autotools top source directory"
+ echo " --builddir=<path> autotools top build directory"
+ echo " --parallel=<num|none> number of parallel test jobs, default: num cpus"
+ echo " --exclude=<list> exclude tests by list '<utilname>/<testname> ..'"
echo
exit 1
;;
OPTS="$OPTS --srcdir=$top_srcdir --builddir=$top_builddir"
+# Auto-enable ASAN to avoid conflicts between tests and binaries
+if [ -z "$has_asan_opt" ]; then
+ asan=$(awk '/^ASAN_LDFLAGS/ { print $3 }' $top_builddir/Makefile)
+ if [ -n "$asan" ]; then
+ OPTS="$OPTS --memcheck-asan"
+ fi
+fi
+
+declare -a comps
if [ -n "$SUBTESTS" ]; then
# selected tests only
for s in $SUBTESTS; do
- if [ -d "$top_srcdir/tests/ts/$s" ]; then
- co=$(find $top_srcdir/tests/ts/$s -type f -perm /a+x -regex ".*/[^\.~]*" | sort)
- comps="$comps $co"
+ if [ -e "$top_srcdir/tests/ts/$s" ]; then
+ comps+=( $(find_test_scripts "$top_srcdir/tests/ts/$s") ) || exit 1
else
echo "Unknown test component '$s'"
exit 1
fi
done
else
- if [ ! -f "$top_builddir/test_tt" ]; then
+ if [ -z "$SYSCOMMANDS" -a ! -f "$top_builddir/test_ttyutils" ]; then
echo "Tests not compiled! Run 'make check' to fix the problem."
exit 1
fi
- comps=$(find $top_srcdir/tests/ts/ -type f -perm /a+x -regex ".*/[^\.~]*" | sort)
+ comps=( $(find_test_scripts "$top_srcdir/tests/ts") ) || exit 1
fi
+if [ -n "$EXCLUDETESTS" ]; then
+ declare -a xcomps # temporary array
+ for ts in ${comps[@]}; do
+ tsname=${ts##*ts/} # test name
+
+ if [[ "$EXCLUDETESTS" == *${tsname}* ]]; then
+ #echo "Ignore ${tsname}."
+ true
+ else
+ xcomps+=($ts)
+ fi
+ done
+ comps=("${xcomps[@]}") # replace the array
+fi
unset LIBMOUNT_DEBUG
unset LIBBLKID_DEBUG
unset LIBFDISK_DEBUG
+unset LIBSMARTCOLS_DEBUG
echo
echo "-------------------- util-linux regression tests --------------------"
echo " Don't execute on production system! "
echo
-res=0
-count=0
-for ts in $comps; do
- $ts "$OPTS"
- res=$(( $res + $? ))
- count=$(( $count + 1 ))
-done
+# TODO: add more information about system
+printf "%13s: %-30s " "kernel" "$(uname -r)"
+echo
+echo
+echo " options: $(echo $OPTS | sed 's/ / \\\n /g')"
+echo
+if [ "$paraller_jobs" -ne 1 ]; then
+ tmp=$paraller_jobs
+ [ "$paraller_jobs" -eq 0 ] && tmp=infinite
+ echo " Executing the tests in parallel ($tmp jobs) "
+ echo
+ OPTS="$OPTS --parallel"
+fi
+
+count=0
+>| $top_builddir/tests/failures
+printf "%s\n" ${comps[*]} |
+ sort |
+ xargs -I '{}' -P $paraller_jobs -n 1 bash -c "'{}' \"$OPTS\" ||
+ echo 1 >> $top_builddir/tests/failures"
+if [ $? != 0 ]; then
+ echo "xargs error" >&2
+ exit 1
+fi
+declare -a fail_file
+fail_file=( $( < $top_builddir/tests/failures ) ) || exit 1
+rm -f $top_builddir/tests/failures
echo
echo "---------------------------------------------------------------------"
-if [ $res -eq 0 ]; then
- echo " All $count tests PASSED"
+if [ ${#fail_file[@]} -eq 0 ]; then
+ echo " All ${#comps[@]} tests PASSED"
res=0
else
- echo " $res tests of $count FAILED"
+ echo " ${#fail_file[@]} tests of ${#comps[@]} FAILED"
res=1
fi
echo "---------------------------------------------------------------------"