Merge branch 'jk/sanity' into maint
authorJunio C Hamano <gitster@pobox.com>
Fri, 5 Feb 2016 22:54:14 +0000 (14:54 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 5 Feb 2016 22:54:14 +0000 (14:54 -0800)
The description for SANITY prerequisite the test suite uses has
been clarified both in the comment and in the implementation.

* jk/sanity:
  test-lib: clarify and tighten SANITY

1  2 
t/test-lib.sh

diff --combined t/test-lib.sh
@@@ -15,6 -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"
@@@ -65,12 -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
@@@ -137,9 -140,6 +137,9 @@@ els
        }
  fi
  
 +: ${ASAN_OPTIONS=detect_leaks=0}
 +export ASAN_OPTIONS
 +
  # Protect ourselves from common misconfiguration to export
  # CDPATH into the environment
  unset CDPATH
@@@ -149,7 -149,10 +149,7 @@@ unset UNZI
  
  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
  
@@@ -178,8 -181,10 +178,8 @@@ export _x05 _x40 _z40 LF u200
  # This test checks if command xyzzy does the right thing...
  # '
  # . ./test-lib.sh
 -[ "x$ORIGINAL_TERM" != "xdumb" ] && (
 -              TERM=$ORIGINAL_TERM &&
 -              export TERM &&
 -              [ -t 1 ] &&
 +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
        --root=*)
                root=$(expr "z$1" : 'z[^=]*=\(.*\)')
                shift ;;
 +      --chain-lint)
 +              GIT_TEST_CHAIN_LINT=1
 +              shift ;;
 +      --no-chain-lint)
 +              GIT_TEST_CHAIN_LINT=0
 +              shift ;;
 +      -x)
 +              trace=t
 +              verbose=t
 +              shift ;;
        *)
                echo "error: unknown test option '$1'" >&2; exit 1 ;;
        esac
  
  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 () {
 -              (
 -              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
 +              test -z "$1" && test -n "$quiet" && return
 +              eval "say_color_color=\$say_color_$1"
                shift
 -              printf "%s" "$*"
 -              tput sgr0
 -              echo
 -              )
 +              printf "%s\\n" "$say_color_color$*$say_color_reset"
        }
  else
        say_color() {
        }
  fi
  
 +TERM=dumb
 +export TERM
 +
  error () {
        say_color error "error: $*"
        GIT_EXIT_OK=t
@@@ -343,7 -334,6 +343,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
@@@ -531,70 -521,21 +531,70 @@@ 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
 +# "set +x").
 +test_eval_inner_ () {
 +      # Do not add anything extra (including LF) after '$*'
 +      eval "
 +              want_trace && set -x
 +              $*"
 +}
 +
  test_eval_ () {
 -      # This is a separate function because some tests use
 -      # "return" to end a test_expect_success block early.
 -      eval </dev/null >&3 2>&4 "$*"
 +      # We run this block with stderr redirected to avoid extra cruft
 +      # during a "-x" trace. 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).
 +      {
 +              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
 +      return $test_eval_ret_
  }
  
  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=$?
        teardown_malloc_check
  
 -      if test -z "$immediate" || test $eval_ret = 0 || test -n "$expecting_failure"
 +      if test -z "$immediate" || test $eval_ret = 0 ||
 +         test -n "$expecting_failure" && test "$test_cleanup" != ":"
        then
                setup_malloc_check
                test_eval_ "$test_cleanup"
@@@ -706,7 -647,7 +706,7 @@@ test_done () 
                then
                        error "Can't use skip_all after running some tests"
                fi
 -              [ -z "$skip_all" ] || skip_all=" # SKIP $skip_all"
 +              test -z "$skip_all" || skip_all=" # SKIP $skip_all"
  
                if test $test_external_has_tap -eq 0
                then
@@@ -876,8 -817,7 +876,8 @@@ rm -fr "$TRASH_DIRECTORY" || 
  }
  
  HOME="$TRASH_DIRECTORY"
 -export HOME
 +GNUPGHOME="$HOME/gnupg-home-not-used"
 +export HOME GNUPGHOME
  
  if test -z "$TEST_NO_CREATE_REPO"
  then
@@@ -934,7 -874,7 +934,7 @@@ case $(uname -s) i
        # backslashes in pathspec are converted to '/'
        # exec does not inherit the PID
        test_set_prereq MINGW
 -      test_set_prereq NOT_CYGWIN
 +      test_set_prereq NATIVE_CRLF
        test_set_prereq SED_STRIPS_CR
        test_set_prereq GREP_STRIPS_CR
        GIT_TEST_CMP=mingw_test_cmp
  *CYGWIN*)
        test_set_prereq POSIXPERM
        test_set_prereq EXECKEEPSPID
 -      test_set_prereq NOT_MINGW
        test_set_prereq CYGWIN
        test_set_prereq SED_STRIPS_CR
        test_set_prereq GREP_STRIPS_CR
        test_set_prereq POSIXPERM
        test_set_prereq BSLASHPSPEC
        test_set_prereq EXECKEEPSPID
 -      test_set_prereq NOT_MINGW
 -      test_set_prereq NOT_CYGWIN
        ;;
  esac
  
@@@ -1054,20 -997,28 +1054,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=$?
  
@@@ -1082,9 -1033,3 +1090,9 @@@ 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'