btrfs-progs: tests: add support for additional command arguments
authorDavid Sterba <dsterba@suse.com>
Tue, 22 Nov 2016 12:32:18 +0000 (13:32 +0100)
committerDavid Sterba <dsterba@suse.com>
Wed, 23 Nov 2016 10:07:06 +0000 (11:07 +0100)
Add convenient support for extending command arguments, now implemented
for 'btrfs check' to cover the low-memory mode. If defined, arguments
are inserted to any 'btrfs check' command in tests. Exceptions could be
defined in common.local.

Signed-off-by: David Sterba <dsterba@suse.com>
tests/README.md
tests/common
tests/common.local [new file with mode: 0644]

index 4866447..bb2846a 100644 (file)
@@ -107,7 +107,7 @@ are possible.
 Note: instrumentation is not applied to privileged commands (anything that uses
 the root helper).
 
-### Verbosity
+### Verbosity, test tuning
 
 * `TEST_LOG=tty` -- setting the variable will print all commands executed by
   some of the wrappers (`run_check` etc), other commands are not printed to the
@@ -115,6 +115,13 @@ the root helper).
 
 * `TEST_LOG=dump` -- dump the entire testing log when a test fails
 
+* `TEST_ENABLE_OVERRIDE` -- defined either as make arguments or via
+  `tests/common.local` to enable additional arguments to some commands, using
+  the variable(s) below (default: false, enable by setting to 'true')
+
+* `TEST_ARGS_CHECK` -- user-defined arguments to `btrfs check`, before the
+  test-specific arguments
+
 Multiple values can be separated by `,`.
 
 ### Permissions
index 98ef029..571118a 100644 (file)
@@ -39,8 +39,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 "$cmd")
+       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,6 +121,15 @@ 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 "$cmd")
+       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
@@ -68,8 +144,16 @@ 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 "$cmd")
+       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
@@ -93,11 +177,19 @@ 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
 
+       ins=$(_get_spec_ins "$@")
+       spec=$(($ins-1))
+       cmd=$(eval echo "\${$spec}")
+       spec=$(_cmd_spec "$cmd")
+       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
@@ -403,5 +495,11 @@ init_env()
        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
diff --git a/tests/common.local b/tests/common.local
new file mode 100644 (file)
index 0000000..9f567c2
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/bash
+#
+# additional arguments to various commands
+
+# already defined, eg. via make argument
+if [ -n "$TEST_ENABLE_OVERRIDE" ]; then
+       return
+fi
+
+# set to 'true'
+TEST_ENABLE_OVERRIDE=false
+
+TEST_ARGS_CHECK=--mode=lowmem
+
+# gets arguments of a current command and can decide if the argument insertion
+# should happen, eg. if some option combination does not make sense or would
+# break tests
+_skip_spec()
+{
+       if echo "$TEST_CHECK" | grep -q 'mode=lowmem' &&
+          echo "$@" | grep -q -- '--repair'; then
+               return 0
+       fi
+       return 1
+}