]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - tests/run.sh
build-sys: support 'none' for parallel tests
[thirdparty/util-linux.git] / tests / run.sh
index 8a7924ae144d736db2852d4d48d419c8a000909d..1c3efdb6e9a808c81a9c914efae82f4da4c83481 100755 (executable)
 
 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
                ;;
@@ -49,18 +91,40 @@ while [ -n "$1" ]; do
        --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
                ;;
@@ -87,30 +151,53 @@ fi
 
 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 --------------------"
@@ -119,21 +206,41 @@ echo "                    For development purpose only.                    "
 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 "---------------------------------------------------------------------"