pack-objects: compute local/ignore_pack_keep early
[gitweb.git] / t / test-lib.sh
index 33bbfd57afeb59aebd28fd1a28ea33db631a4188..11201e9cf8320a0f90e4848d8bfe4ccd2ba92c88 100644 (file)
@@ -149,10 +149,7 @@ unset UNZIP
 
 case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in
 1|2|true)
-       echo "* warning: Some tests will not work if GIT_TRACE" \
-               "is set as to trace on STDERR ! *"
-       echo "* warning: Please set GIT_TRACE to something" \
-               "other than 1, 2 or true ! *"
+       GIT_TRACE=4
        ;;
 esac
 
@@ -205,13 +202,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
@@ -225,15 +222,21 @@ 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
+               shift ;;
+       --no-chain-lint)
+               GIT_TEST_CHAIN_LINT=0
                shift ;;
        -x)
                trace=t
@@ -319,6 +322,19 @@ 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
@@ -340,6 +356,7 @@ die () {
 
 GIT_EXIT_OK=
 trap 'die' EXIT
+trap 'exit $?' INT
 
 # The user-facing functions are loaded from a separate file so that
 # test_perf subshells can have them too
@@ -527,6 +544,10 @@ maybe_setup_valgrind () {
        fi
 }
 
+want_trace () {
+       test "$trace" = t && test "$verbose" = t
+}
+
 # This is a separate function because some tests use
 # "return" to end a test_expect_success block early
 # (and we want to make sure we run any cleanup like
@@ -534,7 +555,7 @@ maybe_setup_valgrind () {
 test_eval_inner_ () {
        # Do not add anything extra (including LF) after '$*'
        eval "
-               test \"$trace\" = t && set -x
+               want_trace && set -x
                $*"
 }
 
@@ -550,7 +571,7 @@ test_eval_ () {
        {
                test_eval_inner_ "$@" </dev/null >&3 2>&4
                test_eval_ret_=$?
-               if test "$trace" = t
+               if want_trace
                then
                        set +x
                        if test "$test_eval_ret_" != 0
@@ -565,6 +586,21 @@ test_eval_ () {
 test_run_ () {
        test_cleanup=:
        expecting_failure=$2
+
+       if test "${GIT_TEST_CHAIN_LINT:-1}" != 0; then
+               # turn off tracing for this test-eval, as it simply creates
+               # confusing noise in the "-x" output
+               trace_tmp=$trace
+               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"
+               fi
+               trace=$trace_tmp
+       fi
+
        setup_malloc_check
        test_eval_ "$1"
        eval_ret=$?
@@ -831,10 +867,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
 
@@ -884,9 +920,11 @@ yes () {
                y="$*"
        fi
 
-       while echo "$y"
+       i=0
+       while test $i -lt 99
        do
-               :
+               echo "$y"
+               i=$(($i+1))
        done
 }
 
@@ -975,7 +1013,7 @@ test_i18ngrep () {
 test_lazy_prereq PIPE '
        # test whether the filesystem supports FIFOs
        case $(uname -s) in
-       CYGWIN*)
+       CYGWIN*|MINGW*)
                false
                ;;
        *)
@@ -1026,12 +1064,59 @@ test_lazy_prereq USR_BIN_TIME '
        test -x /usr/bin/time
 '
 
-# 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
+test_lazy_prereq NOT_ROOT '
+       uid=$(id -u) &&
+       test "$uid" != 0
+'
+
+# 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
+# suite as root, where a test may expect "chmod -r file && cat file"
+# to fail because file is supposed to be unreadable after a successful
+# chmod.  In an environment (i.e. combination of what filesystem is
+# being used and who is running the tests) that lacks SANITY, you may
+# be able to delete or create a file when the containing directory
+# doesn't have write permissions, or access a file even if the
+# containing directory doesn't have read or execute permissions.
+
+test_lazy_prereq SANITY '
+       mkdir SANETESTD.1 SANETESTD.2 &&
+
+       chmod +w SANETESTD.1 SANETESTD.2 &&
+       >SANETESTD.1/x 2>SANETESTD.2/x &&
+       chmod -w SANETESTD.1 &&
+       chmod -r SANETESTD.1/x &&
+       chmod -rx SANETESTD.2 ||
+       error "bug in test sript: cannot prepare SANETESTD"
+
+       ! test -r SANETESTD.1/x &&
+       ! rm SANETESTD.1/x && ! test -f SANETESTD.2/x
+       status=$?
+
+       chmod +rwx SANETESTD.1 SANETESTD.2 &&
+       rm -rf SANETESTD.1 SANETESTD.2 ||
+       error "bug in test sript: cannot clean SANETESTD"
+       return $status
+'
 
 GIT_UNZIP=${GIT_UNZIP:-unzip}
 test_lazy_prereq UNZIP '
        "$GIT_UNZIP" -v
        test $? -ne 127
 '
+
+run_with_limited_cmdline () {
+       (ulimit -s 128 && "$@")
+}
+
+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)"
+'