Git 2.23
[gitweb.git] / t / test-lib.sh
index 25e649c997bbe4dfa03f1eca1f1591181efab5a3..30b07e310f59493616f766ea6cf7c45a335c9258 100644 (file)
@@ -57,6 +57,13 @@ fi
 . "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
 export PERL_PATH SHELL_PATH
 
+# Disallow the use of abbreviated options in the test suite by default
+if test -z "${GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS}"
+then
+       GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=true
+       export GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS
+fi
+
 ################################################################
 # It appears that people try to run tests without building...
 "${GIT_TEST_INSTALLED:-$GIT_BUILD_DIR}/git$X" >/dev/null
@@ -147,10 +154,28 @@ do
        --stress)
                stress=t ;;
        --stress=*)
+               echo "error: --stress does not accept an argument: '$opt'" >&2
+               echo "did you mean --stress-jobs=${opt#*=} or --stress-limit=${opt#*=}?" >&2
+               exit 1
+               ;;
+       --stress-jobs=*)
+               stress=t;
                stress=${opt#--*=}
                case "$stress" in
-               *[^0-9]*|0*|"")
-                       echo "error: --stress=<N> requires the number of jobs to run" >&2
+               *[!0-9]*|0*|"")
+                       echo "error: --stress-jobs=<N> requires the number of jobs to run" >&2
+                       exit 1
+                       ;;
+               *)      # Good.
+                       ;;
+               esac
+               ;;
+       --stress-limit=*)
+               stress=t;
+               stress_limit=${opt#--*=}
+               case "$stress_limit" in
+               *[!0-9]*|0*|"")
+                       echo "error: --stress-limit=<N> requires the number of repetitions" >&2
                        exit 1
                        ;;
                *)      # Good.
@@ -242,8 +267,10 @@ then
                                exit 1
                        ' TERM INT
 
-                       cnt=0
-                       while ! test -e "$stressfail"
+                       cnt=1
+                       while ! test -e "$stressfail" &&
+                             { test -z "$stress_limit" ||
+                               test $cnt -le $stress_limit ; }
                        do
                                $TEST_SHELL_PATH "$0" "$@" >"$TEST_RESULTS_BASE.stress-$job_nr.out" 2>&1 &
                                test_pid=$!
@@ -266,6 +293,7 @@ then
 
        if test -f "$stressfail"
        then
+               stress_exit=1
                echo "Log(s) of failed test run(s):"
                for failed_job_nr in $(sort -n "$stressfail")
                do
@@ -606,6 +634,10 @@ test_external_has_tap=0
 
 die () {
        code=$?
+       # This is responsible for running the atexit commands even when a
+       # test script run with '--immediate' fails, or when the user hits
+       # ctrl-C, i.e. when 'test_done' is not invoked at all.
+       test_atexit_handler || code=$?
        if test -n "$GIT_EXIT_OK"
        then
                exit $code
@@ -617,7 +649,10 @@ die () {
 
 GIT_EXIT_OK=
 trap 'die' EXIT
-trap 'exit $?' INT TERM HUP
+# Disable '-x' tracing, because with some shells, notably dash, it
+# prevents running the cleanup commands when a test script run with
+# '--verbose-log -x' is interrupted.
+trap '{ code=$?; set +x; } 2>/dev/null; exit $code' INT TERM HUP
 
 # The user-facing functions are loaded from a separate file so that
 # test_perf subshells can have them too
@@ -1028,9 +1063,28 @@ write_junit_xml_testcase () {
        junit_have_testcase=t
 }
 
+test_atexit_cleanup=:
+test_atexit_handler () {
+       # In a succeeding test script 'test_atexit_handler' is invoked
+       # twice: first from 'test_done', then from 'die' in the trap on
+       # EXIT.
+       # This condition and resetting 'test_atexit_cleanup' below makes
+       # sure that the registered cleanup commands are run only once.
+       test : != "$test_atexit_cleanup" || return 0
+
+       setup_malloc_check
+       test_eval_ "$test_atexit_cleanup"
+       test_atexit_cleanup=:
+       teardown_malloc_check
+}
+
 test_done () {
        GIT_EXIT_OK=t
 
+       # Run the atexit commands _before_ the trash directory is
+       # removed, so the commands can access pidfiles and socket files.
+       test_atexit_handler
+
        if test -n "$write_junit_xml" && test -n "$junit_xml_path"
        then
                test -n "$junit_have_testcase" || {
@@ -1258,7 +1312,7 @@ test -d "$GIT_BUILD_DIR"/templates/blt || {
        error "You haven't built things yet, have you?"
 }
 
-if ! test -x "$GIT_BUILD_DIR"/t/helper/test-tool
+if ! test -x "$GIT_BUILD_DIR"/t/helper/test-tool$X
 then
        echo >&2 'You need to build test-tool:'
        echo >&2 'Run "make t/helper/test-tool" in the source (toplevel) directory'
@@ -1313,7 +1367,11 @@ then
        fi
 fi
 
-# Provide an implementation of the 'yes' utility
+# Provide an implementation of the 'yes' utility; the upper bound
+# limit is there to help Windows that cannot stop this loop from
+# wasting cycles when the downstream stops reading, so do not be
+# tempted to turn it into an infinite loop. cf. 6129c930 ("test-lib:
+# limit the output of the yes utility", 2016-02-02)
 yes () {
        if test $# = 0
        then
@@ -1330,6 +1388,25 @@ yes () {
        done
 }
 
+# The GIT_TEST_FAIL_PREREQS code hooks into test_set_prereq(), and
+# thus needs to be set up really early, and set an internal variable
+# for convenience so the hot test_set_prereq() codepath doesn't need
+# to call "git env--helper". Only do that work if needed by seeing if
+# GIT_TEST_FAIL_PREREQS is set at all.
+GIT_TEST_FAIL_PREREQS_INTERNAL=
+if test -n "$GIT_TEST_FAIL_PREREQS"
+then
+       if git env--helper --type=bool --default=0 --exit-code GIT_TEST_FAIL_PREREQS
+       then
+               GIT_TEST_FAIL_PREREQS_INTERNAL=true
+               test_set_prereq FAIL_PREREQS
+       fi
+else
+       test_lazy_prereq FAIL_PREREQS '
+               git env--helper --type=bool --default=0 --exit-code GIT_TEST_FAIL_PREREQS
+       '
+fi
+
 # Fix some commands on Windows
 uname_s=$(uname -s)
 case $uname_s in
@@ -1380,14 +1457,13 @@ test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
 if test -n "$GIT_TEST_GETTEXT_POISON_ORIG"
 then
        GIT_TEST_GETTEXT_POISON=$GIT_TEST_GETTEXT_POISON_ORIG
+       export GIT_TEST_GETTEXT_POISON
        unset GIT_TEST_GETTEXT_POISON_ORIG
 fi
 
-# Can we rely on git's output in the C locale?
-if test -z "$GIT_TEST_GETTEXT_POISON"
-then
-       test_set_prereq C_LOCALE_OUTPUT
-fi
+test_lazy_prereq C_LOCALE_OUTPUT '
+       ! git env--helper --type=bool --default=0 --exit-code GIT_TEST_GETTEXT_POISON
+'
 
 if test -z "$GIT_TEST_CHECK_CACHE_TREE"
 then
@@ -1462,7 +1538,7 @@ test_lazy_prereq NOT_ROOT '
 '
 
 test_lazy_prereq JGIT '
-       type jgit
+       jgit --version
 '
 
 # SANITY is about "can you correctly predict what the filesystem would