btrfs-progs: update CHANGES for v4.13.3
[platform/upstream/btrfs-progs.git] / tests / common
index d9dec0c..eb525a4 100644 (file)
@@ -21,6 +21,27 @@ _assert_path()
        exit 1
 }
 
+# $1: this string gets matched to files, absolute or relative path, or a
+# systemwide command available via $PATH
+_is_file_or_command()
+{
+       local msg
+
+       msg="$1"
+       if [ -z "$msg" ]; then
+               return 1
+       fi
+
+       if [ -f "$msg" -o -d "$msg" -o -b "$msg" ]; then
+               return 0
+       fi
+       msg=$(type -p -- "$msg")
+       if [ -f "$msg" ]; then
+               return 0
+       fi
+       return 1
+}
+
 _fail()
 {
        echo "$*" | tee -a "$RESULTS"
@@ -39,8 +60,75 @@ _not_run()
        exit 0
 }
 
+# debugging helper
+_dump_args()
+{
+       local i
+
+       i=1
+       echo "DUMP args for ${FUNCNAME[1]}:"
+       while [ $# -gt 0 ]; do
+               echo "ARG[$i]: $1"
+               i=$(($i+1))
+               shift
+       done
+}
+
+# read arguments, look if we're calling btrfs and if there's a known
+# subcommand, return argument index to insert, taking root helper into
+# consideration, returns 2 for unknown subcommand
+_get_spec_ins()
+{
+       if [ "$1" = 'root_helper' ]; then
+               if [[ $2 =~ /btrfs$ ]]; then
+                       echo -n 4
+                       return
+               fi
+       else
+               if [[ $1 =~ /btrfs$ ]]; then
+                       echo -n 3
+                       return
+               fi
+       fi
+       echo -n 2
+}
+
+# return command-specific arguments if enabled
+_cmd_spec()
+{
+       if [ "$TEST_ENABLE_OVERRIDE" = 'true' ]; then
+               # if defined via common.local, use it, otherwise pass make
+               # arguments
+               if [ "$(type -t _skip_spec)" = 'function' ]; then
+                       if _skip_spec "$@"; then
+                               return
+                       fi
+               fi
+               case "$1" in
+                       check) echo -n "$TEST_ARGS_CHECK" ;;
+               esac
+       fi
+}
+
+# Argument passing magic:
+# the command passed to run_* helpers is inspected, if there's 'btrfs command'
+# found and there are defined additional arguments, they're inserted just after
+# the command name, ie. any arguments in the test could override them.
+#
+# The root helper is recognized.  Unrecognized subcommands or external tools
+# are not affected.
+
 run_check()
 {
+       local spec
+       local ins
+       local cmd
+
+       ins=$(_get_spec_ins "$@")
+       spec=$(($ins-1))
+       cmd=$(eval echo "\${$spec}")
+       spec=$(_cmd_spec "${@:$spec}")
+       set -- "${@:1:$(($ins-1))}" $spec "${@: $ins}"
        echo "############### $@" >> "$RESULTS" 2>&1
        if [[ $TEST_LOG =~ tty ]]; then echo "CMD: $@" > /dev/tty; fi
        if [ "$1" = 'root_helper' ]; then
@@ -54,12 +142,24 @@ run_check()
 # can be processed further
 run_check_stdout()
 {
+       local spec
+       local ins
+       local cmd
+
+       ins=$(_get_spec_ins "$@")
+       spec=$(($ins-1))
+       cmd=$(eval echo "\${$spec}")
+       spec=$(_cmd_spec "${@:$spec}")
+       set -- "${@:1:$(($ins-1))}" $spec "${@: $ins}"
        echo "############### $@" >> "$RESULTS" 2>&1
        if [[ $TEST_LOG =~ tty ]]; then echo "CMD(stdout): $@" > /dev/tty; fi
        if [ "$1" = 'root_helper' ]; then
-               "$@" 2>&1 | tee -a "$RESULTS" || _fail "failed: $@"
+               "$@" 2>&1 | tee -a "$RESULTS"
        else
-               $INSTRUMENT "$@" 2>&1 | tee -a "$RESULTS" || _fail "failed: $@"
+               $INSTRUMENT "$@" 2>&1 | tee -a "$RESULTS"
+       fi
+       if [ ${PIPESTATUS[0]} -ne 0 ]; then
+               _fail "failed: $@"
        fi
 }
 
@@ -68,12 +168,20 @@ run_check_stdout()
 # output is logged
 run_mayfail()
 {
+       local spec
+       local ins
+       local cmd
        local ret
 
+       ins=$(_get_spec_ins "$@")
+       spec=$(($ins-1))
+       cmd=$(eval echo "\${$spec}")
+       spec=$(_cmd_spec "${@:$spec}")
+       set -- "${@:1:$(($ins-1))}" $spec "${@: $ins}"
        echo "############### $@" >> "$RESULTS" 2>&1
        if [[ $TEST_LOG =~ tty ]]; then echo "CMD(mayfail): $@" > /dev/tty; fi
        if [ "$1" = 'root_helper' ]; then
-               "$@" >> $RESULTS 2>&1
+               "$@" >> "$RESULTS" 2>&1
        else
                $INSTRUMENT "$@" >> "$RESULTS" 2>&1
        fi
@@ -93,11 +201,24 @@ run_mayfail()
 # same as run_check but expects the command to fail, output is logged
 run_mustfail()
 {
+       local spec
+       local ins
+       local cmd
        local msg
 
        msg="$1"
        shift
 
+       if _is_file_or_command "$msg"; then
+               echo "ASSERTION FAIL: 1st argument of run_mustfail must be a message"
+               exit 1
+       fi
+
+       ins=$(_get_spec_ins "$@")
+       spec=$(($ins-1))
+       cmd=$(eval echo "\${$spec}")
+       spec=$(_cmd_spec "${@:$spec}")
+       set -- "${@:1:$(($ins-1))}" $spec "${@: $ins}"
        echo "############### $@" >> "$RESULTS" 2>&1
        if [[ $TEST_LOG =~ tty ]]; then echo "CMD(mustfail): $@" > /dev/tty; fi
        if [ "$1" = 'root_helper' ]; then
@@ -136,11 +257,11 @@ check_image()
 
        image=$1
        echo "testing image $(basename $image)" >> "$RESULTS"
-       $TOP/btrfs check "$image" >> "$RESULTS" 2>&1
+       "$TOP/btrfs" check "$image" >> "$RESULTS" 2>&1
        [ $? -eq 0 ] && _fail "btrfs check should have detected corruption"
 
-       run_check $TOP/btrfs check --repair "$image"
-       run_check $TOP/btrfs check "$image"
+       run_check "$TOP/btrfs" check --repair "$image"
+       run_check "$TOP/btrfs" check "$image"
 }
 
 # Extract a usable image from packed formats
@@ -295,7 +416,7 @@ run_check_mount_test_dev()
                _fail "Invalid \$TEST_MNT: $TEST_MNT"
        }
 
-       run_check $SUDO_HELPER mount $loop_opt "$@" "$TEST_DEV" "$TEST_MNT"
+       run_check $SUDO_HELPER mount -t btrfs $loop_opt "$@" "$TEST_DEV" "$TEST_MNT"
 }
 
 run_check_umount_test_dev()
@@ -322,7 +443,7 @@ generate_dataset() {
        dirpath=$TEST_MNT/$dataset_type
        run_check $SUDO_HELPER mkdir -p "$dirpath"
 
-       case $dataset_type in
+       case "$dataset_type" in
                small)
                        for num in $(seq 1 "$DATASET_SIZE"); do
                                run_check $SUDO_HELPER dd if=/dev/urandom of="$dirpath/$dataset_type.$num" bs=10K \
@@ -332,14 +453,14 @@ generate_dataset() {
 
                hardlink)
                        for num in $(seq 1 "$DATASET_SIZE"); do
-                               run_check $SUDO_HELPER touch $dirpath/$dataset_type.$num
+                               run_check $SUDO_HELPER touch "$dirpath/$dataset_type.$num"
                                run_check $SUDO_HELPER ln "$dirpath/$dataset_type.$num" "$dirpath/hlink.$num"
                        done
                        ;;
 
                fast_symlink)
                        for num in $(seq 1 "$DATASET_SIZE"); do
-                               run_check $SUDO_HELPER touch $dirpath/$dataset_type.$num
+                               run_check $SUDO_HELPER touch "$dirpath/$dataset_type.$num"
                                run_check cd "$dirpath" && \
                                        $SUDO_HELPER ln -s "$dataset_type.$num" "$dirpath/slink.$num" && \
                                        cd /
@@ -388,20 +509,72 @@ generate_dataset() {
                        ;;
 
                slow_symlink)
-                       long_filename=`date +%s | sha256sum | cut -f1 -d'-'`
+                       long_filename=`date +%s | sha256sum | cut -f1 -d ' '`
                        run_check $SUDO_HELPER touch "$dirpath/$long_filename"
                        for num in $(seq 1 "$DATASET_SIZE"); do
                                run_check $SUDO_HELPER ln -s "$dirpath/$long_filename" "$dirpath/slow_slink.$num"
                        done
                        ;;
+               large)
+                       run_check $SUDO_HELPER dd if=/dev/urandom bs=32M count=1 \
+                               of="$dirpath/$dataset_type" >/dev/null 2>&1
+                       ;;
        esac
 }
 
+# prepare environment for loop devices, set up the following variables
+# - nloopdevs -- number of desired devices
+# - loopdevs  -- array containing paths to all devices (after prepare is called)
+# - loopdev_prefix -- file backed images starting with this string, 'img' by default
+#
+# $1: number of loop devices to be set up
+setup_loopdevs()
+{
+       if [ -z "$1" ]; then
+               _fail "setup_loopdevs needs a number"
+       fi
+       nloopdevs="$1"
+       loopdev_prefix=img
+       declare -a loopdevs
+
+}
+
+# create all loop devices from a given loopdev environment
+prepare_loopdevs()
+{
+       for i in `seq $nloopdevs`; do
+               touch $loopdev_prefix$i
+               chmod a+rw $loopdev_prefix$i
+               truncate -s0 $loopdev_prefix$i
+               truncate -s2g $loopdev_prefix$i
+               loopdevs[$i]=`run_check_stdout $SUDO_HELPER losetup --find --show $loopdev_prefix$i`
+       done
+}
+
+# detach loop devices and reset their size to 0, delete the files afterwards
+cleanup_loopdevs()
+{
+       for dev in ${loopdevs[@]}; do
+               run_check $SUDO_HELPER losetup -d $dev
+       done
+       for i in `seq $nloopdevs`; do
+               truncate -s0 $loopdev_prefix$i
+               rm -- "$loopdev_prefix$i"
+       done
+       run_check $SUDO_HELPER losetup --all
+}
+
 init_env()
 {
        TEST_MNT="${TEST_MNT:-$TOP/tests/mnt}"
        export TEST_MNT
        mkdir -p "$TEST_MNT" || { echo "Failed mkdir -p $TEST_MNT"; exit 1; }
 
+       source $TOP/tests/common.local
+
+       if [ "$TEST_ENABLE_OVERRIDE" = 'true' -a -n "$RESULTS" ]; then
+               echo "INCLUDE common.local" >> "$RESULTS"
+               echo "  check: $TEST_ARGS_CHECK" >> "$RESULTS"
+       fi
 }
 init_env