Merge branch 'jk/test-suite-tracing'
authorJunio C Hamano <gitster@pobox.com>
Fri, 5 Jan 2018 21:28:09 +0000 (13:28 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 5 Jan 2018 21:28:09 +0000 (13:28 -0800)
Assorted fixes around running tests with "-x" tracing option.

* jk/test-suite-tracing:
t/Makefile: introduce TEST_SHELL_PATH
test-lib: make "-x" work with "--verbose-log"
t5615: avoid re-using descriptor 4
test-lib: silence "-x" cleanup under bash

Makefile
t/Makefile
t/t5615-alternate-env.sh
t/test-lib.sh
index 2a81ae22e92cc5a92507666340d340cef3c6b418..bb5b7cdfb695ee7f15128d5885ea74a4e34f5b9b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -426,6 +426,10 @@ all::
 # to say "export LESS=FRX (and LV=-c) if the environment variable
 # LESS (and LV) is not set, respectively".
 #
+# Define TEST_SHELL_PATH if you want to use a shell besides SHELL_PATH for
+# running the test scripts (e.g., bash has better support for "set -x"
+# tracing).
+#
 # When cross-compiling, define HOST_CPU as the canonical name of the CPU on
 # which the built Git will run (for instance "x86_64").
 
@@ -733,6 +737,8 @@ endif
 export PERL_PATH
 export PYTHON_PATH
 
+TEST_SHELL_PATH = $(SHELL_PATH)
+
 LIB_FILE = libgit.a
 XDIFF_LIB = xdiff/lib.a
 VCSSVN_LIB = vcs-svn/lib.a
@@ -1738,6 +1744,7 @@ prefix_SQ = $(subst ','\'',$(prefix))
 gitwebdir_SQ = $(subst ','\'',$(gitwebdir))
 
 SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
+TEST_SHELL_PATH_SQ = $(subst ','\'',$(TEST_SHELL_PATH))
 PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
 PYTHON_PATH_SQ = $(subst ','\'',$(PYTHON_PATH))
 TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
@@ -2370,6 +2377,7 @@ GIT-LDFLAGS: FORCE
 # and the first level quoting from the shell that runs "echo".
 GIT-BUILD-OPTIONS: FORCE
        @echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@+
+       @echo TEST_SHELL_PATH=\''$(subst ','\'',$(TEST_SHELL_PATH_SQ))'\' >>$@+
        @echo PERL_PATH=\''$(subst ','\'',$(PERL_PATH_SQ))'\' >>$@+
        @echo DIFF=\''$(subst ','\'',$(subst ','\'',$(DIFF)))'\' >>$@+
        @echo PYTHON_PATH=\''$(subst ','\'',$(PYTHON_PATH_SQ))'\' >>$@+
index 1bb06c36f22d9fa0fb01fb8dfad02ffa9f338ebd..96317a35f4df9944cd3b9f64db0db3132d69da6e 100644 (file)
@@ -8,6 +8,7 @@
 
 #GIT_TEST_OPTS = --verbose --debug
 SHELL_PATH ?= $(SHELL)
+TEST_SHELL_PATH ?= $(SHELL_PATH)
 PERL_PATH ?= /usr/bin/perl
 TAR ?= $(TAR)
 RM ?= rm -f
@@ -23,6 +24,7 @@ endif
 
 # Shell quote;
 SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
+TEST_SHELL_PATH_SQ = $(subst ','\'',$(TEST_SHELL_PATH))
 PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
 TEST_RESULTS_DIRECTORY_SQ = $(subst ','\'',$(TEST_RESULTS_DIRECTORY))
 
@@ -42,11 +44,11 @@ failed:
        test -z "$$failed" || $(MAKE) $$failed
 
 prove: pre-clean $(TEST_LINT)
-       @echo "*** prove ***"; $(PROVE) --exec '$(SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)
+       @echo "*** prove ***"; $(PROVE) --exec '$(TEST_SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)
        $(MAKE) clean-except-prove-cache
 
 $(T):
-       @echo "*** $@ ***"; '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
+       @echo "*** $@ ***"; '$(TEST_SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
 
 pre-clean:
        $(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'
index d2d883f3a1d473a2b69fab05adbb21e67e5e600c..b4905b822c07048ddfbc43cfd39265bd2116f197 100755 (executable)
@@ -7,9 +7,9 @@ check_obj () {
        alt=$1; shift
        while read obj expect
        do
-               echo "$obj" >&3 &&
-               echo "$obj $expect" >&4
-       done 3>input 4>expect &&
+               echo "$obj" >&5 &&
+               echo "$obj $expect" >&6
+       done 5>input 6>expect &&
        GIT_ALTERNATE_OBJECT_DIRECTORIES=$alt \
                git "$@" cat-file --batch-check='%(objectname) %(objecttype)' \
                <input >actual &&
index e7065df2bb028aff76f3169d84873a1a3d789571..9a0a21f49ae7bef3d0a1b653cce811d12499672e 100644 (file)
@@ -80,7 +80,7 @@ done,*)
        # from any previous runs.
        >"$GIT_TEST_TEE_OUTPUT_FILE"
 
-       (GIT_TEST_TEE_STARTED=done ${SHELL_PATH} "$0" "$@" 2>&1;
+       (GIT_TEST_TEE_STARTED=done ${TEST_SHELL_PATH} "$0" "$@" 2>&1;
         echo $? >"$BASE.exit") | tee -a "$GIT_TEST_TEE_OUTPUT_FILE"
        test "$(cat "$BASE.exit")" = 0
        exit
@@ -264,7 +264,6 @@ do
                shift ;;
        -x)
                trace=t
-               verbose=t
                shift ;;
        --verbose-log)
                verbose_log=t
@@ -283,6 +282,11 @@ then
        test -z "$verbose_log" && verbose=t
 fi
 
+if test -n "$trace" && test -z "$verbose_log"
+then
+       verbose=t
+fi
+
 if test -n "$color"
 then
        # Save the color control sequences now rather than run tput
@@ -586,7 +590,9 @@ maybe_setup_valgrind () {
 }
 
 want_trace () {
-       test "$trace" = t && test "$verbose" = t
+       test "$trace" = t && {
+               test "$verbose" = t || test "$verbose_log" = t
+       }
 }
 
 # This is a separate function because some tests use
@@ -601,26 +607,40 @@ test_eval_inner_ () {
 }
 
 test_eval_ () {
-       # We run this block with stderr redirected to avoid extra cruft
-       # during a "-x" trace. Once in "set -x" mode, we cannot prevent
+       # If "-x" tracing is in effect, then we want to avoid polluting stderr
+       # with non-test commands. But once in "set -x" mode, we cannot prevent
        # the shell from printing the "set +x" to turn it off (nor the saving
        # of $? before that). But we can make sure that the output goes to
        # /dev/null.
        #
-       # The test itself is run with stderr put back to &4 (so either to
-       # /dev/null, or to the original stderr if --verbose was used).
+       # There are a few subtleties here:
+       #
+       #   - we have to redirect descriptor 4 in addition to 2, to cover
+       #     BASH_XTRACEFD
+       #
+       #   - the actual eval has to come before the redirection block (since
+       #     it needs to see descriptor 4 to set up its stderr)
+       #
+       #   - likewise, any error message we print must be outside the block to
+       #     access descriptor 4
+       #
+       #   - checking $? has to come immediately after the eval, but it must
+       #     be _inside_ the block to avoid polluting the "set -x" output
+       #
+
+       test_eval_inner_ "$@" </dev/null >&3 2>&4
        {
-               test_eval_inner_ "$@" </dev/null >&3 2>&4
                test_eval_ret_=$?
                if want_trace
                then
                        set +x
-                       if test "$test_eval_ret_" != 0
-                       then
-                               say_color error >&4 "error: last command exited with \$?=$test_eval_ret_"
-                       fi
                fi
-       } 2>/dev/null
+       } 2>/dev/null 4>&2
+
+       if test "$test_eval_ret_" != 0 && want_trace
+       then
+               say_color error >&4 "error: last command exited with \$?=$test_eval_ret_"
+       fi
        return $test_eval_ret_
 }