submodule: avoid auto-discovery in prepare_submodule_repo_env()
[gitweb.git] / t / test-lib.sh
index ab8461648494848b05170ac402f66acd168baee1..d731d66e3673f0e9d990007dd690c14d84eae783 100644 (file)
@@ -15,9 +15,6 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see http://www.gnu.org/licenses/ .
 
-# Keep the original TERM for say_color
-ORIGINAL_TERM=$TERM
-
 # Test the binaries we have just built.  The tests are kept in
 # t/ subdirectory and are run in 'trash directory' subdirectory.
 if test -z "$TEST_DIRECTORY"
@@ -68,12 +65,12 @@ done,*)
 esac
 
 # For repeatability, reset the environment to known value.
+# TERM is sanitized below, after saving color control sequences.
 LANG=C
 LC_ALL=C
 PAGER=cat
 TZ=UTC
-TERM=dumb
-export LANG LC_ALL PAGER TERM TZ
+export LANG LC_ALL PAGER TZ
 EDITOR=:
 # A call to "unset" with no arguments causes at least Solaris 10
 # /usr/xpg4/bin/sh and /bin/ksh to bail out.  So keep the unsets
@@ -152,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
 
@@ -168,6 +162,9 @@ _x40="$_x05$_x05$_x05$_x05$_x05$_x05$_x05$_x05"
 # Zero SHA-1
 _z40=0000000000000000000000000000000000000000
 
+EMPTY_TREE=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+EMPTY_BLOB=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
+
 # Line feed
 LF='
 '
@@ -176,7 +173,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:
 #
@@ -184,8 +181,14 @@ export _x05 _x40 _z40 LF u200c
 # This test checks if command xyzzy does the right thing...
 # '
 # . ./test-lib.sh
+test "x$TERM" != "xdumb" && (
+               test -t 1 &&
+               tput bold >/dev/null 2>&1 &&
+               tput setaf 1 >/dev/null 2>&1 &&
+               tput sgr0 >/dev/null 2>&1
+       ) &&
+       color=t
 
-unset color
 while test "$#" -ne 0
 do
        case "$1" in
@@ -202,13 +205,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 +225,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
@@ -256,6 +259,44 @@ then
        verbose=t
 fi
 
+if test -n "$color"
+then
+       # Save the color control sequences now rather than run tput
+       # each time say_color() is called.  This is done for two
+       # reasons:
+       #   * TERM will be changed to dumb
+       #   * HOME will be changed to a temporary directory and tput
+       #     might need to read ~/.terminfo from the original HOME
+       #     directory to get the control sequences
+       # Note:  This approach assumes the control sequences don't end
+       # in a newline for any terminal of interest (command
+       # substitutions strip trailing newlines).  Given that most
+       # (all?) terminals in common use are related to ECMA-48, this
+       # shouldn't be a problem.
+       say_color_error=$(tput bold; tput setaf 1) # bold red
+       say_color_skip=$(tput setaf 4) # blue
+       say_color_warn=$(tput setaf 3) # brown/yellow
+       say_color_pass=$(tput setaf 2) # green
+       say_color_info=$(tput setaf 6) # cyan
+       say_color_reset=$(tput sgr0)
+       say_color_="" # no formatting for normal text
+       say_color () {
+               test -z "$1" && test -n "$quiet" && return
+               eval "say_color_color=\$say_color_$1"
+               shift
+               printf "%s\\n" "$say_color_color$*$say_color_reset"
+       }
+else
+       say_color() {
+               test -z "$1" && test -n "$quiet" && return
+               shift
+               printf "%s\n" "$*"
+       }
+fi
+
+TERM=dumb
+export TERM
+
 error () {
        say_color error "error: $*"
        GIT_EXIT_OK=t
@@ -284,6 +325,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
@@ -305,6 +359,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
@@ -746,7 +801,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
@@ -815,10 +870,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
 
@@ -840,52 +895,6 @@ HOME="$TRASH_DIRECTORY"
 GNUPGHOME="$HOME/gnupg-home-not-used"
 export HOME GNUPGHOME
 
-# run the tput tests *after* changing HOME (in case ncurses needs
-# ~/.terminfo for $TERM)
-test -n "${color+set}" || test "x$ORIGINAL_TERM" != "xdumb" && (
-               TERM=$ORIGINAL_TERM &&
-               export TERM &&
-               test -t 1 &&
-               tput bold >/dev/null 2>&1 &&
-               tput setaf 1 >/dev/null 2>&1 &&
-               tput sgr0 >/dev/null 2>&1
-       ) &&
-       color=t
-
-if test -n "$color"
-then
-       say_color () {
-               (
-               TERM=$ORIGINAL_TERM
-               export TERM
-               case "$1" in
-               error)
-                       tput bold; tput setaf 1;; # bold red
-               skip)
-                       tput setaf 4;; # blue
-               warn)
-                       tput setaf 3;; # brown/yellow
-               pass)
-                       tput setaf 2;; # green
-               info)
-                       tput setaf 6;; # cyan
-               *)
-                       test -n "$quiet" && return;;
-               esac
-               shift
-               printf "%s" "$*"
-               tput sgr0
-               echo
-               )
-       }
-else
-       say_color() {
-               test -z "$1" && test -n "$quiet" && return
-               shift
-               printf "%s\n" "$*"
-       }
-fi
-
 if test -z "$TEST_NO_CREATE_REPO"
 then
        test_create_repo "$TRASH_DIRECTORY"
@@ -914,9 +923,11 @@ yes () {
                y="$*"
        fi
 
-       while echo "$y"
+       i=0
+       while test $i -lt 99
        do
-               :
+               echo "$y"
+               i=$(($i+1))
        done
 }
 
@@ -1005,7 +1016,7 @@ test_i18ngrep () {
 test_lazy_prereq PIPE '
        # test whether the filesystem supports FIFOs
        case $(uname -s) in
-       CYGWIN*)
+       CYGWIN*|MINGW*)
                false
                ;;
        *)
@@ -1061,20 +1072,28 @@ test_lazy_prereq NOT_ROOT '
        test "$uid" != 0
 '
 
-# On a filesystem that lacks SANITY, a file can be deleted even if
-# the containing directory doesn't have write permissions, or a file
-# can be accessed even if the containing directory doesn't have read
-# or execute permissions, causing our tests that validate that Git
-# works sensibly in such situations.
+# 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=$?
 
@@ -1089,3 +1108,18 @@ 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)"
+'