check: avoid spurious complaints that tests/$FSTYP/group does not exist
[xfstests-dev.git] / check
diff --git a/check b/check
index a5a6184e07f28c9f42184b2464ec71440a0bb80d..2986d84d84b2ae0f6f4bdad68ce22dd3fa0ae7d3 100755 (executable)
--- a/check
+++ b/check
@@ -37,6 +37,8 @@ randomize=false
 export here=`pwd`
 xfile=""
 
+DUMP_OUTPUT=false
+
 # start the initialisation work now
 iam=check
 
@@ -51,22 +53,6 @@ timestamp=${TIMESTAMP:=false}
 
 rm -f $tmp.list $tmp.tmp $tmp.grep $here/$iam.out $tmp.xlist
 
-# we need common/config
-if ! . ./common/config
-then
-    echo "$iam: failed to source common/config"
-    exit 1
-fi
-
-# Autodetect fs type based on what's on $TEST_DEV unless it's been set
-# externally
-if [ -z "$FSTYP" -a "$HOSTOS" == "Linux" ]; then
-    FSTYP=`blkid -c /dev/null -s TYPE -o value $TEST_DEV`
-fi
-FSTYP=${FSTYP:=xfs}
-export FSTYP
-
-SUPPORTED_TESTS="[0-9][0-9][0-9] [0-9][0-9][0-9][0-9]"
 SRC_GROUPS="generic shared"
 export SRC_DIR="tests"
 
@@ -76,18 +62,24 @@ usage()
 
 check options
     -nfs                test NFS
+    -cifs               test CIFS
+    -overlay           test overlay
     -tmpfs              test TMPFS
     -l                 line mode diff
     -udiff             show unified diff (default)
     -n                 show me, do not run tests
     -T                 output timestamps
     -r                 randomize test order
+    -d                 dump test output to stdout
     --large-fs         optimise scratch device for large filesystems
+    -s section         run only specified section from config file
+    -S section         exclude the specified section from the config file
 
 testlist options
     -g group[,group...]        include tests from these groups
     -x group[,group...]        exclude tests from these groups
     -X file            exclude individual tests
+    -E external_file   exclude individual tests
     [testlist]         include tests matching names in testlist
 '
            exit 0
@@ -98,24 +90,30 @@ get_group_list()
        grp=$1
 
        for d in $SRC_GROUPS $FSTYP; do
+               if ! test -d "$SRC_DIR/$d" ; then
+                       continue
+               fi
                l=$(sed -n < $SRC_DIR/$d/group \
                        -e 's/#.*//' \
                        -e 's/$/ /' \
-                       -e "s;\(^[0-9][0-9][0-9]\).* $grp .*;$SRC_DIR/$d/\1;p")
+                       -e "s;^\($VALID_TEST_NAME\).* $grp .*;$SRC_DIR/$d/\1;p")
                grpl="$grpl $l"
        done
        echo $grpl
 }
 
-# find all tests, excluding files that are test metadata such as group files.
-# This assumes that tests are defined purely by alphanumeric filenames with no
-# ".xyz" extensions in the name.
+# Find all tests, excluding files that are test metadata such as group files.
+# It matches test names against $VALID_TEST_NAME defined in common/rc
 get_all_tests()
 {
        touch $tmp.list
        for d in $SRC_GROUPS $FSTYP; do
+               if ! test -d "$SRC_DIR/$d" ; then
+                       continue
+               fi
                ls $SRC_DIR/$d/* | \
                        grep -v "\..*" | \
+                       grep "^$SRC_DIR/$d/$VALID_TEST_NAME"| \
                        grep -v "group\|Makefile" >> $tmp.list 2>/dev/null
        done
 }
@@ -146,7 +144,7 @@ trim_test_list()
 
 _wallclock()
 {
-    date "+%H %M %S" | $AWK_PROG '{ print $1*3600 + $2*60 + $3 }'
+    date "+%s"
 }
 
 _timestamp()
@@ -210,15 +208,17 @@ while [ $# -gt 0 ]; do
        case "$1" in
        -\? | -h | --help) usage ;;
 
-       -nfs)   FSTYP=nfs ;;
-       -tmpfs) FSTYP=tmpfs ;;
+       -nfs)           FSTYP=nfs ;;
+       -cifs)          FSTYP=cifs ;;
+       -overlay)       FSTYP=overlay ;;
+       -tmpfs)         FSTYP=tmpfs ;;
 
        -g)     group=$2 ; shift ;
-               GROUP_LIST="$GROUP_LIST $group"
+               GROUP_LIST="$GROUP_LIST ${group//,/ }"
                ;;
 
        -x)     xgroup=$2 ; shift ;
-               XGROUP_LIST="$XGROUP_LIST $xgroup"
+               XGROUP_LIST="$XGROUP_LIST ${xgroup//,/ }"
                ;;
 
        -X)     xfile=$2; shift ;
@@ -229,7 +229,13 @@ while [ $# -gt 0 ]; do
                        done
                done
                ;;
-
+       -E)     xfile=$2; shift ;
+               if [ -f $xfile ]; then
+                       cat "$xfile" >> $tmp.xlist
+               fi
+               ;;
+       -s)     RUN_SECTION="$RUN_SECTION $2"; shift ;;
+       -S)     EXCLUDE_SECTION="$EXCLUDE_SECTION $2"; shift ;;
        -l)     diff="diff" ;;
        -udiff) diff="$diff -u" ;;
 
@@ -237,6 +243,7 @@ while [ $# -gt 0 ]; do
         -r)    randomize=true ;;
 
        -T)     timestamp=true ;;
+       -d)     DUMP_OUTPUT=true ;;
 
        --large-fs) export LARGE_SCRATCH_DEV=yes ;;
        --extra-space=*) export SCRATCH_DEV_EMPTY_SPACE=${r#*=} ;;
@@ -256,11 +263,18 @@ while [ $# -gt 0 ]; do
        shift
 done
 
+# we need common/config, source it after processing args, overlay needs FSTYP
+# set before sourcing common/config
+if ! . ./common/config; then
+       echo "$iam: failed to source common/config"
+       exit 1
+fi
+
 # Process tests from command line now.
 if $have_test_arg; then
        while [ $# -gt 0 ]; do
                case "$1" in
-               -*)     echo "Argments before tests, please!"
+               -*)     echo "Arguments before tests, please!"
                        status=1
                        exit $status
                        ;;
@@ -384,6 +398,18 @@ _summary()
        rm -f $tmp.*
 }
 
+_check_filesystems()
+{
+       if [ -f ${RESULT_DIR}/require_test ]; then
+               _check_test_fs || err=true
+               rm -f ${RESULT_DIR}/require_test
+       fi
+       if [ -f ${RESULT_DIR}/require_scratch ]; then
+               _check_scratch_fs || err=true
+               rm -f ${RESULT_DIR}/require_scratch
+       fi
+}
+
 _prepare_test_list
 
 if $OPTIONS_HAVE_SECTIONS; then
@@ -394,12 +420,42 @@ fi
 
 for section in $HOST_OPTIONS_SECTIONS; do
        OLD_FSTYP=$FSTYP
+       OLD_MOUNT_OPTIONS=$MOUNT_OPTIONS
        get_next_config $section
 
+       # Do we need to run only some sections ?
+       if [ ! -z "$RUN_SECTION" ]; then
+               skip=true
+               for s in $RUN_SECTION; do
+                       if [ $section == $s ]; then
+                               skip=false
+                               break;
+                       fi
+               done
+               if $skip; then
+                       continue
+               fi
+       fi
+
+       # Did this section get excluded?
+       if [ ! -z "$EXCLUDE_SECTION" ]; then
+               skip=false
+               for s in $EXCLUDE_SECTION; do
+                       if [ $section == $s ]; then
+                               skip=true
+                               break;
+                       fi
+               done
+               if $skip; then
+                       continue
+               fi
+       fi
+
        mkdir -p $RESULT_BASE
        if [ ! -d $RESULT_BASE ]; then
-               echo "failed to create results directory $RESULTS_BASE"
-               exit 1;
+               echo "failed to create results directory $RESULT_BASE"
+               status=1
+               exit
        fi
 
        if $OPTIONS_HAVE_SECTIONS; then
@@ -408,20 +464,30 @@ for section in $HOST_OPTIONS_SECTIONS; do
 
        if $RECREATE_TEST_DEV || [ "$OLD_FSTYP" != "$FSTYP" ]; then
                echo "RECREATING    -- $FSTYP on $TEST_DEV"
-               umount $TEST_DEV 2> /dev/null
+               _test_unmount 2> /dev/null
                if ! _test_mkfs >$tmp.err 2>&1
                then
                        echo "our local _test_mkfs routine ..."
                        cat $tmp.err
                        echo "check: failed to mkfs \$TEST_DEV using specified options"
-                       exit 1
+                       status=1
+                       exit
                fi
                out=`_mount_or_remount_rw "$MOUNT_OPTIONS" $TEST_DEV $TEST_DIR`
                if [ $? -ne 1 ]; then
                        echo $out
-                       exit 1
+                       status=1
+                       exit
                fi
                _prepare_test_list
+       elif [ "$OLD_MOUNT_OPTIONS" != "$MOUNT_OPTIONS" ]; then
+               _test_unmount 2> /dev/null
+               out=`_mount_or_remount_rw "$MOUNT_OPTIONS" $TEST_DEV $TEST_DIR`
+               if [ $? -ne 1 ]; then
+                       echo $out
+                       status=1
+                       exit
+               fi
        fi
 
        init_rc
@@ -445,16 +511,17 @@ for section in $HOST_OPTIONS_SECTIONS; do
        needwrap=true
 
        if [ ! -z "$SCRATCH_DEV" ]; then
-         umount $SCRATCH_DEV 2>/dev/null
+         _scratch_unmount 2> /dev/null
          # call the overridden mkfs - make sure the FS is built
          # the same as we'll create it later.
 
-         if ! _scratch_mkfs $flag >$tmp.err 2>&1
+         if ! _scratch_mkfs >$tmp.err 2>&1
          then
              echo "our local _scratch_mkfs routine ..."
              cat $tmp.err
              echo "check: failed to mkfs \$SCRATCH_DEV using specified options"
-             exit 1
+             status=1
+             exit
          fi
 
          # call the overridden mount - make sure the FS mounts with
@@ -464,7 +531,8 @@ for section in $HOST_OPTIONS_SECTIONS; do
              echo "our local mount routine ..."
              cat $tmp.err
              echo "check: failed to mount \$SCRATCH_DEV using specified options"
-             exit 1
+             status=1
+             exit
          fi
        fi
 
@@ -477,7 +545,7 @@ for section in $HOST_OPTIONS_SECTIONS; do
 
            # the filename for the test and the name output are different.
            # we don't include the tests/ directory in the name output.
-           seqnum=`echo $seq | sed -e "s;$SRC_DIR/;;"`
+           export seqnum=`echo $seq | sed -e "s;$SRC_DIR/;;"`
 
            # Similarly, the result directory needs to replace the tests/
            # part of the test location.
@@ -494,14 +562,27 @@ for section in $HOST_OPTIONS_SECTIONS; do
 
            echo -n "$seqnum"
 
-           if $showme
-           then
-               echo
-               continue
-           elif [ ! -f $seq ]
-           then
-               echo " - no such test?"
-           else
+               if $showme; then
+                       echo
+                       continue
+               elif [ ! -f $seq ]; then
+                       # Try to get full name in case the user supplied only seq id
+                       # and the test has a name. A bit of hassle to find really
+                       # the test and not its sample output or helping files.
+                       bname=$(basename $seq)
+                       full_seq=$(find $(dirname $seq) -name $bname* -executable |
+                               awk '(NR == 1 || length < length(shortest)) { shortest = $0 }\
+                                       END { print shortest }')
+                       if [ -f $full_seq ] \
+                               && [ x$(echo $bname | grep -o "^$VALID_TEST_ID") != x ]; then
+                               seq=$full_seq
+                               seqnum=${full_seq#*/}
+                       fi
+               fi
+
+               if [ ! -f $seq ]; then
+                       echo " - no such test?"
+               else
                # really going to try and run this one
                #
                rm -f $seqres.out.bad
@@ -527,8 +608,20 @@ for section in $HOST_OPTIONS_SECTIONS; do
                $timestamp && echo -n " ["`date "+%T"`"]"
                [ ! -x $seq ] && chmod u+x $seq # ensure we can run it
                $LOGGER_PROG "run xfstest $seqnum"
-               ./$seq >$tmp.rawout 2>&1
-               sts=$?
+               if [ -w /dev/kmsg ]; then
+                       export date_time=`date +"%F %T"`
+                       echo "run fstests $seqnum at $date_time" > /dev/kmsg
+                       # _check_dmesg depends on this log in dmesg
+                       touch ${RESULT_DIR}/check_dmesg
+               fi
+               if [ "$DUMP_OUTPUT" = true ]; then
+                       ./$seq 2>&1 | tee $tmp.rawout
+                       # Because $? would get tee's return code
+                       sts=${PIPESTATUS[0]}
+               else
+                       ./$seq >$tmp.rawout 2>&1
+                       sts=$?
+               fi
                $timestamp && _timestamp
                stop=`_wallclock`
 
@@ -589,6 +682,10 @@ for section in $HOST_OPTIONS_SECTIONS; do
                            err=true
                        fi
                    fi
+                   try="$try $seqnum"
+                   n_try=`expr $n_try + 1`
+                   _check_filesystems
+                   _check_dmesg || err=true
                fi
 
            fi
@@ -601,17 +698,14 @@ for section in $HOST_OPTIONS_SECTIONS; do
                n_bad=`expr $n_bad + 1`
                quick=false
            fi
-           if [ ! -f $seqres.notrun ]
-           then
-               try="$try $seqnum"
-               n_try=`expr $n_try + 1`
-               _check_test_fs
-           fi
 
            seq="after_$seqnum"
        done
        _wrapup
        echo
+
+       _test_unmount 2> /dev/null
+       _scratch_unmount 2> /dev/null
 done
 
 interrupt=false