Merge branch 'sg/show-failed-test-names'
authorJunio C Hamano <gitster@pobox.com>
Thu, 22 Aug 2019 19:34:11 +0000 (12:34 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 22 Aug 2019 19:34:11 +0000 (12:34 -0700)
The first line of verbose output from each test piece now carries
the test name and number to help scanning with eyeballs.

* sg/show-failed-test-names:
tests: show the test name and number at the start of verbose output
t0000-basic: use realistic test script names in the verbose tests

1  2 
t/t0000-basic.sh
t/test-lib-functions.sh
t/test-lib.sh
diff --combined t/t0000-basic.sh
index 9ca0818cbe4c1fb7f7d4c4558f00c5dabc0ae778,8ba34efefca10e1816136ea29df8e84c25404a7a..4c01f60dd3ca0f2cab26298dbc795e08a61b819b
@@@ -25,14 -25,16 +25,14 @@@ try_local_x () 
        echo "$x"
  }
  
 -# This test is an experiment to check whether any Git users are using
 -# Shells that don't support the "local" keyword. "local" is not
 +# Check whether the shell supports the "local" keyword. "local" is not
  # POSIX-standard, but it is very widely supported by POSIX-compliant
 -# shells, and if it doesn't cause problems for people, we would like
 -# to be able to use it in Git code.
 +# shells, and we rely on it within Git's test framework.
  #
 -# For now, this is the only test that requires "local". If your shell
 -# fails this test, you can ignore the failure, but please report the
 -# problem to the Git mailing list <git@vger.kernel.org>, as it might
 -# convince us to continue avoiding the use of "local".
 +# If your shell fails this test, the results of other tests may be
 +# unreliable. You may wish to report the problem to the Git mailing
 +# list <git@vger.kernel.org>, as it could cause us to reconsider
 +# relying on "local".
  test_expect_success 'verify that the running shell supports "local"' '
        x="notlocal" &&
        echo "local" >expected1 &&
@@@ -274,23 -276,23 +274,23 @@@ test_expect_success 'pretend we have a 
  
  test_expect_success C_LOCALE_OUTPUT 'test --verbose' '
        test_must_fail run_sub_test_lib_test \
-               test-verbose "test verbose" --verbose <<-\EOF &&
+               t1234-verbose "test verbose" --verbose <<-\EOF &&
        test_expect_success "passing test" true
        test_expect_success "test with output" "echo foo"
        test_expect_success "failing test" false
        test_done
        EOF
-       mv test-verbose/out test-verbose/out+ &&
-       grep -v "^Initialized empty" test-verbose/out+ >test-verbose/out &&
-       check_sub_test_lib_test test-verbose <<-\EOF
-       > expecting success: true
+       mv t1234-verbose/out t1234-verbose/out+ &&
+       grep -v "^Initialized empty" t1234-verbose/out+ >t1234-verbose/out &&
+       check_sub_test_lib_test t1234-verbose <<-\EOF
+       > expecting success of 1234.1 '\''passing test'\'': true
        > ok 1 - passing test
        > Z
-       > expecting success: echo foo
+       > expecting success of 1234.2 '\''test with output'\'': echo foo
        > foo
        > ok 2 - test with output
        > Z
-       > expecting success: false
+       > expecting success of 1234.3 '\''failing test'\'': false
        > not ok 3 - failing test
        > #     false
        > Z
  
  test_expect_success 'test --verbose-only' '
        test_must_fail run_sub_test_lib_test \
-               test-verbose-only-2 "test verbose-only=2" \
+               t2345-verbose-only-2 "test verbose-only=2" \
                --verbose-only=2 <<-\EOF &&
        test_expect_success "passing test" true
        test_expect_success "test with output" "echo foo"
        test_expect_success "failing test" false
        test_done
        EOF
-       check_sub_test_lib_test test-verbose-only-2 <<-\EOF
+       check_sub_test_lib_test t2345-verbose-only-2 <<-\EOF
        > ok 1 - passing test
        > Z
-       > expecting success: echo foo
+       > expecting success of 2345.2 '\''test with output'\'': echo foo
        > foo
        > ok 2 - test with output
        > Z
@@@ -724,7 -726,7 +724,7 @@@ donthaveit=ye
  test_expect_success DONTHAVEIT 'unmet prerequisite causes test to be skipped' '
        donthaveit=no
  '
 -if test $haveit$donthaveit != yesyes
 +if test -z "$GIT_TEST_FAIL_PREREQS_INTERNAL" -a $haveit$donthaveit != yesyes
  then
        say "bug in test framework: prerequisite tags do not work reliably"
        exit 1
@@@ -745,7 -747,7 +745,7 @@@ donthaveiteither=ye
  test_expect_success DONTHAVEIT,HAVEIT 'unmet prerequisites causes test to be skipped' '
        donthaveiteither=no
  '
 -if test $haveit$donthaveit$donthaveiteither != yesyesyes
 +if test -z "$GIT_TEST_FAIL_PREREQS_INTERNAL" -a $haveit$donthaveit$donthaveiteither != yesyesyes
  then
        say "bug in test framework: multiple prerequisite tags do not work reliably"
        exit 1
@@@ -761,7 -763,7 +761,7 @@@ test_expect_success !LAZY_TRUE 'missin
        donthavetrue=no
  '
  
 -if test "$havetrue$donthavetrue" != yesyes
 +if test -z "$GIT_TEST_FAIL_PREREQS_INTERNAL" -a "$havetrue$donthavetrue" != yesyes
  then
        say 'bug in test framework: lazy prerequisites do not work'
        exit 1
@@@ -777,7 -779,7 +777,7 @@@ test_expect_success LAZY_FALSE 'missin
        havefalse=no
  '
  
 -if test "$nothavefalse$havefalse" != yesyes
 +if test -z "$GIT_TEST_FAIL_PREREQS_INTERNAL" -a "$nothavefalse$havefalse" != yesyes
  then
        say 'bug in test framework: negative lazy prerequisites do not work'
        exit 1
@@@ -788,7 -790,7 +788,7 @@@ test_expect_success 'tests clean up aft
        test_when_finished clean=yes
  '
  
 -if test $clean != yes
 +if test -z "$GIT_TEST_FAIL_PREREQS_INTERNAL" -a $clean != yes
  then
        say "bug in test framework: basic cleanup command does not work reliably"
        exit 1
diff --combined t/test-lib-functions.sh
index e0b3f28d3a96e1b937f4c31e0a3d2e8fb3e6fed5,cb3941beea619dda056725a0df65e820c73164bb..87bf3a2287381be4586eccd94cce35c0a3b3d60f
@@@ -233,129 -233,6 +233,129 @@@ test_merge () 
        git tag "$1"
  }
  
 +# Efficiently create <nr> commits, each with a unique number (from 1 to <nr>
 +# by default) in the commit message.
 +#
 +# Usage: test_commit_bulk [options] <nr>
 +#   -C <dir>:
 +#     Run all git commands in directory <dir>
 +#   --ref=<n>:
 +#     ref on which to create commits (default: HEAD)
 +#   --start=<n>:
 +#     number commit messages from <n> (default: 1)
 +#   --message=<msg>:
 +#     use <msg> as the commit mesasge (default: "commit %s")
 +#   --filename=<fn>:
 +#     modify <fn> in each commit (default: %s.t)
 +#   --contents=<string>:
 +#     place <string> in each file (default: "content %s")
 +#   --id=<string>:
 +#     shorthand to use <string> and %s in message, filename, and contents
 +#
 +# The message, filename, and contents strings are evaluated by printf, with the
 +# first "%s" replaced by the current commit number. So you can do:
 +#
 +#   test_commit_bulk --filename=file --contents="modification %s"
 +#
 +# to have every commit touch the same file, but with unique content.
 +#
 +test_commit_bulk () {
 +      tmpfile=.bulk-commit.input
 +      indir=.
 +      ref=HEAD
 +      n=1
 +      message='commit %s'
 +      filename='%s.t'
 +      contents='content %s'
 +      while test $# -gt 0
 +      do
 +              case "$1" in
 +              -C)
 +                      indir=$2
 +                      shift
 +                      ;;
 +              --ref=*)
 +                      ref=${1#--*=}
 +                      ;;
 +              --start=*)
 +                      n=${1#--*=}
 +                      ;;
 +              --message=*)
 +                      message=${1#--*=}
 +                      ;;
 +              --filename=*)
 +                      filename=${1#--*=}
 +                      ;;
 +              --contents=*)
 +                      contents=${1#--*=}
 +                      ;;
 +              --id=*)
 +                      message="${1#--*=} %s"
 +                      filename="${1#--*=}-%s.t"
 +                      contents="${1#--*=} %s"
 +                      ;;
 +              -*)
 +                      BUG "invalid test_commit_bulk option: $1"
 +                      ;;
 +              *)
 +                      break
 +                      ;;
 +              esac
 +              shift
 +      done
 +      total=$1
 +
 +      add_from=
 +      if git -C "$indir" rev-parse --verify "$ref"
 +      then
 +              add_from=t
 +      fi
 +
 +      while test "$total" -gt 0
 +      do
 +              test_tick &&
 +              echo "commit $ref"
 +              printf 'author %s <%s> %s\n' \
 +                      "$GIT_AUTHOR_NAME" \
 +                      "$GIT_AUTHOR_EMAIL" \
 +                      "$GIT_AUTHOR_DATE"
 +              printf 'committer %s <%s> %s\n' \
 +                      "$GIT_COMMITTER_NAME" \
 +                      "$GIT_COMMITTER_EMAIL" \
 +                      "$GIT_COMMITTER_DATE"
 +              echo "data <<EOF"
 +              printf "$message\n" $n
 +              echo "EOF"
 +              if test -n "$add_from"
 +              then
 +                      echo "from $ref^0"
 +                      add_from=
 +              fi
 +              printf "M 644 inline $filename\n" $n
 +              echo "data <<EOF"
 +              printf "$contents\n" $n
 +              echo "EOF"
 +              echo
 +              n=$((n + 1))
 +              total=$((total - 1))
 +      done >"$tmpfile"
 +
 +      git -C "$indir" \
 +          -c fastimport.unpacklimit=0 \
 +          fast-import <"$tmpfile" || return 1
 +
 +      # This will be left in place on failure, which may aid debugging.
 +      rm -f "$tmpfile"
 +
 +      # If we updated HEAD, then be nice and update the index and working
 +      # tree, too.
 +      if test "$ref" = "HEAD"
 +      then
 +              git -C "$indir" checkout -f HEAD || return 1
 +      fi
 +
 +}
 +
  # This function helps systems where core.filemode=false is set.
  # Use it instead of plain 'chmod +x' to set or unset the executable bit
  # of a file in the working directory and add it to the index.
@@@ -432,26 -309,6 +432,26 @@@ test_unset_prereq () 
  }
  
  test_set_prereq () {
 +      if test -n "$GIT_TEST_FAIL_PREREQS_INTERNAL"
 +      then
 +              case "$1" in
 +              # The "!" case is handled below with
 +              # test_unset_prereq()
 +              !*)
 +                      ;;
 +              # (Temporary?) whitelist of things we can't easily
 +              # pretend not to support
 +              SYMLINKS)
 +                      ;;
 +              # Inspecting whether GIT_TEST_FAIL_PREREQS is on
 +              # should be unaffected.
 +              FAIL_PREREQS)
 +                      ;;
 +              *)
 +                      return
 +              esac
 +      fi
 +
        case "$1" in
        !*)
                test_unset_prereq "${1#!}"
@@@ -580,7 -437,7 +580,7 @@@ test_expect_failure () 
        export test_prereq
        if ! test_skip "$@"
        then
-               say >&3 "checking known breakage: $2"
+               say >&3 "checking known breakage of $TEST_NUMBER.$test_count '$1': $2"
                if test_run_ "$2" expecting_failure
                then
                        test_known_broken_ok_ "$1"
@@@ -600,7 -457,7 +600,7 @@@ test_expect_success () 
        export test_prereq
        if ! test_skip "$@"
        then
-               say >&3 "expecting success: $2"
+               say >&3 "expecting success of $TEST_NUMBER.$test_count '$1': $2"
                if test_run_ "$2"
                then
                        test_ok_ "$1"
@@@ -1173,20 -1030,62 +1173,20 @@@ perl () 
        command "$PERL_PATH" "$@" 2>&7
  } 7>&2 2>&4
  
 -# Is the value one of the various ways to spell a boolean true/false?
 -test_normalize_bool () {
 -      git -c magic.variable="$1" config --bool magic.variable 2>/dev/null
 -}
 -
 -# Given a variable $1, normalize the value of it to one of "true",
 -# "false", or "auto" and store the result to it.
 -#
 -#     test_tristate GIT_TEST_HTTPD
 -#
 -# A variable set to an empty string is set to 'false'.
 -# A variable set to 'false' or 'auto' keeps its value.
 -# Anything else is set to 'true'.
 -# An unset variable defaults to 'auto'.
 -#
 -# The last rule is to allow people to set the variable to an empty
 -# string and export it to decline testing the particular feature
 -# for versions both before and after this change.  We used to treat
 -# both unset and empty variable as a signal for "do not test" and
 -# took any non-empty string as "please test".
 -
 -test_tristate () {
 -      if eval "test x\"\${$1+isset}\" = xisset"
 -      then
 -              # explicitly set
 -              eval "
 -                      case \"\$$1\" in
 -                      '')     $1=false ;;
 -                      auto)   ;;
 -                      *)      $1=\$(test_normalize_bool \$$1 || echo true) ;;
 -                      esac
 -              "
 -      else
 -              eval "$1=auto"
 -      fi
 -}
 -
  # Exit the test suite, either by skipping all remaining tests or by
 -# exiting with an error. If "$1" is "auto", we then we assume we were
 -# opportunistically trying to set up some tests and we skip. If it is
 -# "true", then we report a failure.
 +# exiting with an error. If our prerequisite variable $1 falls back
 +# on a default assume we were opportunistically trying to set up some
 +# tests and we skip. If it is explicitly "true", then we report a failure.
  #
  # The error/skip message should be given by $2.
  #
  test_skip_or_die () {
 -      case "$1" in
 -      auto)
 +      if ! git env--helper --type=bool --default=false --exit-code $1
 +      then
                skip_all=$2
                test_done
 -              ;;
 -      true)
 -              error "$2"
 -              ;;
 -      *)
 -              error "BUG: test tristate is '$1' (real error: $2)"
 -      esac
 +      fi
 +      error "$2"
  }
  
  # The following mingw_* functions obey POSIX shell syntax, but are actually
@@@ -1430,13 -1329,6 +1430,13 @@@ test_oid () 
        eval "printf '%s' \"\${$var}\""
  }
  
 +# Insert a slash into an object ID so it can be used to reference a location
 +# under ".git/objects".  For example, "deadbeef..." becomes "de/adbeef..".
 +test_oid_to_path () {
 +      local basename=${1#??}
 +      echo "${1%$basename}/$basename"
 +}
 +
  # Choose a port number based on the test script's number and store it in
  # the given variable name, unless that variable already contains a number.
  test_set_port () {
diff --combined t/test-lib.sh
index 30b07e310f59493616f766ea6cf7c45a335c9258,901f57915193e952c23a5f7ae4a1f8a7e60254d2..a9d45642a5b32328200b0eec93183279c00d9444
@@@ -212,6 -212,8 +212,8 @@@ f
  
  TEST_STRESS_JOB_SFX="${GIT_TEST_STRESS_JOB_NR:+.stress-$GIT_TEST_STRESS_JOB_NR}"
  TEST_NAME="$(basename "$0" .sh)"
+ TEST_NUMBER="${TEST_NAME%%-*}"
+ TEST_NUMBER="${TEST_NUMBER#t}"
  TEST_RESULTS_DIR="$TEST_OUTPUT_DIRECTORY/test-results"
  TEST_RESULTS_BASE="$TEST_RESULTS_DIR/$TEST_NAME$TEST_STRESS_JOB_SFX"
  TRASH_DIRECTORY="trash directory.$TEST_NAME$TEST_STRESS_JOB_SFX"
@@@ -386,6 -388,7 +388,6 @@@ unset VISUAL EMAIL LANGUAGE COLUMNS $("
        my @env = keys %ENV;
        my $ok = join("|", qw(
                TRACE
 -              TR2_
                DEBUG
                TEST
                .*_TEST
@@@ -1388,25 -1391,6 +1390,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
@@@ -1461,9 -1445,11 +1463,9 @@@ the
        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