Merge tag 'v2.12.4' into maint
[gitweb.git] / t / test-lib.sh
index 51e4a88c333463e23957eb07139b01a3de1a1a0e..30eb7437198dddbb2d251e9ec91590754b1eddcf 100644 (file)
@@ -54,12 +54,22 @@ case "$GIT_TEST_TEE_STARTED, $* " in
 done,*)
        # do not redirect again
        ;;
-*' --tee '*|*' --va'*)
+*' --tee '*|*' --va'*|*' --verbose-log '*)
        mkdir -p "$TEST_OUTPUT_DIRECTORY/test-results"
        BASE="$TEST_OUTPUT_DIRECTORY/test-results/$(basename "$0" .sh)"
+
+       # Make this filename available to the sub-process in case it is using
+       # --verbose-log.
+       GIT_TEST_TEE_OUTPUT_FILE=$BASE.out
+       export GIT_TEST_TEE_OUTPUT_FILE
+
+       # Truncate before calling "tee -a" to get rid of the results
+       # from any previous runs.
+       >"$GIT_TEST_TEE_OUTPUT_FILE"
+
        (GIT_TEST_TEE_STARTED=done ${SHELL_PATH} "$0" "$@" 2>&1;
-        echo $? > $BASE.exit) | tee $BASE.out
-       test "$(cat $BASE.exit)" = 0
+        echo $? >"$BASE.exit") | tee -a "$GIT_TEST_TEE_OUTPUT_FILE"
+       test "$(cat "$BASE.exit")" = 0
        exit
        ;;
 esac
@@ -89,6 +99,7 @@ unset VISUAL EMAIL LANGUAGE COLUMNS $("$PERL_PATH" -e '
                UNZIP
                PERF_
                CURL_VERBOSE
+               TRACE_CURL
        ));
        my @vars = grep(/^GIT_/ && !/^GIT_($ok)/o, @env);
        print join("\n", @vars);
@@ -162,6 +173,9 @@ _x40="$_x05$_x05$_x05$_x05$_x05$_x05$_x05$_x05"
 # Zero SHA-1
 _z40=0000000000000000000000000000000000000000
 
+EMPTY_TREE=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+EMPTY_BLOB=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
+
 # Line feed
 LF='
 '
@@ -170,7 +184,7 @@ LF='
 # when case-folding filenames
 u200c=$(printf '\342\200\214')
 
-export _x05 _x40 _z40 LF u200c
+export _x05 _x40 _z40 LF u200c EMPTY_TREE EMPTY_BLOB
 
 # Each test should start with something like this, after copyright notices:
 #
@@ -202,13 +216,13 @@ do
                }
                run_list=$1; shift ;;
        --run=*)
-               run_list=$(expr "z$1" : 'z[^=]*=\(.*\)'); shift ;;
+               run_list=${1#--*=}; shift ;;
        -h|--h|--he|--hel|--help)
                help=t; shift ;;
        -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
                verbose=t; shift ;;
        --verbose-only=*)
-               verbose_only=$(expr "z$1" : 'z[^=]*=\(.*\)')
+               verbose_only=${1#--*=}
                shift ;;
        -q|--q|--qu|--qui|--quie|--quiet)
                # Ignore --quiet under a TAP::Harness. Saying how many tests
@@ -222,15 +236,15 @@ do
                valgrind=memcheck
                shift ;;
        --valgrind=*)
-               valgrind=$(expr "z$1" : 'z[^=]*=\(.*\)')
+               valgrind=${1#--*=}
                shift ;;
        --valgrind-only=*)
-               valgrind_only=$(expr "z$1" : 'z[^=]*=\(.*\)')
+               valgrind_only=${1#--*=}
                shift ;;
        --tee)
                shift ;; # was handled already
        --root=*)
-               root=$(expr "z$1" : 'z[^=]*=\(.*\)')
+               root=${1#--*=}
                shift ;;
        --chain-lint)
                GIT_TEST_CHAIN_LINT=1
@@ -242,6 +256,9 @@ do
                trace=t
                verbose=t
                shift ;;
+       --verbose-log)
+               verbose_log=t
+               shift ;;
        *)
                echo "error: unknown test option '$1'" >&2; exit 1 ;;
        esac
@@ -304,6 +321,16 @@ say () {
        say_color info "$*"
 }
 
+if test -n "$HARNESS_ACTIVE"
+then
+       if test "$verbose" = t || test -n "$verbose_only"
+       then
+               printf 'Bail out! %s\n' \
+                'verbose mode forbidden under TAP harness; try --verbose-log'
+               exit 1
+       fi
+fi
+
 test "${test_description}" != "" ||
 error "Test script did not set test_description."
 
@@ -315,13 +342,30 @@ fi
 
 exec 5>&1
 exec 6<&0
-if test "$verbose" = "t"
+exec 7>&2
+if test "$verbose_log" = "t"
+then
+       exec 3>>"$GIT_TEST_TEE_OUTPUT_FILE" 4>&3
+elif test "$verbose" = "t"
 then
        exec 4>&2 3>&1
 else
        exec 4>/dev/null 3>/dev/null
 fi
 
+# Send any "-x" output directly to stderr to avoid polluting tests
+# which capture stderr. We can do this unconditionally since it
+# has no effect if tracing isn't turned on.
+#
+# Note that this sets up the trace fd as soon as we assign the variable, so it
+# must come after the creation of descriptor 4 above. Likewise, we must never
+# unset this, as it has the side effect of closing descriptor 4, which we
+# use to show verbose tests to the user.
+#
+# Note also that we don't need or want to export it. The tracing is local to
+# this shell, and we would not want to influence any shells we exec.
+BASH_XTRACEFD=4
+
 test_failure=0
 test_count=0
 test_fixed=0
@@ -581,9 +625,9 @@ test_run_ () {
                trace=
                # 117 is magic because it is unlikely to match the exit
                # code of other programs
-               test_eval_ "(exit 117) && $1"
-               if test "$?" != 117; then
-                       error "bug in the test script: broken &&-chain: $1"
+               if test "OK-117" != "$(test_eval_ "(exit 117) && $1${LF}${LF}echo OK-\$?" 3>&1)"
+               then
+                       error "bug in the test script: broken &&-chain or run-away HERE-DOC: $1"
                fi
                trace=$trace_tmp
        fi
@@ -671,9 +715,9 @@ test_done () {
                test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results"
                mkdir -p "$test_results_dir"
                base=${0##*/}
-               test_results_path="$test_results_dir/${base%.sh}-$$.counts"
+               test_results_path="$test_results_dir/${base%.sh}.counts"
 
-               cat >>"$test_results_path" <<-EOF
+               cat >"$test_results_path" <<-EOF
                total $test_count
                success $test_success
                fixed $test_fixed
@@ -701,20 +745,25 @@ test_done () {
        fi
        case "$test_failure" in
        0)
-               # Maybe print SKIP message
-               if test -n "$skip_all" && test $test_count -gt 0
-               then
-                       error "Can't use skip_all after running some tests"
-               fi
-               test -z "$skip_all" || skip_all=" # SKIP $skip_all"
-
                if test $test_external_has_tap -eq 0
                then
                        if test $test_remaining -gt 0
                        then
                                say_color pass "# passed all $msg"
                        fi
-                       say "1..$test_count$skip_all"
+
+                       # Maybe print SKIP message
+                       test -z "$skip_all" || skip_all="# SKIP $skip_all"
+                       case "$test_count" in
+                       0)
+                               say "1..$test_count${skip_all:+ $skip_all}"
+                               ;;
+                       *)
+                               test -z "$skip_all" ||
+                               say_color warn "$skip_all"
+                               say "1..$test_count"
+                               ;;
+                       esac
                fi
 
                test -d "$remove_trash" &&
@@ -766,7 +815,14 @@ then
                return;
 
                base=$(basename "$1")
-               symlink_target=$GIT_BUILD_DIR/$base
+               case "$base" in
+               test-*)
+                       symlink_target="$GIT_BUILD_DIR/t/helper/$base"
+                       ;;
+               *)
+                       symlink_target="$GIT_BUILD_DIR/$base"
+                       ;;
+               esac
                # do not override scripts
                if test -x "$symlink_target" &&
                    test ! -d "$symlink_target" &&
@@ -785,7 +841,7 @@ then
        # override all git executables in TEST_DIRECTORY/..
        GIT_VALGRIND=$TEST_DIRECTORY/valgrind
        mkdir -p "$GIT_VALGRIND"/bin
-       for file in $GIT_BUILD_DIR/git* $GIT_BUILD_DIR/test-*
+       for file in $GIT_BUILD_DIR/git* $GIT_BUILD_DIR/t/helper/test-*
        do
                make_valgrind_symlink $file
        done
@@ -854,10 +910,10 @@ test -d "$GIT_BUILD_DIR"/templates/blt || {
        error "You haven't built things yet, have you?"
 }
 
-if ! test -x "$GIT_BUILD_DIR"/test-chmtime
+if ! test -x "$GIT_BUILD_DIR"/t/helper/test-chmtime
 then
        echo >&2 'You need to build test-chmtime:'
-       echo >&2 'Run "make test-chmtime" in the source (toplevel) directory'
+       echo >&2 'Run "make t/helper/test-chmtime" in the source (toplevel) directory'
        exit 1
 fi
 
@@ -916,7 +972,8 @@ yes () {
 }
 
 # Fix some commands on Windows
-case $(uname -s) in
+uname_s=$(uname -s)
+case $uname_s in
 *MINGW*)
        # Windows has its own (incompatible) sort and find
        sort () {
@@ -1000,7 +1057,7 @@ test_i18ngrep () {
 test_lazy_prereq PIPE '
        # test whether the filesystem supports FIFOs
        case $(uname -s) in
-       CYGWIN*)
+       CYGWIN*|MINGW*)
                false
                ;;
        *)
@@ -1056,6 +1113,10 @@ test_lazy_prereq NOT_ROOT '
        test "$uid" != 0
 '
 
+test_lazy_prereq JGIT '
+       type jgit
+'
+
 # SANITY is about "can you correctly predict what the filesystem would
 # do by only looking at the permission bits of the files and
 # directories?"  A typical example of !SANITY is running the test
@@ -1087,6 +1148,7 @@ test_lazy_prereq SANITY '
        return $status
 '
 
+test FreeBSD != $uname_s || GIT_UNZIP=${GIT_UNZIP:-/usr/local/bin/unzip}
 GIT_UNZIP=${GIT_UNZIP:-unzip}
 test_lazy_prereq UNZIP '
        "$GIT_UNZIP" -v
@@ -1098,3 +1160,12 @@ run_with_limited_cmdline () {
 }
 
 test_lazy_prereq CMDLINE_LIMIT 'run_with_limited_cmdline true'
+
+build_option () {
+       git version --build-options |
+       sed -ne "s/^$1: //p"
+}
+
+test_lazy_prereq LONG_IS_64BIT '
+       test 8 -le "$(build_option sizeof-long)"
+'