t / test-lib.shon commit t/test-lib: make sure Git has already been built (2006f0a)
   1#!/bin/sh
   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# if --tee was passed, write the output not only to the terminal, but
  19# additionally to the file test-results/$BASENAME.out, too.
  20case "$GIT_TEST_TEE_STARTED, $* " in
  21done,*)
  22        # do not redirect again
  23        ;;
  24*' --tee '*|*' --va'*)
  25        mkdir -p test-results
  26        BASE=test-results/$(basename "$0" .sh)
  27        (GIT_TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;
  28         echo $? > $BASE.exit) | tee $BASE.out
  29        test "$(cat $BASE.exit)" = 0
  30        exit
  31        ;;
  32esac
  33
  34# Keep the original TERM for say_color
  35ORIGINAL_TERM=$TERM
  36
  37# Test the binaries we have just built.  The tests are kept in
  38# t/ subdirectory and are run in 'trash directory' subdirectory.
  39if test -z "$TEST_DIRECTORY"
  40then
  41        # We allow tests to override this, in case they want to run tests
  42        # outside of t/, e.g. for running tests on the test library
  43        # itself.
  44        TEST_DIRECTORY=$(pwd)
  45fi
  46if test -z "$TEST_OUTPUT_DIRECTORY"
  47then
  48        # Similarly, override this to store the test-results subdir
  49        # elsewhere
  50        TEST_OUTPUT_DIRECTORY=$TEST_DIRECTORY
  51fi
  52GIT_BUILD_DIR="$TEST_DIRECTORY"/..
  53
  54################################################################
  55# It appears that people try to run tests without building...
  56"$GIT_BUILD_DIR/git" >/dev/null
  57if test $? != 1
  58then
  59        echo >&2 'error: you do not seem to have built git yet.'
  60        exit 1
  61fi
  62
  63. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
  64export PERL_PATH SHELL_PATH
  65
  66# For repeatability, reset the environment to known value.
  67LANG=C
  68LC_ALL=C
  69PAGER=cat
  70TZ=UTC
  71TERM=dumb
  72export LANG LC_ALL PAGER TERM TZ
  73EDITOR=:
  74# A call to "unset" with no arguments causes at least Solaris 10
  75# /usr/xpg4/bin/sh and /bin/ksh to bail out.  So keep the unsets
  76# deriving from the command substitution clustered with the other
  77# ones.
  78unset VISUAL EMAIL LANGUAGE COLUMNS $("$PERL_PATH" -e '
  79        my @env = keys %ENV;
  80        my $ok = join("|", qw(
  81                TRACE
  82                DEBUG
  83                USE_LOOKUP
  84                TEST
  85                .*_TEST
  86                PROVE
  87                VALGRIND
  88                PERF_AGGREGATING_LATER
  89        ));
  90        my @vars = grep(/^GIT_/ && !/^GIT_($ok)/o, @env);
  91        print join("\n", @vars);
  92')
  93unset XDG_CONFIG_HOME
  94GIT_AUTHOR_EMAIL=author@example.com
  95GIT_AUTHOR_NAME='A U Thor'
  96GIT_COMMITTER_EMAIL=committer@example.com
  97GIT_COMMITTER_NAME='C O Mitter'
  98GIT_MERGE_VERBOSITY=5
  99GIT_MERGE_AUTOEDIT=no
 100export GIT_MERGE_VERBOSITY GIT_MERGE_AUTOEDIT
 101export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
 102export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
 103export EDITOR
 104
 105# Protect ourselves from common misconfiguration to export
 106# CDPATH into the environment
 107unset CDPATH
 108
 109unset GREP_OPTIONS
 110
 111case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in
 112        1|2|true)
 113                echo "* warning: Some tests will not work if GIT_TRACE" \
 114                        "is set as to trace on STDERR ! *"
 115                echo "* warning: Please set GIT_TRACE to something" \
 116                        "other than 1, 2 or true ! *"
 117                ;;
 118esac
 119
 120# Convenience
 121#
 122# A regexp to match 5 and 40 hexdigits
 123_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
 124_x40="$_x05$_x05$_x05$_x05$_x05$_x05$_x05$_x05"
 125
 126# Zero SHA-1
 127_z40=0000000000000000000000000000000000000000
 128
 129# Line feed
 130LF='
 131'
 132
 133export _x05 _x40 _z40 LF
 134
 135# Each test should start with something like this, after copyright notices:
 136#
 137# test_description='Description of this test...
 138# This test checks if command xyzzy does the right thing...
 139# '
 140# . ./test-lib.sh
 141[ "x$ORIGINAL_TERM" != "xdumb" ] && (
 142                TERM=$ORIGINAL_TERM &&
 143                export TERM &&
 144                [ -t 1 ] &&
 145                tput bold >/dev/null 2>&1 &&
 146                tput setaf 1 >/dev/null 2>&1 &&
 147                tput sgr0 >/dev/null 2>&1
 148        ) &&
 149        color=t
 150
 151while test "$#" -ne 0
 152do
 153        case "$1" in
 154        -d|--d|--de|--deb|--debu|--debug)
 155                debug=t; shift ;;
 156        -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate)
 157                immediate=t; shift ;;
 158        -l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)
 159                GIT_TEST_LONG=t; export GIT_TEST_LONG; shift ;;
 160        -h|--h|--he|--hel|--help)
 161                help=t; shift ;;
 162        -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
 163                verbose=t; shift ;;
 164        -q|--q|--qu|--qui|--quie|--quiet)
 165                # Ignore --quiet under a TAP::Harness. Saying how many tests
 166                # passed without the ok/not ok details is always an error.
 167                test -z "$HARNESS_ACTIVE" && quiet=t; shift ;;
 168        --with-dashes)
 169                with_dashes=t; shift ;;
 170        --no-color)
 171                color=; shift ;;
 172        --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)
 173                valgrind=t; verbose=t; shift ;;
 174        --tee)
 175                shift ;; # was handled already
 176        --root=*)
 177                root=$(expr "z$1" : 'z[^=]*=\(.*\)')
 178                shift ;;
 179        *)
 180                echo "error: unknown test option '$1'" >&2; exit 1 ;;
 181        esac
 182done
 183
 184if test -n "$color"; then
 185        say_color () {
 186                (
 187                TERM=$ORIGINAL_TERM
 188                export TERM
 189                case "$1" in
 190                        error) tput bold; tput setaf 1;; # bold red
 191                        skip)  tput bold; tput setaf 2;; # bold green
 192                        pass)  tput setaf 2;;            # green
 193                        info)  tput setaf 3;;            # brown
 194                        *) test -n "$quiet" && return;;
 195                esac
 196                shift
 197                printf "%s" "$*"
 198                tput sgr0
 199                echo
 200                )
 201        }
 202else
 203        say_color() {
 204                test -z "$1" && test -n "$quiet" && return
 205                shift
 206                echo "$*"
 207        }
 208fi
 209
 210error () {
 211        say_color error "error: $*"
 212        GIT_EXIT_OK=t
 213        exit 1
 214}
 215
 216say () {
 217        say_color info "$*"
 218}
 219
 220test "${test_description}" != "" ||
 221error "Test script did not set test_description."
 222
 223if test "$help" = "t"
 224then
 225        echo "$test_description"
 226        exit 0
 227fi
 228
 229exec 5>&1
 230exec 6<&0
 231if test "$verbose" = "t"
 232then
 233        exec 4>&2 3>&1
 234else
 235        exec 4>/dev/null 3>/dev/null
 236fi
 237
 238test_failure=0
 239test_count=0
 240test_fixed=0
 241test_broken=0
 242test_success=0
 243
 244test_external_has_tap=0
 245
 246die () {
 247        code=$?
 248        if test -n "$GIT_EXIT_OK"
 249        then
 250                exit $code
 251        else
 252                echo >&5 "FATAL: Unexpected exit with code $code"
 253                exit 1
 254        fi
 255}
 256
 257GIT_EXIT_OK=
 258trap 'die' EXIT
 259
 260# The user-facing functions are loaded from a separate file so that
 261# test_perf subshells can have them too
 262. "$TEST_DIRECTORY/test-lib-functions.sh"
 263
 264# You are not expected to call test_ok_ and test_failure_ directly, use
 265# the text_expect_* functions instead.
 266
 267test_ok_ () {
 268        test_success=$(($test_success + 1))
 269        say_color "" "ok $test_count - $@"
 270}
 271
 272test_failure_ () {
 273        test_failure=$(($test_failure + 1))
 274        say_color error "not ok - $test_count $1"
 275        shift
 276        echo "$@" | sed -e 's/^/#       /'
 277        test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
 278}
 279
 280test_known_broken_ok_ () {
 281        test_fixed=$(($test_fixed+1))
 282        say_color "" "ok $test_count - $@ # TODO known breakage"
 283}
 284
 285test_known_broken_failure_ () {
 286        test_broken=$(($test_broken+1))
 287        say_color skip "not ok $test_count - $@ # TODO known breakage"
 288}
 289
 290test_debug () {
 291        test "$debug" = "" || eval "$1"
 292}
 293
 294test_eval_ () {
 295        # This is a separate function because some tests use
 296        # "return" to end a test_expect_success block early.
 297        eval </dev/null >&3 2>&4 "$*"
 298}
 299
 300test_run_ () {
 301        test_cleanup=:
 302        expecting_failure=$2
 303        test_eval_ "$1"
 304        eval_ret=$?
 305
 306        if test -z "$immediate" || test $eval_ret = 0 || test -n "$expecting_failure"
 307        then
 308                test_eval_ "$test_cleanup"
 309        fi
 310        if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then
 311                echo ""
 312        fi
 313        return "$eval_ret"
 314}
 315
 316test_skip () {
 317        test_count=$(($test_count+1))
 318        to_skip=
 319        for skp in $GIT_SKIP_TESTS
 320        do
 321                case $this_test.$test_count in
 322                $skp)
 323                        to_skip=t
 324                        break
 325                esac
 326        done
 327        if test -z "$to_skip" && test -n "$test_prereq" &&
 328           ! test_have_prereq "$test_prereq"
 329        then
 330                to_skip=t
 331        fi
 332        case "$to_skip" in
 333        t)
 334                of_prereq=
 335                if test "$missing_prereq" != "$test_prereq"
 336                then
 337                        of_prereq=" of $test_prereq"
 338                fi
 339
 340                say_color skip >&3 "skipping test: $@"
 341                say_color skip "ok $test_count # skip $1 (missing $missing_prereq${of_prereq})"
 342                : true
 343                ;;
 344        *)
 345                false
 346                ;;
 347        esac
 348}
 349
 350# stub; perf-lib overrides it
 351test_at_end_hook_ () {
 352        :
 353}
 354
 355test_done () {
 356        GIT_EXIT_OK=t
 357
 358        if test -z "$HARNESS_ACTIVE"; then
 359                test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results"
 360                mkdir -p "$test_results_dir"
 361                test_results_path="$test_results_dir/${0%.sh}-$$.counts"
 362
 363                cat >>"$test_results_path" <<-EOF
 364                total $test_count
 365                success $test_success
 366                fixed $test_fixed
 367                broken $test_broken
 368                failed $test_failure
 369
 370                EOF
 371        fi
 372
 373        if test "$test_fixed" != 0
 374        then
 375                say_color pass "# fixed $test_fixed known breakage(s)"
 376        fi
 377        if test "$test_broken" != 0
 378        then
 379                say_color error "# still have $test_broken known breakage(s)"
 380                msg="remaining $(($test_count-$test_broken)) test(s)"
 381        else
 382                msg="$test_count test(s)"
 383        fi
 384        case "$test_failure" in
 385        0)
 386                # Maybe print SKIP message
 387                [ -z "$skip_all" ] || skip_all=" # SKIP $skip_all"
 388
 389                if test $test_external_has_tap -eq 0; then
 390                        say_color pass "# passed all $msg"
 391                        say "1..$test_count$skip_all"
 392                fi
 393
 394                test -d "$remove_trash" &&
 395                cd "$(dirname "$remove_trash")" &&
 396                rm -rf "$(basename "$remove_trash")"
 397
 398                test_at_end_hook_
 399
 400                exit 0 ;;
 401
 402        *)
 403                if test $test_external_has_tap -eq 0; then
 404                        say_color error "# failed $test_failure among $msg"
 405                        say "1..$test_count"
 406                fi
 407
 408                exit 1 ;;
 409
 410        esac
 411}
 412
 413if test -n "$valgrind"
 414then
 415        make_symlink () {
 416                test -h "$2" &&
 417                test "$1" = "$(readlink "$2")" || {
 418                        # be super paranoid
 419                        if mkdir "$2".lock
 420                        then
 421                                rm -f "$2" &&
 422                                ln -s "$1" "$2" &&
 423                                rm -r "$2".lock
 424                        else
 425                                while test -d "$2".lock
 426                                do
 427                                        say "Waiting for lock on $2."
 428                                        sleep 1
 429                                done
 430                        fi
 431                }
 432        }
 433
 434        make_valgrind_symlink () {
 435                # handle only executables, unless they are shell libraries that
 436                # need to be in the exec-path.  We will just use "#!" as a
 437                # guess for a shell-script, since we have no idea what the user
 438                # may have configured as the shell path.
 439                test -x "$1" ||
 440                test "#!" = "$(head -c 2 <"$1")" ||
 441                return;
 442
 443                base=$(basename "$1")
 444                symlink_target=$GIT_BUILD_DIR/$base
 445                # do not override scripts
 446                if test -x "$symlink_target" &&
 447                    test ! -d "$symlink_target" &&
 448                    test "#!" != "$(head -c 2 < "$symlink_target")"
 449                then
 450                        symlink_target=../valgrind.sh
 451                fi
 452                case "$base" in
 453                *.sh|*.perl)
 454                        symlink_target=../unprocessed-script
 455                esac
 456                # create the link, or replace it if it is out of date
 457                make_symlink "$symlink_target" "$GIT_VALGRIND/bin/$base" || exit
 458        }
 459
 460        # override all git executables in TEST_DIRECTORY/..
 461        GIT_VALGRIND=$TEST_DIRECTORY/valgrind
 462        mkdir -p "$GIT_VALGRIND"/bin
 463        for file in $GIT_BUILD_DIR/git* $GIT_BUILD_DIR/test-*
 464        do
 465                make_valgrind_symlink $file
 466        done
 467        # special-case the mergetools loadables
 468        make_symlink "$GIT_BUILD_DIR"/mergetools "$GIT_VALGRIND/bin/mergetools"
 469        OLDIFS=$IFS
 470        IFS=:
 471        for path in $PATH
 472        do
 473                ls "$path"/git-* 2> /dev/null |
 474                while read file
 475                do
 476                        make_valgrind_symlink "$file"
 477                done
 478        done
 479        IFS=$OLDIFS
 480        PATH=$GIT_VALGRIND/bin:$PATH
 481        GIT_EXEC_PATH=$GIT_VALGRIND/bin
 482        export GIT_VALGRIND
 483elif test -n "$GIT_TEST_INSTALLED" ; then
 484        GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path)  ||
 485        error "Cannot run git from $GIT_TEST_INSTALLED."
 486        PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR:$PATH
 487        GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH}
 488else # normal case, use ../bin-wrappers only unless $with_dashes:
 489        git_bin_dir="$GIT_BUILD_DIR/bin-wrappers"
 490        if ! test -x "$git_bin_dir/git" ; then
 491                if test -z "$with_dashes" ; then
 492                        say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH"
 493                fi
 494                with_dashes=t
 495        fi
 496        PATH="$git_bin_dir:$PATH"
 497        GIT_EXEC_PATH=$GIT_BUILD_DIR
 498        if test -n "$with_dashes" ; then
 499                PATH="$GIT_BUILD_DIR:$PATH"
 500        fi
 501fi
 502GIT_TEMPLATE_DIR="$GIT_BUILD_DIR"/templates/blt
 503unset GIT_CONFIG
 504GIT_CONFIG_NOSYSTEM=1
 505GIT_ATTR_NOSYSTEM=1
 506export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_ATTR_NOSYSTEM
 507
 508if test -z "$GIT_TEST_CMP"
 509then
 510        if test -n "$GIT_TEST_CMP_USE_COPIED_CONTEXT"
 511        then
 512                GIT_TEST_CMP="$DIFF -c"
 513        else
 514                GIT_TEST_CMP="$DIFF -u"
 515        fi
 516fi
 517
 518GITPERLLIB="$GIT_BUILD_DIR"/perl/blib/lib:"$GIT_BUILD_DIR"/perl/blib/arch/auto/Git
 519export GITPERLLIB
 520test -d "$GIT_BUILD_DIR"/templates/blt || {
 521        error "You haven't built things yet, have you?"
 522}
 523
 524if test -z "$GIT_TEST_INSTALLED" && test -z "$NO_PYTHON"
 525then
 526        GITPYTHONLIB="$GIT_BUILD_DIR/git_remote_helpers/build/lib"
 527        export GITPYTHONLIB
 528        test -d "$GIT_BUILD_DIR"/git_remote_helpers/build || {
 529                error "You haven't built git_remote_helpers yet, have you?"
 530        }
 531fi
 532
 533if ! test -x "$GIT_BUILD_DIR"/test-chmtime; then
 534        echo >&2 'You need to build test-chmtime:'
 535        echo >&2 'Run "make test-chmtime" in the source (toplevel) directory'
 536        exit 1
 537fi
 538
 539# Test repository
 540test="trash directory.$(basename "$0" .sh)"
 541test -n "$root" && test="$root/$test"
 542case "$test" in
 543/*) TRASH_DIRECTORY="$test" ;;
 544 *) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$test" ;;
 545esac
 546test ! -z "$debug" || remove_trash=$TRASH_DIRECTORY
 547rm -fr "$test" || {
 548        GIT_EXIT_OK=t
 549        echo >&5 "FATAL: Cannot prepare test area"
 550        exit 1
 551}
 552
 553HOME="$TRASH_DIRECTORY"
 554export HOME
 555
 556if test -z "$TEST_NO_CREATE_REPO"; then
 557        test_create_repo "$test"
 558else
 559        mkdir -p "$test"
 560fi
 561# Use -P to resolve symlinks in our working directory so that the cwd
 562# in subprocesses like git equals our $PWD (for pathname comparisons).
 563cd -P "$test" || exit 1
 564
 565this_test=${0##*/}
 566this_test=${this_test%%-*}
 567for skp in $GIT_SKIP_TESTS
 568do
 569        case "$this_test" in
 570        $skp)
 571                say_color skip >&3 "skipping test $this_test altogether"
 572                skip_all="skip all tests in $this_test"
 573                test_done
 574        esac
 575done
 576
 577# Provide an implementation of the 'yes' utility
 578yes () {
 579        if test $# = 0
 580        then
 581                y=y
 582        else
 583                y="$*"
 584        fi
 585
 586        while echo "$y"
 587        do
 588                :
 589        done
 590}
 591
 592# Fix some commands on Windows
 593case $(uname -s) in
 594*MINGW*)
 595        # Windows has its own (incompatible) sort and find
 596        sort () {
 597                /usr/bin/sort "$@"
 598        }
 599        find () {
 600                /usr/bin/find "$@"
 601        }
 602        sum () {
 603                md5sum "$@"
 604        }
 605        # git sees Windows-style pwd
 606        pwd () {
 607                builtin pwd -W
 608        }
 609        # no POSIX permissions
 610        # backslashes in pathspec are converted to '/'
 611        # exec does not inherit the PID
 612        test_set_prereq MINGW
 613        test_set_prereq SED_STRIPS_CR
 614        ;;
 615*CYGWIN*)
 616        test_set_prereq POSIXPERM
 617        test_set_prereq EXECKEEPSPID
 618        test_set_prereq NOT_MINGW
 619        test_set_prereq SED_STRIPS_CR
 620        ;;
 621*)
 622        test_set_prereq POSIXPERM
 623        test_set_prereq BSLASHPSPEC
 624        test_set_prereq EXECKEEPSPID
 625        test_set_prereq NOT_MINGW
 626        ;;
 627esac
 628
 629( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1
 630test -z "$NO_PERL" && test_set_prereq PERL
 631test -z "$NO_PYTHON" && test_set_prereq PYTHON
 632test -n "$USE_LIBPCRE" && test_set_prereq LIBPCRE
 633test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
 634
 635# Can we rely on git's output in the C locale?
 636if test -n "$GETTEXT_POISON"
 637then
 638        GIT_GETTEXT_POISON=YesPlease
 639        export GIT_GETTEXT_POISON
 640        test_set_prereq GETTEXT_POISON
 641else
 642        test_set_prereq C_LOCALE_OUTPUT
 643fi
 644
 645# Use this instead of test_cmp to compare files that contain expected and
 646# actual output from git commands that can be translated.  When running
 647# under GETTEXT_POISON this pretends that the command produced expected
 648# results.
 649test_i18ncmp () {
 650        test -n "$GETTEXT_POISON" || test_cmp "$@"
 651}
 652
 653# Use this instead of "grep expected-string actual" to see if the
 654# output from a git command that can be translated either contains an
 655# expected string, or does not contain an unwanted one.  When running
 656# under GETTEXT_POISON this pretends that the command produced expected
 657# results.
 658test_i18ngrep () {
 659        if test -n "$GETTEXT_POISON"
 660        then
 661            : # pretend success
 662        elif test "x!" = "x$1"
 663        then
 664                shift
 665                ! grep "$@"
 666        else
 667                grep "$@"
 668        fi
 669}
 670
 671test_lazy_prereq SYMLINKS '
 672        # test whether the filesystem supports symbolic links
 673        ln -s x y && test -h y
 674'
 675
 676test_lazy_prereq CASE_INSENSITIVE_FS '
 677        echo good >CamelCase &&
 678        echo bad >camelcase &&
 679        test "$(cat CamelCase)" != good
 680'
 681
 682test_lazy_prereq UTF8_NFD_TO_NFC '
 683        # check whether FS converts nfd unicode to nfc
 684        auml=$(printf "\303\244")
 685        aumlcdiar=$(printf "\141\314\210")
 686        >"$auml" &&
 687        case "$(echo *)" in
 688        "$aumlcdiar")
 689                true ;;
 690        *)
 691                false ;;
 692        esac
 693'
 694
 695# When the tests are run as root, permission tests will report that
 696# things are writable when they shouldn't be.
 697test -w / || test_set_prereq SANITY