]> git.ipfire.org Git - thirdparty/git.git/blobdiff - t/test-lib.sh
test-lib: Allow overriding of TEST_DIRECTORY
[thirdparty/git.git] / t / test-lib.sh
index 367f0537cd87c29bfdca15b4744f1aef3ddd8d7e..4167138250f914f48fc989f814512ee0f7d4dff0 100644 (file)
@@ -127,14 +127,13 @@ do
        -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
                verbose=t; shift ;;
        -q|--q|--qu|--qui|--quie|--quiet)
-               quiet=t; shift ;;
+               # Ignore --quiet under a TAP::Harness. Saying how many tests
+               # passed without the ok/not ok details is always an error.
+               test -z "$HARNESS_ACTIVE" && quiet=t; shift ;;
        --with-dashes)
                with_dashes=t; shift ;;
        --no-color)
                color=; shift ;;
-       --no-python)
-               # noop now...
-               shift ;;
        --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)
                valgrind=t; verbose=t; shift ;;
        --tee)
@@ -160,7 +159,7 @@ if test -n "$color"; then
                        *) test -n "$quiet" && return;;
                esac
                shift
-               printf "%s" "$*"
+               printf "%s" "$*"
                tput sgr0
                echo
                )
@@ -169,7 +168,7 @@ else
        say_color() {
                test -z "$1" && test -n "$quiet" && return
                shift
-               echo "$*"
+               echo "$*"
        }
 fi
 
@@ -206,6 +205,8 @@ test_fixed=0
 test_broken=0
 test_success=0
 
+test_external_has_tap=0
+
 die () {
        code=$?
        if test -n "$GIT_EXIT_OK"
@@ -326,12 +327,35 @@ test_set_prereq () {
 satisfied=" "
 
 test_have_prereq () {
-       case $satisfied in
-       *" $1 "*)
-               : yes, have it ;;
-       *)
-               ! : nope ;;
-       esac
+       # prerequisites can be concatenated with ','
+       save_IFS=$IFS
+       IFS=,
+       set -- $*
+       IFS=$save_IFS
+
+       total_prereq=0
+       ok_prereq=0
+       missing_prereq=
+
+       for prerequisite
+       do
+               total_prereq=$(($total_prereq + 1))
+               case $satisfied in
+               *" $prerequisite "*)
+                       ok_prereq=$(($ok_prereq + 1))
+                       ;;
+               *)
+                       # Keep a list of missing prerequisites
+                       if test -z "$missing_prereq"
+                       then
+                               missing_prereq=$prerequisite
+                       else
+                               missing_prereq="$prerequisite,$missing_prereq"
+                       fi
+               esac
+       done
+
+       test $total_prereq = $ok_prereq
 }
 
 # You are not expected to call test_ok_ and test_failure_ directly, use
@@ -339,25 +363,25 @@ test_have_prereq () {
 
 test_ok_ () {
        test_success=$(($test_success + 1))
-       say_color "" "  ok $test_count: $@"
+       say_color "" "ok $test_count - $@"
 }
 
 test_failure_ () {
        test_failure=$(($test_failure + 1))
-       say_color error "FAIL $test_count: $1"
+       say_color error "not ok - $test_count $1"
        shift
-       echo "$@" | sed -e 's/^/        /'
+       echo "$@" | sed -e 's/^/#       /'
        test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
 }
 
 test_known_broken_ok_ () {
        test_fixed=$(($test_fixed+1))
-       say_color "" "  FIXED $test_count: $@"
+       say_color "" "ok $test_count - $@ # TODO known breakage"
 }
 
 test_known_broken_failure_ () {
        test_broken=$(($test_broken+1))
-       say_color skip "  still broken $test_count: $@"
+       say_color skip "not ok $test_count - $@ # TODO known breakage"
 }
 
 test_debug () {
@@ -369,6 +393,9 @@ test_run_ () {
        eval >&3 2>&4 "$1"
        eval_ret=$?
        eval >&3 2>&4 "$test_cleanup"
+       if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then
+               echo ""
+       fi
        return 0
 }
 
@@ -380,6 +407,7 @@ test_skip () {
                case $this_test.$test_count in
                $skp)
                        to_skip=t
+                       break
                esac
        done
        if test -z "$to_skip" && test -n "$prereq" &&
@@ -390,7 +418,7 @@ test_skip () {
        case "$to_skip" in
        t)
                say_color skip >&3 "skipping test: $@"
-               say_color skip "skip $test_count: $1"
+               say_color skip "ok $test_count # skip $1 (missing $missing_prereq of $prereq)"
                : true
                ;;
        *)
@@ -456,7 +484,7 @@ test_expect_code () {
 # test_external runs external test scripts that provide continuous
 # test output about their progress, and succeeds/fails on
 # zero/non-zero exit code.  It outputs the test output on stdout even
-# in non-verbose mode, and announces the external script with "* run
+# in non-verbose mode, and announces the external script with "# run
 # <n>: ..." before running it.  When providing relative paths, keep in
 # mind that all scripts run in "trash directory".
 # Usage: test_external description command arguments...
@@ -471,7 +499,7 @@ test_external () {
        then
                # Announce the script to reduce confusion about the
                # test output that follows.
-               say_color "" " run $test_count: $descr ($*)"
+               say_color "" "# run $test_count: $descr ($*)"
                # Export TEST_DIRECTORY, TRASH_DIRECTORY and GIT_TEST_LONG
                # to be able to use them in script
                export TEST_DIRECTORY TRASH_DIRECTORY GIT_TEST_LONG
@@ -481,9 +509,19 @@ test_external () {
                "$@" 2>&4
                if [ "$?" = 0 ]
                then
-                       test_ok_ "$descr"
+                       if test $test_external_has_tap -eq 0; then
+                               test_ok_ "$descr"
+                       else
+                               say_color "" "# test_external test $descr was ok"
+                               test_success=$(($test_success + 1))
+                       fi
                else
-                       test_failure_ "$descr" "$@"
+                       if test $test_external_has_tap -eq 0; then
+                               test_failure_ "$descr" "$@"
+                       else
+                               say_color error "# test_external test $descr failed: $@"
+                               test_failure=$(($test_failure + 1))
+                       fi
                fi
        fi
 }
@@ -499,19 +537,30 @@ test_external_without_stderr () {
        [ -f "$stderr" ] || error "Internal error: $stderr disappeared."
        descr="no stderr: $1"
        shift
-       say >&3 "expecting no stderr from previous command"
+       say >&3 "expecting no stderr from previous command"
        if [ ! -s "$stderr" ]; then
                rm "$stderr"
-               test_ok_ "$descr"
+
+               if test $test_external_has_tap -eq 0; then
+                       test_ok_ "$descr"
+               else
+                       say_color "" "# test_external_without_stderr test $descr was ok"
+                       test_success=$(($test_success + 1))
+               fi
        else
                if [ "$verbose" = t ]; then
-                       output=`echo; echo Stderr is:; cat "$stderr"`
+                       output=`echo; echo "# Stderr is:"; cat "$stderr"`
                else
                        output=
                fi
                # rm first in case test_failure exits.
                rm "$stderr"
-               test_failure_ "$descr" "$@" "$output"
+               if test $test_external_has_tap -eq 0; then
+                       test_failure_ "$descr" "$@" "$output"
+               else
+                       say_color error "# test_external_without_stderr test $descr failed: $@: $output"
+                       test_failure=$(($test_failure + 1))
+               fi
        fi
 }
 
@@ -599,7 +648,7 @@ test_create_repo () {
        repo="$1"
        mkdir -p "$repo"
        cd "$repo" || error "Cannot setup test environment"
-       "$GIT_EXEC_PATH/git-init" "--template=$TEST_DIRECTORY/../templates/blt/" >&3 2>&4 ||
+       "$GIT_EXEC_PATH/git-init" "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
        error "cannot run git init -- have you built things yet?"
        mv .git/hooks .git/hooks-disabled
        cd "$owd"
@@ -607,31 +656,40 @@ test_create_repo () {
 
 test_done () {
        GIT_EXIT_OK=t
-       test_results_dir="$TEST_DIRECTORY/test-results"
-       mkdir -p "$test_results_dir"
-       test_results_path="$test_results_dir/${0%.sh}-$$"
 
-       echo "total $test_count" >> $test_results_path
-       echo "success $test_success" >> $test_results_path
-       echo "fixed $test_fixed" >> $test_results_path
-       echo "broken $test_broken" >> $test_results_path
-       echo "failed $test_failure" >> $test_results_path
-       echo "" >> $test_results_path
+       if test -z "$HARNESS_ACTIVE"; then
+               test_results_dir="$TEST_DIRECTORY/test-results"
+               mkdir -p "$test_results_dir"
+               test_results_path="$test_results_dir/${0%.sh}-$$.counts"
+
+               echo "total $test_count" >> $test_results_path
+               echo "success $test_success" >> $test_results_path
+               echo "fixed $test_fixed" >> $test_results_path
+               echo "broken $test_broken" >> $test_results_path
+               echo "failed $test_failure" >> $test_results_path
+               echo "" >> $test_results_path
+       fi
 
        if test "$test_fixed" != 0
        then
-               say_color pass "fixed $test_fixed known breakage(s)"
+               say_color pass "fixed $test_fixed known breakage(s)"
        fi
        if test "$test_broken" != 0
        then
-               say_color error "still have $test_broken known breakage(s)"
+               say_color error "still have $test_broken known breakage(s)"
                msg="remaining $(($test_count-$test_broken)) test(s)"
        else
                msg="$test_count test(s)"
        fi
        case "$test_failure" in
        0)
-               say_color pass "passed all $msg"
+               # Maybe print SKIP message
+               [ -z "$skip_all" ] || skip_all=" # SKIP $skip_all"
+
+               if test $test_external_has_tap -eq 0; then
+                       say_color pass "# passed all $msg"
+                       say "1..$test_count$skip_all"
+               fi
 
                test -d "$remove_trash" &&
                cd "$(dirname "$remove_trash")" &&
@@ -640,7 +698,11 @@ test_done () {
                exit 0 ;;
 
        *)
-               say_color error "failed $test_failure among $msg"
+               if test $test_external_has_tap -eq 0; then
+                       say_color error "# failed $test_failure among $msg"
+                       say "1..$test_count"
+               fi
+
                exit 1 ;;
 
        esac
@@ -648,7 +710,15 @@ test_done () {
 
 # Test the binaries we have just built.  The tests are kept in
 # t/ subdirectory and are run in 'trash directory' subdirectory.
-TEST_DIRECTORY=$(pwd)
+if test -z "$TEST_DIRECTORY"
+then
+       # We allow tests to override this, in case they want to run tests
+       # outside of t/, e.g. for running tests on the test library
+       # itself.
+       TEST_DIRECTORY=$(pwd)
+fi
+GIT_BUILD_DIR="$TEST_DIRECTORY"/..
+
 if test -n "$valgrind"
 then
        make_symlink () {
@@ -675,7 +745,7 @@ then
                test -x "$1" || return
 
                base=$(basename "$1")
-               symlink_target=$TEST_DIRECTORY/../$base
+               symlink_target=$GIT_BUILD_DIR/$base
                # do not override scripts
                if test -x "$symlink_target" &&
                    test ! -d "$symlink_target" &&
@@ -694,7 +764,7 @@ then
        # override all git executables in TEST_DIRECTORY/..
        GIT_VALGRIND=$TEST_DIRECTORY/valgrind
        mkdir -p "$GIT_VALGRIND"/bin
-       for file in $TEST_DIRECTORY/../git* $TEST_DIRECTORY/../test-*
+       for file in $GIT_BUILD_DIR/git* $GIT_BUILD_DIR/test-*
        do
                make_valgrind_symlink $file
        done
@@ -715,10 +785,10 @@ then
 elif test -n "$GIT_TEST_INSTALLED" ; then
        GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path)  ||
        error "Cannot run git from $GIT_TEST_INSTALLED."
-       PATH=$GIT_TEST_INSTALLED:$TEST_DIRECTORY/..:$PATH
+       PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR:$PATH
        GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH}
 else # normal case, use ../bin-wrappers only unless $with_dashes:
-       git_bin_dir="$TEST_DIRECTORY/../bin-wrappers"
+       git_bin_dir="$GIT_BUILD_DIR/bin-wrappers"
        if ! test -x "$git_bin_dir/git" ; then
                if test -z "$with_dashes" ; then
                        say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH"
@@ -726,18 +796,18 @@ else # normal case, use ../bin-wrappers only unless $with_dashes:
                with_dashes=t
        fi
        PATH="$git_bin_dir:$PATH"
-       GIT_EXEC_PATH=$TEST_DIRECTORY/..
+       GIT_EXEC_PATH=$GIT_BUILD_DIR
        if test -n "$with_dashes" ; then
-               PATH="$TEST_DIRECTORY/..:$PATH"
+               PATH="$GIT_BUILD_DIR:$PATH"
        fi
 fi
-GIT_TEMPLATE_DIR=$(pwd)/../templates/blt
+GIT_TEMPLATE_DIR="$GIT_BUILD_DIR"/templates/blt
 unset GIT_CONFIG
 GIT_CONFIG_NOSYSTEM=1
 GIT_CONFIG_NOGLOBAL=1
 export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOBAL
 
-. ../GIT-BUILD-OPTIONS
+. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
 
 if test -z "$GIT_TEST_CMP"
 then
@@ -749,22 +819,22 @@ then
        fi
 fi
 
-GITPERLLIB=$(pwd)/../perl/blib/lib:$(pwd)/../perl/blib/arch/auto/Git
+GITPERLLIB="$GIT_BUILD_DIR"/perl/blib/lib:"$GIT_BUILD_DIR"/perl/blib/arch/auto/Git
 export GITPERLLIB
-test -d ../templates/blt || {
+test -d "$GIT_BUILD_DIR"/templates/blt || {
        error "You haven't built things yet, have you?"
 }
 
 if test -z "$GIT_TEST_INSTALLED" && test -z "$NO_PYTHON"
 then
-       GITPYTHONLIB="$(pwd)/../git_remote_helpers/build/lib"
+       GITPYTHONLIB="$GIT_BUILD_DIR/git_remote_helpers/build/lib"
        export GITPYTHONLIB
-       test -d ../git_remote_helpers/build || {
+       test -d "$GIT_BUILD_DIR"/git_remote_helpers/build || {
                error "You haven't built git_remote_helpers yet, have you?"
        }
 fi
 
-if ! test -x ../test-chmtime; then
+if ! test -x "$GIT_BUILD_DIR"/test-chmtime; then
        echo >&2 'You need to build test-chmtime:'
        echo >&2 'Run "make test-chmtime" in the source (toplevel) directory'
        exit 1
@@ -793,18 +863,10 @@ this_test=${0##*/}
 this_test=${this_test%%-*}
 for skp in $GIT_SKIP_TESTS
 do
-       to_skip=
-       for skp in $GIT_SKIP_TESTS
-       do
-               case "$this_test" in
-               $skp)
-                       to_skip=t
-               esac
-       done
-       case "$to_skip" in
-       t)
+       case "$this_test" in
+       $skp)
                say_color skip >&3 "skipping test $this_test altogether"
-               say_color skip "skip all tests in $this_test"
+               skip_all="skip all tests in $this_test"
                test_done
        esac
 done
@@ -858,3 +920,7 @@ test -z "$NO_PYTHON" && test_set_prereq PYTHON
 # test whether the filesystem supports symbolic links
 ln -s x y 2>/dev/null && test -h y 2>/dev/null && test_set_prereq SYMLINKS
 rm -f y
+
+# When the tests are run as root, permission tests will report that
+# things are writable when they shouldn't be.
+test -w / || test_set_prereq SANITY