a3b2166cb5908152df5a2b0d73fa128720b7a095
   1# Test framework for git.  See t/README for usage.
   2#
   3# Copyright (c) 2005 Junio C Hamano
   4#
   5# This program is free software: you can redistribute it and/or modify
   6# it under the terms of the GNU General Public License as published by
   7# the Free Software Foundation, either version 2 of the License, or
   8# (at your option) any later version.
   9#
  10# This program is distributed in the hope that it will be useful,
  11# but WITHOUT ANY WARRANTY; without even the implied warranty of
  12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13# GNU General Public License for more details.
  14#
  15# You should have received a copy of the GNU General Public License
  16# along with this program.  If not, see http://www.gnu.org/licenses/ .
  17
  18# Test the binaries we have just built.  The tests are kept in
  19# t/ subdirectory and are run in 'trash directory' subdirectory.
  20if test -z "$TEST_DIRECTORY"
  21then
  22        # We allow tests to override this, in case they want to run tests
  23        # outside of t/, e.g. for running tests on the test library
  24        # itself.
  25        TEST_DIRECTORY=$(pwd)
  26else
  27        # ensure that TEST_DIRECTORY is an absolute path so that it
  28        # is valid even if the current working directory is changed
  29        TEST_DIRECTORY=$(cd "$TEST_DIRECTORY" && pwd) || exit 1
  30fi
  31if test -z "$TEST_OUTPUT_DIRECTORY"
  32then
  33        # Similarly, override this to store the test-results subdir
  34        # elsewhere
  35        TEST_OUTPUT_DIRECTORY=$TEST_DIRECTORY
  36fi
  37GIT_BUILD_DIR="$TEST_DIRECTORY"/..
  38
  39# If we were built with ASAN, it may complain about leaks
  40# of program-lifetime variables. Disable it by default to lower
  41# the noise level. This needs to happen at the start of the script,
  42# before we even do our "did we build git yet" check (since we don't
  43# want that one to complain to stderr).
  44: ${ASAN_OPTIONS=detect_leaks=0:abort_on_error=1}
  45export ASAN_OPTIONS
  46
  47# If LSAN is in effect we _do_ want leak checking, but we still
  48# want to abort so that we notice the problems.
  49: ${LSAN_OPTIONS=abort_on_error=1}
  50export LSAN_OPTIONS
  51
  52if test ! -f "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
  53then
  54        echo >&2 'error: GIT-BUILD-OPTIONS missing (has Git been built?).'
  55        exit 1
  56fi
  57. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
  58export PERL_PATH SHELL_PATH
  59
  60################################################################
  61# It appears that people try to run tests without building...
  62"${GIT_TEST_INSTALLED:-$GIT_BUILD_DIR}/git$X" >/dev/null
  63if test $? != 1
  64then
  65        if test -n "$GIT_TEST_INSTALLED"
  66        then
  67                echo >&2 "error: there is no working Git at '$GIT_TEST_INSTALLED'"
  68        else
  69                echo >&2 'error: you do not seem to have built git yet.'
  70        fi
  71        exit 1
  72fi
  73
  74# Parse options while taking care to leave $@ intact, so we will still
  75# have all the original command line options when executing the test
  76# script again for '--tee' and '--verbose-log' below.
  77store_arg_to=
  78prev_opt=
  79for opt
  80do
  81        if test -n "$store_arg_to"
  82        then
  83                eval $store_arg_to=\$opt
  84                store_arg_to=
  85                prev_opt=
  86                continue
  87        fi
  88
  89        case "$opt" in
  90        -d|--d|--de|--deb|--debu|--debug)
  91                debug=t ;;
  92        -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate)
  93                immediate=t ;;
  94        -l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)
  95                GIT_TEST_LONG=t; export GIT_TEST_LONG ;;
  96        -r)
  97                store_arg_to=run_list
  98                ;;
  99        --run=*)
 100                run_list=${opt#--*=} ;;
 101        -h|--h|--he|--hel|--help)
 102                help=t ;;
 103        -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
 104                verbose=t ;;
 105        --verbose-only=*)
 106                verbose_only=${opt#--*=}
 107                ;;
 108        -q|--q|--qu|--qui|--quie|--quiet)
 109                # Ignore --quiet under a TAP::Harness. Saying how many tests
 110                # passed without the ok/not ok details is always an error.
 111                test -z "$HARNESS_ACTIVE" && quiet=t ;;
 112        --with-dashes)
 113                with_dashes=t ;;
 114        --no-color)
 115                color= ;;
 116        --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)
 117                valgrind=memcheck
 118                tee=t
 119                ;;
 120        --valgrind=*)
 121                valgrind=${opt#--*=}
 122                tee=t
 123                ;;
 124        --valgrind-only=*)
 125                valgrind_only=${opt#--*=}
 126                tee=t
 127                ;;
 128        --tee)
 129                tee=t ;;
 130        --root=*)
 131                root=${opt#--*=} ;;
 132        --chain-lint)
 133                GIT_TEST_CHAIN_LINT=1 ;;
 134        --no-chain-lint)
 135                GIT_TEST_CHAIN_LINT=0 ;;
 136        -x)
 137                trace=t ;;
 138        -V|--verbose-log)
 139                verbose_log=t
 140                tee=t
 141                ;;
 142        --write-junit-xml)
 143                write_junit_xml=t
 144                ;;
 145        --stress)
 146                stress=t ;;
 147        --stress=*)
 148                stress=${opt#--*=}
 149                case "$stress" in
 150                *[^0-9]*|0*|"")
 151                        echo "error: --stress=<N> requires the number of jobs to run" >&2
 152                        exit 1
 153                        ;;
 154                *)      # Good.
 155                        ;;
 156                esac
 157                ;;
 158        *)
 159                echo "error: unknown test option '$opt'" >&2; exit 1 ;;
 160        esac
 161
 162        prev_opt=$opt
 163done
 164if test -n "$store_arg_to"
 165then
 166        echo "error: $prev_opt requires an argument" >&2
 167        exit 1
 168fi
 169
 170if test -n "$valgrind_only"
 171then
 172        test -z "$valgrind" && valgrind=memcheck
 173        test -z "$verbose" && verbose_only="$valgrind_only"
 174elif test -n "$valgrind"
 175then
 176        test -z "$verbose_log" && verbose=t
 177fi
 178
 179if test -n "$stress"
 180then
 181        verbose=t
 182        trace=t
 183        immediate=t
 184fi
 185
 186TEST_STRESS_JOB_SFX="${GIT_TEST_STRESS_JOB_NR:+.stress-$GIT_TEST_STRESS_JOB_NR}"
 187TEST_NAME="$(basename "$0" .sh)"
 188TEST_RESULTS_DIR="$TEST_OUTPUT_DIRECTORY/test-results"
 189TEST_RESULTS_BASE="$TEST_RESULTS_DIR/$TEST_NAME$TEST_STRESS_JOB_SFX"
 190TRASH_DIRECTORY="trash directory.$TEST_NAME$TEST_STRESS_JOB_SFX"
 191test -n "$root" && TRASH_DIRECTORY="$root/$TRASH_DIRECTORY"
 192case "$TRASH_DIRECTORY" in
 193/*) ;; # absolute path is good
 194 *) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$TRASH_DIRECTORY" ;;
 195esac
 196
 197# If --stress was passed, run this test repeatedly in several parallel loops.
 198if test "$GIT_TEST_STRESS_STARTED" = "done"
 199then
 200        : # Don't stress test again.
 201elif test -n "$stress"
 202then
 203        if test "$stress" != t
 204        then
 205                job_count=$stress
 206        elif test -n "$GIT_TEST_STRESS_LOAD"
 207        then
 208                job_count="$GIT_TEST_STRESS_LOAD"
 209        elif job_count=$(getconf _NPROCESSORS_ONLN 2>/dev/null) &&
 210             test -n "$job_count"
 211        then
 212                job_count=$((2 * $job_count))
 213        else
 214                job_count=8
 215        fi
 216
 217        mkdir -p "$TEST_RESULTS_DIR"
 218        stressfail="$TEST_RESULTS_BASE.stress-failed"
 219        rm -f "$stressfail"
 220
 221        stress_exit=0
 222        trap '
 223                kill $job_pids 2>/dev/null
 224                wait
 225                stress_exit=1
 226        ' TERM INT HUP
 227
 228        job_pids=
 229        job_nr=0
 230        while test $job_nr -lt "$job_count"
 231        do
 232                (
 233                        GIT_TEST_STRESS_STARTED=done
 234                        GIT_TEST_STRESS_JOB_NR=$job_nr
 235                        export GIT_TEST_STRESS_STARTED GIT_TEST_STRESS_JOB_NR
 236
 237                        trap '
 238                                kill $test_pid 2>/dev/null
 239                                wait
 240                                exit 1
 241                        ' TERM INT
 242
 243                        cnt=0
 244                        while ! test -e "$stressfail"
 245                        do
 246                                $TEST_SHELL_PATH "$0" "$@" >"$TEST_RESULTS_BASE.stress-$job_nr.out" 2>&1 &
 247                                test_pid=$!
 248
 249                                if wait $test_pid
 250                                then
 251                                        printf "OK   %2d.%d\n" $GIT_TEST_STRESS_JOB_NR $cnt
 252                                else
 253                                        echo $GIT_TEST_STRESS_JOB_NR >>"$stressfail"
 254                                        printf "FAIL %2d.%d\n" $GIT_TEST_STRESS_JOB_NR $cnt
 255                                fi
 256                                cnt=$(($cnt + 1))
 257                        done
 258                ) &
 259                job_pids="$job_pids $!"
 260                job_nr=$(($job_nr + 1))
 261        done
 262
 263        wait
 264
 265        if test -f "$stressfail"
 266        then
 267                echo "Log(s) of failed test run(s):"
 268                for failed_job_nr in $(sort -n "$stressfail")
 269                do
 270                        echo "Contents of '$TEST_RESULTS_BASE.stress-$failed_job_nr.out':"
 271                        cat "$TEST_RESULTS_BASE.stress-$failed_job_nr.out"
 272                done
 273                rm -rf "$TRASH_DIRECTORY.stress-failed"
 274                # Move the last one.
 275                mv "$TRASH_DIRECTORY.stress-$failed_job_nr" "$TRASH_DIRECTORY.stress-failed"
 276        fi
 277
 278        exit $stress_exit
 279fi
 280
 281# if --tee was passed, write the output not only to the terminal, but
 282# additionally to the file test-results/$BASENAME.out, too.
 283if test "$GIT_TEST_TEE_STARTED" = "done"
 284then
 285        : # do not redirect again
 286elif test -n "$tee"
 287then
 288        mkdir -p "$TEST_RESULTS_DIR"
 289
 290        # Make this filename available to the sub-process in case it is using
 291        # --verbose-log.
 292        GIT_TEST_TEE_OUTPUT_FILE=$TEST_RESULTS_BASE.out
 293        export GIT_TEST_TEE_OUTPUT_FILE
 294
 295        # Truncate before calling "tee -a" to get rid of the results
 296        # from any previous runs.
 297        >"$GIT_TEST_TEE_OUTPUT_FILE"
 298
 299        (GIT_TEST_TEE_STARTED=done ${TEST_SHELL_PATH} "$0" "$@" 2>&1;
 300         echo $? >"$TEST_RESULTS_BASE.exit") | tee -a "$GIT_TEST_TEE_OUTPUT_FILE"
 301        test "$(cat "$TEST_RESULTS_BASE.exit")" = 0
 302        exit
 303fi
 304
 305if test -n "$trace" && test -n "$test_untraceable"
 306then
 307        # '-x' tracing requested, but this test script can't be reliably
 308        # traced, unless it is run with a Bash version supporting
 309        # BASH_XTRACEFD (introduced in Bash v4.1).
 310        #
 311        # Perform this version check _after_ the test script was
 312        # potentially re-executed with $TEST_SHELL_PATH for '--tee' or
 313        # '--verbose-log', so the right shell is checked and the
 314        # warning is issued only once.
 315        if test -n "$BASH_VERSION" && eval '
 316             test ${BASH_VERSINFO[0]} -gt 4 || {
 317               test ${BASH_VERSINFO[0]} -eq 4 &&
 318               test ${BASH_VERSINFO[1]} -ge 1
 319             }
 320           '
 321        then
 322                : Executed by a Bash version supporting BASH_XTRACEFD.  Good.
 323        else
 324                echo >&2 "warning: ignoring -x; '$0' is untraceable without BASH_XTRACEFD"
 325                trace=
 326        fi
 327fi
 328if test -n "$trace" && test -z "$verbose_log"
 329then
 330        verbose=t
 331fi
 332
 333# For repeatability, reset the environment to known value.
 334# TERM is sanitized below, after saving color control sequences.
 335LANG=C
 336LC_ALL=C
 337PAGER=cat
 338TZ=UTC
 339export LANG LC_ALL PAGER TZ
 340EDITOR=:
 341
 342# GIT_TEST_GETTEXT_POISON should not influence git commands executed
 343# during initialization of test-lib and the test repo. Back it up,
 344# unset and then restore after initialization is finished.
 345if test -n "$GIT_TEST_GETTEXT_POISON"
 346then
 347        GIT_TEST_GETTEXT_POISON_ORIG=$GIT_TEST_GETTEXT_POISON
 348        unset GIT_TEST_GETTEXT_POISON
 349fi
 350
 351# A call to "unset" with no arguments causes at least Solaris 10
 352# /usr/xpg4/bin/sh and /bin/ksh to bail out.  So keep the unsets
 353# deriving from the command substitution clustered with the other
 354# ones.
 355unset VISUAL EMAIL LANGUAGE COLUMNS $("$PERL_PATH" -e '
 356        my @env = keys %ENV;
 357        my $ok = join("|", qw(
 358                TRACE
 359                DEBUG
 360                TEST
 361                .*_TEST
 362                PROVE
 363                VALGRIND
 364                UNZIP
 365                PERF_
 366                CURL_VERBOSE
 367                TRACE_CURL
 368        ));
 369        my @vars = grep(/^GIT_/ && !/^GIT_($ok)/o, @env);
 370        print join("\n", @vars);
 371')
 372unset XDG_CACHE_HOME
 373unset XDG_CONFIG_HOME
 374unset GITPERLLIB
 375GIT_AUTHOR_EMAIL=author@example.com
 376GIT_AUTHOR_NAME='A U Thor'
 377GIT_COMMITTER_EMAIL=committer@example.com
 378GIT_COMMITTER_NAME='C O Mitter'
 379GIT_MERGE_VERBOSITY=5
 380GIT_MERGE_AUTOEDIT=no
 381export GIT_MERGE_VERBOSITY GIT_MERGE_AUTOEDIT
 382export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
 383export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
 384export EDITOR
 385
 386# Tests using GIT_TRACE typically don't want <timestamp> <file>:<line> output
 387GIT_TRACE_BARE=1
 388export GIT_TRACE_BARE
 389
 390check_var_migration () {
 391        # the warnings and hints given from this helper depends
 392        # on end-user settings, which will disrupt the self-test
 393        # done on the test framework itself.
 394        case "$GIT_TEST_FRAMEWORK_SELFTEST" in
 395        t)      return ;;
 396        esac
 397
 398        old_name=$1 new_name=$2
 399        eval "old_isset=\${${old_name}:+isset}"
 400        eval "new_isset=\${${new_name}:+isset}"
 401
 402        case "$old_isset,$new_isset" in
 403        isset,)
 404                echo >&2 "warning: $old_name is now $new_name"
 405                echo >&2 "hint: set $new_name too during the transition period"
 406                eval "$new_name=\$$old_name"
 407                ;;
 408        isset,isset)
 409                # do this later
 410                # echo >&2 "warning: $old_name is now $new_name"
 411                # echo >&2 "hint: remove $old_name"
 412                ;;
 413        esac
 414}
 415
 416check_var_migration GIT_FSMONITOR_TEST GIT_TEST_FSMONITOR
 417check_var_migration TEST_GIT_INDEX_VERSION GIT_TEST_INDEX_VERSION
 418check_var_migration GIT_FORCE_PRELOAD_TEST GIT_TEST_PRELOAD_INDEX
 419
 420# Use specific version of the index file format
 421if test -n "${GIT_TEST_INDEX_VERSION:+isset}"
 422then
 423        GIT_INDEX_VERSION="$GIT_TEST_INDEX_VERSION"
 424        export GIT_INDEX_VERSION
 425fi
 426
 427# Add libc MALLOC and MALLOC_PERTURB test
 428# only if we are not executing the test with valgrind
 429if test -n "$valgrind" ||
 430   test -n "$TEST_NO_MALLOC_CHECK"
 431then
 432        setup_malloc_check () {
 433                : nothing
 434        }
 435        teardown_malloc_check () {
 436                : nothing
 437        }
 438else
 439        setup_malloc_check () {
 440                MALLOC_CHECK_=3 MALLOC_PERTURB_=165
 441                export MALLOC_CHECK_ MALLOC_PERTURB_
 442        }
 443        teardown_malloc_check () {
 444                unset MALLOC_CHECK_ MALLOC_PERTURB_
 445        }
 446fi
 447
 448# Protect ourselves from common misconfiguration to export
 449# CDPATH into the environment
 450unset CDPATH
 451
 452unset GREP_OPTIONS
 453unset UNZIP
 454
 455case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in
 4561|2|true)
 457        GIT_TRACE=4
 458        ;;
 459esac
 460
 461# Convenience
 462#
 463# A regexp to match 5, 35 and 40 hexdigits
 464_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
 465_x35="$_x05$_x05$_x05$_x05$_x05$_x05$_x05"
 466_x40="$_x35$_x05"
 467
 468# Zero SHA-1
 469_z40=0000000000000000000000000000000000000000
 470
 471OID_REGEX="$_x40"
 472ZERO_OID=$_z40
 473EMPTY_TREE=4b825dc642cb6eb9a060e54bf8d69288fbee4904
 474EMPTY_BLOB=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
 475
 476# Line feed
 477LF='
 478'
 479
 480# UTF-8 ZERO WIDTH NON-JOINER, which HFS+ ignores
 481# when case-folding filenames
 482u200c=$(printf '\342\200\214')
 483
 484export _x05 _x35 _x40 _z40 LF u200c EMPTY_TREE EMPTY_BLOB ZERO_OID OID_REGEX
 485
 486# Each test should start with something like this, after copyright notices:
 487#
 488# test_description='Description of this test...
 489# This test checks if command xyzzy does the right thing...
 490# '
 491# . ./test-lib.sh
 492test "x$TERM" != "xdumb" && (
 493                test -t 1 &&
 494                tput bold >/dev/null 2>&1 &&
 495                tput setaf 1 >/dev/null 2>&1 &&
 496                tput sgr0 >/dev/null 2>&1
 497        ) &&
 498        color=t
 499
 500if test -n "$color"
 501then
 502        # Save the color control sequences now rather than run tput
 503        # each time say_color() is called.  This is done for two
 504        # reasons:
 505        #   * TERM will be changed to dumb
 506        #   * HOME will be changed to a temporary directory and tput
 507        #     might need to read ~/.terminfo from the original HOME
 508        #     directory to get the control sequences
 509        # Note:  This approach assumes the control sequences don't end
 510        # in a newline for any terminal of interest (command
 511        # substitutions strip trailing newlines).  Given that most
 512        # (all?) terminals in common use are related to ECMA-48, this
 513        # shouldn't be a problem.
 514        say_color_error=$(tput bold; tput setaf 1) # bold red
 515        say_color_skip=$(tput setaf 4) # blue
 516        say_color_warn=$(tput setaf 3) # brown/yellow
 517        say_color_pass=$(tput setaf 2) # green
 518        say_color_info=$(tput setaf 6) # cyan
 519        say_color_reset=$(tput sgr0)
 520        say_color_="" # no formatting for normal text
 521        say_color () {
 522                test -z "$1" && test -n "$quiet" && return
 523                eval "say_color_color=\$say_color_$1"
 524                shift
 525                printf "%s\\n" "$say_color_color$*$say_color_reset"
 526        }
 527else
 528        say_color() {
 529                test -z "$1" && test -n "$quiet" && return
 530                shift
 531                printf "%s\n" "$*"
 532        }
 533fi
 534
 535TERM=dumb
 536export TERM
 537
 538error () {
 539        say_color error "error: $*"
 540        GIT_EXIT_OK=t
 541        exit 1
 542}
 543
 544BUG () {
 545        error >&7 "bug in the test script: $*"
 546}
 547
 548say () {
 549        say_color info "$*"
 550}
 551
 552if test -n "$HARNESS_ACTIVE"
 553then
 554        if test "$verbose" = t || test -n "$verbose_only"
 555        then
 556                printf 'Bail out! %s\n' \
 557                 'verbose mode forbidden under TAP harness; try --verbose-log'
 558                exit 1
 559        fi
 560fi
 561
 562test "${test_description}" != "" ||
 563error "Test script did not set test_description."
 564
 565if test "$help" = "t"
 566then
 567        printf '%s\n' "$test_description"
 568        exit 0
 569fi
 570
 571exec 5>&1
 572exec 6<&0
 573exec 7>&2
 574if test "$verbose_log" = "t"
 575then
 576        exec 3>>"$GIT_TEST_TEE_OUTPUT_FILE" 4>&3
 577elif test "$verbose" = "t"
 578then
 579        exec 4>&2 3>&1
 580else
 581        exec 4>/dev/null 3>/dev/null
 582fi
 583
 584# Send any "-x" output directly to stderr to avoid polluting tests
 585# which capture stderr. We can do this unconditionally since it
 586# has no effect if tracing isn't turned on.
 587#
 588# Note that this sets up the trace fd as soon as we assign the variable, so it
 589# must come after the creation of descriptor 4 above. Likewise, we must never
 590# unset this, as it has the side effect of closing descriptor 4, which we
 591# use to show verbose tests to the user.
 592#
 593# Note also that we don't need or want to export it. The tracing is local to
 594# this shell, and we would not want to influence any shells we exec.
 595BASH_XTRACEFD=4
 596
 597test_failure=0
 598test_count=0
 599test_fixed=0
 600test_broken=0
 601test_success=0
 602
 603test_external_has_tap=0
 604
 605die () {
 606        code=$?
 607        if test -n "$GIT_EXIT_OK"
 608        then
 609                exit $code
 610        else
 611                echo >&5 "FATAL: Unexpected exit with code $code"
 612                exit 1
 613        fi
 614}
 615
 616GIT_EXIT_OK=
 617trap 'die' EXIT
 618trap 'exit $?' INT TERM HUP
 619
 620# The user-facing functions are loaded from a separate file so that
 621# test_perf subshells can have them too
 622. "$TEST_DIRECTORY/test-lib-functions.sh"
 623
 624# You are not expected to call test_ok_ and test_failure_ directly, use
 625# the test_expect_* functions instead.
 626
 627test_ok_ () {
 628        if test -n "$write_junit_xml"
 629        then
 630                write_junit_xml_testcase "$*"
 631        fi
 632        test_success=$(($test_success + 1))
 633        say_color "" "ok $test_count - $@"
 634}
 635
 636test_failure_ () {
 637        if test -n "$write_junit_xml"
 638        then
 639                junit_insert="<failure message=\"not ok $test_count -"
 640                junit_insert="$junit_insert $(xml_attr_encode "$1")\">"
 641                junit_insert="$junit_insert $(xml_attr_encode \
 642                        "$(printf '%s\n' "$@" | sed 1d)")"
 643                junit_insert="$junit_insert</failure>"
 644                write_junit_xml_testcase "$1" "      $junit_insert"
 645        fi
 646        test_failure=$(($test_failure + 1))
 647        say_color error "not ok $test_count - $1"
 648        shift
 649        printf '%s\n' "$*" | sed -e 's/^/#      /'
 650        test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
 651}
 652
 653test_known_broken_ok_ () {
 654        if test -n "$write_junit_xml"
 655        then
 656                write_junit_xml_testcase "$* (breakage fixed)"
 657        fi
 658        test_fixed=$(($test_fixed+1))
 659        say_color error "ok $test_count - $@ # TODO known breakage vanished"
 660}
 661
 662test_known_broken_failure_ () {
 663        if test -n "$write_junit_xml"
 664        then
 665                write_junit_xml_testcase "$* (known breakage)"
 666        fi
 667        test_broken=$(($test_broken+1))
 668        say_color warn "not ok $test_count - $@ # TODO known breakage"
 669}
 670
 671test_debug () {
 672        test "$debug" = "" || eval "$1"
 673}
 674
 675match_pattern_list () {
 676        arg="$1"
 677        shift
 678        test -z "$*" && return 1
 679        for pattern_
 680        do
 681                case "$arg" in
 682                $pattern_)
 683                        return 0
 684                esac
 685        done
 686        return 1
 687}
 688
 689match_test_selector_list () {
 690        title="$1"
 691        shift
 692        arg="$1"
 693        shift
 694        test -z "$1" && return 0
 695
 696        # Both commas and whitespace are accepted as separators.
 697        OLDIFS=$IFS
 698        IFS='   ,'
 699        set -- $1
 700        IFS=$OLDIFS
 701
 702        # If the first selector is negative we include by default.
 703        include=
 704        case "$1" in
 705                !*) include=t ;;
 706        esac
 707
 708        for selector
 709        do
 710                orig_selector=$selector
 711
 712                positive=t
 713                case "$selector" in
 714                        !*)
 715                                positive=
 716                                selector=${selector##?}
 717                                ;;
 718                esac
 719
 720                test -z "$selector" && continue
 721
 722                case "$selector" in
 723                        *-*)
 724                                if expr "z${selector%%-*}" : "z[0-9]*[^0-9]" >/dev/null
 725                                then
 726                                        echo "error: $title: invalid non-numeric in range" \
 727                                                "start: '$orig_selector'" >&2
 728                                        exit 1
 729                                fi
 730                                if expr "z${selector#*-}" : "z[0-9]*[^0-9]" >/dev/null
 731                                then
 732                                        echo "error: $title: invalid non-numeric in range" \
 733                                                "end: '$orig_selector'" >&2
 734                                        exit 1
 735                                fi
 736                                ;;
 737                        *)
 738                                if expr "z$selector" : "z[0-9]*[^0-9]" >/dev/null
 739                                then
 740                                        echo "error: $title: invalid non-numeric in test" \
 741                                                "selector: '$orig_selector'" >&2
 742                                        exit 1
 743                                fi
 744                esac
 745
 746                # Short cut for "obvious" cases
 747                test -z "$include" && test -z "$positive" && continue
 748                test -n "$include" && test -n "$positive" && continue
 749
 750                case "$selector" in
 751                        -*)
 752                                if test $arg -le ${selector#-}
 753                                then
 754                                        include=$positive
 755                                fi
 756                                ;;
 757                        *-)
 758                                if test $arg -ge ${selector%-}
 759                                then
 760                                        include=$positive
 761                                fi
 762                                ;;
 763                        *-*)
 764                                if test ${selector%%-*} -le $arg \
 765                                        && test $arg -le ${selector#*-}
 766                                then
 767                                        include=$positive
 768                                fi
 769                                ;;
 770                        *)
 771                                if test $arg -eq $selector
 772                                then
 773                                        include=$positive
 774                                fi
 775                                ;;
 776                esac
 777        done
 778
 779        test -n "$include"
 780}
 781
 782maybe_teardown_verbose () {
 783        test -z "$verbose_only" && return
 784        exec 4>/dev/null 3>/dev/null
 785        verbose=
 786}
 787
 788last_verbose=t
 789maybe_setup_verbose () {
 790        test -z "$verbose_only" && return
 791        if match_pattern_list $test_count $verbose_only
 792        then
 793                exec 4>&2 3>&1
 794                # Emit a delimiting blank line when going from
 795                # non-verbose to verbose.  Within verbose mode the
 796                # delimiter is printed by test_expect_*.  The choice
 797                # of the initial $last_verbose is such that before
 798                # test 1, we do not print it.
 799                test -z "$last_verbose" && echo >&3 ""
 800                verbose=t
 801        else
 802                exec 4>/dev/null 3>/dev/null
 803                verbose=
 804        fi
 805        last_verbose=$verbose
 806}
 807
 808maybe_teardown_valgrind () {
 809        test -z "$GIT_VALGRIND" && return
 810        GIT_VALGRIND_ENABLED=
 811}
 812
 813maybe_setup_valgrind () {
 814        test -z "$GIT_VALGRIND" && return
 815        if test -z "$valgrind_only"
 816        then
 817                GIT_VALGRIND_ENABLED=t
 818                return
 819        fi
 820        GIT_VALGRIND_ENABLED=
 821        if match_pattern_list $test_count $valgrind_only
 822        then
 823                GIT_VALGRIND_ENABLED=t
 824        fi
 825}
 826
 827want_trace () {
 828        test "$trace" = t && {
 829                test "$verbose" = t || test "$verbose_log" = t
 830        }
 831}
 832
 833# This is a separate function because some tests use
 834# "return" to end a test_expect_success block early
 835# (and we want to make sure we run any cleanup like
 836# "set +x").
 837test_eval_inner_ () {
 838        # Do not add anything extra (including LF) after '$*'
 839        eval "
 840                want_trace && set -x
 841                $*"
 842}
 843
 844test_eval_ () {
 845        # If "-x" tracing is in effect, then we want to avoid polluting stderr
 846        # with non-test commands. But once in "set -x" mode, we cannot prevent
 847        # the shell from printing the "set +x" to turn it off (nor the saving
 848        # of $? before that). But we can make sure that the output goes to
 849        # /dev/null.
 850        #
 851        # There are a few subtleties here:
 852        #
 853        #   - we have to redirect descriptor 4 in addition to 2, to cover
 854        #     BASH_XTRACEFD
 855        #
 856        #   - the actual eval has to come before the redirection block (since
 857        #     it needs to see descriptor 4 to set up its stderr)
 858        #
 859        #   - likewise, any error message we print must be outside the block to
 860        #     access descriptor 4
 861        #
 862        #   - checking $? has to come immediately after the eval, but it must
 863        #     be _inside_ the block to avoid polluting the "set -x" output
 864        #
 865
 866        test_eval_inner_ "$@" </dev/null >&3 2>&4
 867        {
 868                test_eval_ret_=$?
 869                if want_trace
 870                then
 871                        set +x
 872                fi
 873        } 2>/dev/null 4>&2
 874
 875        if test "$test_eval_ret_" != 0 && want_trace
 876        then
 877                say_color error >&4 "error: last command exited with \$?=$test_eval_ret_"
 878        fi
 879        return $test_eval_ret_
 880}
 881
 882test_run_ () {
 883        test_cleanup=:
 884        expecting_failure=$2
 885
 886        if test "${GIT_TEST_CHAIN_LINT:-1}" != 0; then
 887                # turn off tracing for this test-eval, as it simply creates
 888                # confusing noise in the "-x" output
 889                trace_tmp=$trace
 890                trace=
 891                # 117 is magic because it is unlikely to match the exit
 892                # code of other programs
 893                if $(printf '%s\n' "$1" | sed -f "$GIT_BUILD_DIR/t/chainlint.sed" | grep -q '?![A-Z][A-Z]*?!') ||
 894                        test "OK-117" != "$(test_eval_ "(exit 117) && $1${LF}${LF}echo OK-\$?" 3>&1)"
 895                then
 896                        BUG "broken &&-chain or run-away HERE-DOC: $1"
 897                fi
 898                trace=$trace_tmp
 899        fi
 900
 901        setup_malloc_check
 902        test_eval_ "$1"
 903        eval_ret=$?
 904        teardown_malloc_check
 905
 906        if test -z "$immediate" || test $eval_ret = 0 ||
 907           test -n "$expecting_failure" && test "$test_cleanup" != ":"
 908        then
 909                setup_malloc_check
 910                test_eval_ "$test_cleanup"
 911                teardown_malloc_check
 912        fi
 913        if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"
 914        then
 915                echo ""
 916        fi
 917        return "$eval_ret"
 918}
 919
 920test_start_ () {
 921        test_count=$(($test_count+1))
 922        maybe_setup_verbose
 923        maybe_setup_valgrind
 924        if test -n "$write_junit_xml"
 925        then
 926                junit_start=$(test-tool date getnanos)
 927        fi
 928}
 929
 930test_finish_ () {
 931        echo >&3 ""
 932        maybe_teardown_valgrind
 933        maybe_teardown_verbose
 934}
 935
 936test_skip () {
 937        to_skip=
 938        skipped_reason=
 939        if match_pattern_list $this_test.$test_count $GIT_SKIP_TESTS
 940        then
 941                to_skip=t
 942                skipped_reason="GIT_SKIP_TESTS"
 943        fi
 944        if test -z "$to_skip" && test -n "$test_prereq" &&
 945           ! test_have_prereq "$test_prereq"
 946        then
 947                to_skip=t
 948
 949                of_prereq=
 950                if test "$missing_prereq" != "$test_prereq"
 951                then
 952                        of_prereq=" of $test_prereq"
 953                fi
 954                skipped_reason="missing $missing_prereq${of_prereq}"
 955        fi
 956        if test -z "$to_skip" && test -n "$run_list" &&
 957                ! match_test_selector_list '--run' $test_count "$run_list"
 958        then
 959                to_skip=t
 960                skipped_reason="--run"
 961        fi
 962
 963        case "$to_skip" in
 964        t)
 965                if test -n "$write_junit_xml"
 966                then
 967                        message="$(xml_attr_encode "$skipped_reason")"
 968                        write_junit_xml_testcase "$1" \
 969                                "      <skipped message=\"$message\" />"
 970                fi
 971
 972                say_color skip >&3 "skipping test: $@"
 973                say_color skip "ok $test_count # skip $1 ($skipped_reason)"
 974                : true
 975                ;;
 976        *)
 977                false
 978                ;;
 979        esac
 980}
 981
 982# stub; perf-lib overrides it
 983test_at_end_hook_ () {
 984        :
 985}
 986
 987write_junit_xml () {
 988        case "$1" in
 989        --truncate)
 990                >"$junit_xml_path"
 991                junit_have_testcase=
 992                shift
 993                ;;
 994        esac
 995        printf '%s\n' "$@" >>"$junit_xml_path"
 996}
 997
 998xml_attr_encode () {
 999        printf '%s\n' "$@" | test-tool xml-encode
1000}
1001
1002write_junit_xml_testcase () {
1003        junit_attrs="name=\"$(xml_attr_encode "$this_test.$test_count $1")\""
1004        shift
1005        junit_attrs="$junit_attrs classname=\"$this_test\""
1006        junit_attrs="$junit_attrs time=\"$(test-tool \
1007                date getnanos $junit_start)\""
1008        write_junit_xml "$(printf '%s\n' \
1009                "    <testcase $junit_attrs>" "$@" "    </testcase>")"
1010        junit_have_testcase=t
1011}
1012
1013test_done () {
1014        GIT_EXIT_OK=t
1015
1016        if test -n "$write_junit_xml" && test -n "$junit_xml_path"
1017        then
1018                test -n "$junit_have_testcase" || {
1019                        junit_start=$(test-tool date getnanos)
1020                        write_junit_xml_testcase "all tests skipped"
1021                }
1022
1023                # adjust the overall time
1024                junit_time=$(test-tool date getnanos $junit_suite_start)
1025                sed "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
1026                        <"$junit_xml_path" >"$junit_xml_path.new"
1027                mv "$junit_xml_path.new" "$junit_xml_path"
1028
1029                write_junit_xml "  </testsuite>" "</testsuites>"
1030        fi
1031
1032        if test -z "$HARNESS_ACTIVE"
1033        then
1034                mkdir -p "$TEST_RESULTS_DIR"
1035
1036                cat >"$TEST_RESULTS_BASE.counts" <<-EOF
1037                total $test_count
1038                success $test_success
1039                fixed $test_fixed
1040                broken $test_broken
1041                failed $test_failure
1042
1043                EOF
1044        fi
1045
1046        if test "$test_fixed" != 0
1047        then
1048                say_color error "# $test_fixed known breakage(s) vanished; please update test(s)"
1049        fi
1050        if test "$test_broken" != 0
1051        then
1052                say_color warn "# still have $test_broken known breakage(s)"
1053        fi
1054        if test "$test_broken" != 0 || test "$test_fixed" != 0
1055        then
1056                test_remaining=$(( $test_count - $test_broken - $test_fixed ))
1057                msg="remaining $test_remaining test(s)"
1058        else
1059                test_remaining=$test_count
1060                msg="$test_count test(s)"
1061        fi
1062        case "$test_failure" in
1063        0)
1064                if test $test_external_has_tap -eq 0
1065                then
1066                        if test $test_remaining -gt 0
1067                        then
1068                                say_color pass "# passed all $msg"
1069                        fi
1070
1071                        # Maybe print SKIP message
1072                        test -z "$skip_all" || skip_all="# SKIP $skip_all"
1073                        case "$test_count" in
1074                        0)
1075                                say "1..$test_count${skip_all:+ $skip_all}"
1076                                ;;
1077                        *)
1078                                test -z "$skip_all" ||
1079                                say_color warn "$skip_all"
1080                                say "1..$test_count"
1081                                ;;
1082                        esac
1083                fi
1084
1085                if test -z "$debug"
1086                then
1087                        test -d "$TRASH_DIRECTORY" ||
1088                        error "Tests passed but trash directory already removed before test cleanup; aborting"
1089
1090                        cd "$TRASH_DIRECTORY/.." &&
1091                        rm -fr "$TRASH_DIRECTORY" ||
1092                        error "Tests passed but test cleanup failed; aborting"
1093                fi
1094                test_at_end_hook_
1095
1096                exit 0 ;;
1097
1098        *)
1099                if test $test_external_has_tap -eq 0
1100                then
1101                        say_color error "# failed $test_failure among $msg"
1102                        say "1..$test_count"
1103                fi
1104
1105                exit 1 ;;
1106
1107        esac
1108}
1109
1110if test -n "$valgrind"
1111then
1112        make_symlink () {
1113                test -h "$2" &&
1114                test "$1" = "$(readlink "$2")" || {
1115                        # be super paranoid
1116                        if mkdir "$2".lock
1117                        then
1118                                rm -f "$2" &&
1119                                ln -s "$1" "$2" &&
1120                                rm -r "$2".lock
1121                        else
1122                                while test -d "$2".lock
1123                                do
1124                                        say "Waiting for lock on $2."
1125                                        sleep 1
1126                                done
1127                        fi
1128                }
1129        }
1130
1131        make_valgrind_symlink () {
1132                # handle only executables, unless they are shell libraries that
1133                # need to be in the exec-path.
1134                test -x "$1" ||
1135                test "# " = "$(test_copy_bytes 2 <"$1")" ||
1136                return;
1137
1138                base=$(basename "$1")
1139                case "$base" in
1140                test-*)
1141                        symlink_target="$GIT_BUILD_DIR/t/helper/$base"
1142                        ;;
1143                *)
1144                        symlink_target="$GIT_BUILD_DIR/$base"
1145                        ;;
1146                esac
1147                # do not override scripts
1148                if test -x "$symlink_target" &&
1149                    test ! -d "$symlink_target" &&
1150                    test "#!" != "$(test_copy_bytes 2 <"$symlink_target")"
1151                then
1152                        symlink_target=../valgrind.sh
1153                fi
1154                case "$base" in
1155                *.sh|*.perl)
1156                        symlink_target=../unprocessed-script
1157                esac
1158                # create the link, or replace it if it is out of date
1159                make_symlink "$symlink_target" "$GIT_VALGRIND/bin/$base" || exit
1160        }
1161
1162        # override all git executables in TEST_DIRECTORY/..
1163        GIT_VALGRIND=$TEST_DIRECTORY/valgrind
1164        mkdir -p "$GIT_VALGRIND"/bin
1165        for file in $GIT_BUILD_DIR/git* $GIT_BUILD_DIR/t/helper/test-*
1166        do
1167                make_valgrind_symlink $file
1168        done
1169        # special-case the mergetools loadables
1170        make_symlink "$GIT_BUILD_DIR"/mergetools "$GIT_VALGRIND/bin/mergetools"
1171        OLDIFS=$IFS
1172        IFS=:
1173        for path in $PATH
1174        do
1175                ls "$path"/git-* 2> /dev/null |
1176                while read file
1177                do
1178                        make_valgrind_symlink "$file"
1179                done
1180        done
1181        IFS=$OLDIFS
1182        PATH=$GIT_VALGRIND/bin:$PATH
1183        GIT_EXEC_PATH=$GIT_VALGRIND/bin
1184        export GIT_VALGRIND
1185        GIT_VALGRIND_MODE="$valgrind"
1186        export GIT_VALGRIND_MODE
1187        GIT_VALGRIND_ENABLED=t
1188        test -n "$valgrind_only" && GIT_VALGRIND_ENABLED=
1189        export GIT_VALGRIND_ENABLED
1190elif test -n "$GIT_TEST_INSTALLED"
1191then
1192        GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path)  ||
1193        error "Cannot run git from $GIT_TEST_INSTALLED."
1194        PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR/t/helper:$PATH
1195        GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH}
1196else # normal case, use ../bin-wrappers only unless $with_dashes:
1197        git_bin_dir="$GIT_BUILD_DIR/bin-wrappers"
1198        if ! test -x "$git_bin_dir/git"
1199        then
1200                if test -z "$with_dashes"
1201                then
1202                        say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH"
1203                fi
1204                with_dashes=t
1205        fi
1206        PATH="$git_bin_dir:$PATH"
1207        GIT_EXEC_PATH=$GIT_BUILD_DIR
1208        if test -n "$with_dashes"
1209        then
1210                PATH="$GIT_BUILD_DIR:$PATH"
1211        fi
1212fi
1213GIT_TEMPLATE_DIR="$GIT_BUILD_DIR"/templates/blt
1214GIT_CONFIG_NOSYSTEM=1
1215GIT_ATTR_NOSYSTEM=1
1216export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_ATTR_NOSYSTEM
1217
1218if test -z "$GIT_TEST_CMP"
1219then
1220        if test -n "$GIT_TEST_CMP_USE_COPIED_CONTEXT"
1221        then
1222                GIT_TEST_CMP="$DIFF -c"
1223        else
1224                GIT_TEST_CMP="$DIFF -u"
1225        fi
1226fi
1227
1228GITPERLLIB="$GIT_BUILD_DIR"/perl/build/lib
1229export GITPERLLIB
1230test -d "$GIT_BUILD_DIR"/templates/blt || {
1231        error "You haven't built things yet, have you?"
1232}
1233
1234if ! test -x "$GIT_BUILD_DIR"/t/helper/test-tool
1235then
1236        echo >&2 'You need to build test-tool:'
1237        echo >&2 'Run "make t/helper/test-tool" in the source (toplevel) directory'
1238        exit 1
1239fi
1240
1241# Test repository
1242rm -fr "$TRASH_DIRECTORY" || {
1243        GIT_EXIT_OK=t
1244        echo >&5 "FATAL: Cannot prepare test area"
1245        exit 1
1246}
1247
1248HOME="$TRASH_DIRECTORY"
1249GNUPGHOME="$HOME/gnupg-home-not-used"
1250export HOME GNUPGHOME
1251
1252if test -z "$TEST_NO_CREATE_REPO"
1253then
1254        test_create_repo "$TRASH_DIRECTORY"
1255else
1256        mkdir -p "$TRASH_DIRECTORY"
1257fi
1258
1259# Use -P to resolve symlinks in our working directory so that the cwd
1260# in subprocesses like git equals our $PWD (for pathname comparisons).
1261cd -P "$TRASH_DIRECTORY" || exit 1
1262
1263this_test=${0##*/}
1264this_test=${this_test%%-*}
1265if match_pattern_list "$this_test" $GIT_SKIP_TESTS
1266then
1267        say_color info >&3 "skipping test $this_test altogether"
1268        skip_all="skip all tests in $this_test"
1269        test_done
1270fi
1271
1272if test -n "$write_junit_xml"
1273then
1274        junit_xml_dir="$TEST_OUTPUT_DIRECTORY/out"
1275        mkdir -p "$junit_xml_dir"
1276        junit_xml_base=${0##*/}
1277        junit_xml_path="$junit_xml_dir/TEST-${junit_xml_base%.sh}.xml"
1278        junit_attrs="name=\"${junit_xml_base%.sh}\""
1279        junit_attrs="$junit_attrs timestamp=\"$(TZ=UTC \
1280                date +%Y-%m-%dT%H:%M:%S)\""
1281        write_junit_xml --truncate "<testsuites>" "  <testsuite $junit_attrs>"
1282        junit_suite_start=$(test-tool date getnanos)
1283fi
1284
1285# Provide an implementation of the 'yes' utility
1286yes () {
1287        if test $# = 0
1288        then
1289                y=y
1290        else
1291                y="$*"
1292        fi
1293
1294        i=0
1295        while test $i -lt 99
1296        do
1297                echo "$y"
1298                i=$(($i+1))
1299        done
1300}
1301
1302# Fix some commands on Windows
1303uname_s=$(uname -s)
1304case $uname_s in
1305*MINGW*)
1306        # Windows has its own (incompatible) sort and find
1307        sort () {
1308                /usr/bin/sort "$@"
1309        }
1310        find () {
1311                /usr/bin/find "$@"
1312        }
1313        # git sees Windows-style pwd
1314        pwd () {
1315                builtin pwd -W
1316        }
1317        # no POSIX permissions
1318        # backslashes in pathspec are converted to '/'
1319        # exec does not inherit the PID
1320        test_set_prereq MINGW
1321        test_set_prereq NATIVE_CRLF
1322        test_set_prereq SED_STRIPS_CR
1323        test_set_prereq GREP_STRIPS_CR
1324        GIT_TEST_CMP=mingw_test_cmp
1325        ;;
1326*CYGWIN*)
1327        test_set_prereq POSIXPERM
1328        test_set_prereq EXECKEEPSPID
1329        test_set_prereq CYGWIN
1330        test_set_prereq SED_STRIPS_CR
1331        test_set_prereq GREP_STRIPS_CR
1332        ;;
1333*)
1334        test_set_prereq POSIXPERM
1335        test_set_prereq BSLASHPSPEC
1336        test_set_prereq EXECKEEPSPID
1337        ;;
1338esac
1339
1340( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1
1341test -z "$NO_PERL" && test_set_prereq PERL
1342test -z "$NO_PTHREADS" && test_set_prereq PTHREADS
1343test -z "$NO_PYTHON" && test_set_prereq PYTHON
1344test -n "$USE_LIBPCRE1$USE_LIBPCRE2" && test_set_prereq PCRE
1345test -n "$USE_LIBPCRE1" && test_set_prereq LIBPCRE1
1346test -n "$USE_LIBPCRE2" && test_set_prereq LIBPCRE2
1347test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
1348
1349if test -n "$GIT_TEST_GETTEXT_POISON_ORIG"
1350then
1351        GIT_TEST_GETTEXT_POISON=$GIT_TEST_GETTEXT_POISON_ORIG
1352        unset GIT_TEST_GETTEXT_POISON_ORIG
1353fi
1354
1355# Can we rely on git's output in the C locale?
1356if test -z "$GIT_TEST_GETTEXT_POISON"
1357then
1358        test_set_prereq C_LOCALE_OUTPUT
1359fi
1360
1361if test -z "$GIT_TEST_CHECK_CACHE_TREE"
1362then
1363        GIT_TEST_CHECK_CACHE_TREE=true
1364        export GIT_TEST_CHECK_CACHE_TREE
1365fi
1366
1367test_lazy_prereq PIPE '
1368        # test whether the filesystem supports FIFOs
1369        test_have_prereq !MINGW,!CYGWIN &&
1370        rm -f testfifo && mkfifo testfifo
1371'
1372
1373test_lazy_prereq SYMLINKS '
1374        # test whether the filesystem supports symbolic links
1375        ln -s x y && test -h y
1376'
1377
1378test_lazy_prereq FILEMODE '
1379        test "$(git config --bool core.filemode)" = true
1380'
1381
1382test_lazy_prereq CASE_INSENSITIVE_FS '
1383        echo good >CamelCase &&
1384        echo bad >camelcase &&
1385        test "$(cat CamelCase)" != good
1386'
1387
1388test_lazy_prereq FUNNYNAMES '
1389        test_have_prereq !MINGW &&
1390        touch -- \
1391                "FUNNYNAMES tab embedded" \
1392                "FUNNYNAMES \"quote embedded\"" \
1393                "FUNNYNAMES newline
1394embedded" 2>/dev/null &&
1395        rm -- \
1396                "FUNNYNAMES tab embedded" \
1397                "FUNNYNAMES \"quote embedded\"" \
1398                "FUNNYNAMES newline
1399embedded" 2>/dev/null
1400'
1401
1402test_lazy_prereq UTF8_NFD_TO_NFC '
1403        # check whether FS converts nfd unicode to nfc
1404        auml=$(printf "\303\244")
1405        aumlcdiar=$(printf "\141\314\210")
1406        >"$auml" &&
1407        test -f "$aumlcdiar"
1408'
1409
1410test_lazy_prereq AUTOIDENT '
1411        sane_unset GIT_AUTHOR_NAME &&
1412        sane_unset GIT_AUTHOR_EMAIL &&
1413        git var GIT_AUTHOR_IDENT
1414'
1415
1416test_lazy_prereq EXPENSIVE '
1417        test -n "$GIT_TEST_LONG"
1418'
1419
1420test_lazy_prereq EXPENSIVE_ON_WINDOWS '
1421        test_have_prereq EXPENSIVE || test_have_prereq !MINGW,!CYGWIN
1422'
1423
1424test_lazy_prereq USR_BIN_TIME '
1425        test -x /usr/bin/time
1426'
1427
1428test_lazy_prereq NOT_ROOT '
1429        uid=$(id -u) &&
1430        test "$uid" != 0
1431'
1432
1433test_lazy_prereq JGIT '
1434        type jgit
1435'
1436
1437# SANITY is about "can you correctly predict what the filesystem would
1438# do by only looking at the permission bits of the files and
1439# directories?"  A typical example of !SANITY is running the test
1440# suite as root, where a test may expect "chmod -r file && cat file"
1441# to fail because file is supposed to be unreadable after a successful
1442# chmod.  In an environment (i.e. combination of what filesystem is
1443# being used and who is running the tests) that lacks SANITY, you may
1444# be able to delete or create a file when the containing directory
1445# doesn't have write permissions, or access a file even if the
1446# containing directory doesn't have read or execute permissions.
1447
1448test_lazy_prereq SANITY '
1449        mkdir SANETESTD.1 SANETESTD.2 &&
1450
1451        chmod +w SANETESTD.1 SANETESTD.2 &&
1452        >SANETESTD.1/x 2>SANETESTD.2/x &&
1453        chmod -w SANETESTD.1 &&
1454        chmod -r SANETESTD.1/x &&
1455        chmod -rx SANETESTD.2 ||
1456        BUG "cannot prepare SANETESTD"
1457
1458        ! test -r SANETESTD.1/x &&
1459        ! rm SANETESTD.1/x && ! test -f SANETESTD.2/x
1460        status=$?
1461
1462        chmod +rwx SANETESTD.1 SANETESTD.2 &&
1463        rm -rf SANETESTD.1 SANETESTD.2 ||
1464        BUG "cannot clean SANETESTD"
1465        return $status
1466'
1467
1468test FreeBSD != $uname_s || GIT_UNZIP=${GIT_UNZIP:-/usr/local/bin/unzip}
1469GIT_UNZIP=${GIT_UNZIP:-unzip}
1470test_lazy_prereq UNZIP '
1471        "$GIT_UNZIP" -v
1472        test $? -ne 127
1473'
1474
1475run_with_limited_cmdline () {
1476        (ulimit -s 128 && "$@")
1477}
1478
1479test_lazy_prereq CMDLINE_LIMIT '
1480        test_have_prereq !MINGW,!CYGWIN &&
1481        run_with_limited_cmdline true
1482'
1483
1484run_with_limited_stack () {
1485        (ulimit -s 128 && "$@")
1486}
1487
1488test_lazy_prereq ULIMIT_STACK_SIZE '
1489        test_have_prereq !MINGW,!CYGWIN &&
1490        run_with_limited_stack true
1491'
1492
1493build_option () {
1494        git version --build-options |
1495        sed -ne "s/^$1: //p"
1496}
1497
1498test_lazy_prereq LONG_IS_64BIT '
1499        test 8 -le "$(build_option sizeof-long)"
1500'
1501
1502test_lazy_prereq TIME_IS_64BIT 'test-tool date is64bit'
1503test_lazy_prereq TIME_T_IS_64BIT 'test-tool date time_t-is64bit'
1504
1505test_lazy_prereq CURL '
1506        curl --version
1507'
1508
1509# SHA1 is a test if the hash algorithm in use is SHA-1.  This is both for tests
1510# which will not work with other hash algorithms and tests that work but don't
1511# test anything meaningful (e.g. special values which cause short collisions).
1512test_lazy_prereq SHA1 '
1513        test $(git hash-object /dev/null) = e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
1514'
1515
1516test_lazy_prereq REBASE_P '
1517        test -z "$GIT_TEST_SKIP_REBASE_P"
1518'