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