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