1#!/bin/sh 2# 3# Copyright (c) 2005 Junio C Hamano 4# 5 6# Keep the original TERM for say_color 7ORIGINAL_TERM=$TERM 8 9# For repeatability, reset the environment to known value. 10LANG=C 11LC_ALL=C 12PAGER=cat 13TZ=UTC 14TERM=dumb 15export LANG LC_ALL PAGER TERM TZ 16EDITOR=: 17VISUAL=: 18unset GIT_EDITOR 19unset AUTHOR_DATE 20unset AUTHOR_EMAIL 21unset AUTHOR_NAME 22unset COMMIT_AUTHOR_EMAIL 23unset COMMIT_AUTHOR_NAME 24unset EMAIL 25unset GIT_ALTERNATE_OBJECT_DIRECTORIES 26unset GIT_AUTHOR_DATE 27GIT_AUTHOR_EMAIL=author@example.com 28GIT_AUTHOR_NAME='A U Thor' 29unset GIT_COMMITTER_DATE 30GIT_COMMITTER_EMAIL=committer@example.com 31GIT_COMMITTER_NAME='C O Mitter' 32unset GIT_DIFF_OPTS 33unset GIT_DIR 34unset GIT_WORK_TREE 35unset GIT_EXTERNAL_DIFF 36unset GIT_INDEX_FILE 37unset GIT_OBJECT_DIRECTORY 38unset GIT_CEILING_DIRECTORIES 39unset SHA1_FILE_DIRECTORIES 40unset SHA1_FILE_DIRECTORY 41GIT_MERGE_VERBOSITY=5 42export GIT_MERGE_VERBOSITY 43export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME 44export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME 45export EDITOR VISUAL 46GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u} 47 48# Protect ourselves from common misconfiguration to export 49# CDPATH into the environment 50unset CDPATH 51 52case$(echo $GIT_TRACE |tr "[A-Z]" "[a-z]")in 531|2|true) 54echo"* warning: Some tests will not work if GIT_TRACE" \ 55"is set as to trace on STDERR ! *" 56echo"* warning: Please set GIT_TRACE to something" \ 57"other than 1, 2 or true ! *" 58;; 59esac 60 61# Each test should start with something like this, after copyright notices: 62# 63# test_description='Description of this test... 64# This test checks if command xyzzy does the right thing... 65# ' 66# . ./test-lib.sh 67["x$ORIGINAL_TERM"!="xdumb"] && ( 68 TERM=$ORIGINAL_TERM&& 69export TERM && 70[-t1] && 71tput bold >/dev/null 2>&1&& 72tput setaf 1>/dev/null 2>&1&& 73tput sgr0 >/dev/null 2>&1 74) && 75 color=t 76 77whiletest"$#"-ne0 78do 79case"$1"in 80-d|--d|--de|--deb|--debu|--debug) 81 debug=t;shift;; 82-i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate) 83 immediate=t;shift;; 84-l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests) 85export GIT_TEST_LONG=t;shift;; 86-h|--h|--he|--hel|--help) 87help=t;shift;; 88-v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose) 89 verbose=t;shift;; 90-q|--q|--qu|--qui|--quie|--quiet) 91 quiet=t;shift;; 92--no-color) 93 color=;shift;; 94--no-python) 95# noop now... 96shift;; 97--va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind) 98 valgrind=t;shift;; 99*) 100break;; 101esac 102done 103 104iftest -n"$color";then 105 say_color () { 106( 107 TERM=$ORIGINAL_TERM 108export TERM 109case"$1"in 110 error)tput bold;tput setaf 1;;# bold red 111 skip)tput bold;tput setaf 2;;# bold green 112 pass)tput setaf 2;;# green 113 info)tput setaf 3;;# brown 114*)test -n"$quiet"&&return;; 115esac 116shift 117printf"* %s""$*" 118tput sgr0 119echo 120) 121} 122else 123 say_color() { 124test -z"$1"&&test -n"$quiet"&&return 125shift 126echo"* $*" 127} 128fi 129 130error () { 131 say_color error "error: $*" 132trap- EXIT 133exit1 134} 135 136say () { 137 say_color info "$*" 138} 139 140test"${test_description}"!=""|| 141error "Test script did not set test_description." 142 143iftest"$help"="t" 144then 145echo"$test_description" 146exit0 147fi 148 149exec5>&1 150iftest"$verbose"="t" 151then 152exec4>&2 3>&1 153else 154exec4>/dev/null 3>/dev/null 155fi 156 157test_failure=0 158test_count=0 159test_fixed=0 160test_broken=0 161test_success=0 162 163die () { 164echo>&5"FATAL: Unexpected exit with code $?" 165exit1 166} 167 168trap'die' EXIT 169 170# The semantics of the editor variables are that of invoking 171# sh -c "$EDITOR \"$@\"" files ... 172# 173# If our trash directory contains shell metacharacters, they will be 174# interpreted if we just set $EDITOR directly, so do a little dance with 175# environment variables to work around this. 176# 177# In particular, quoting isn't enough, as the path may contain the same quote 178# that we're using. 179test_set_editor () { 180 FAKE_EDITOR="$1" 181export FAKE_EDITOR 182 VISUAL='"$FAKE_EDITOR"' 183export VISUAL 184} 185 186test_tick () { 187iftest -z"${test_tick+set}" 188then 189 test_tick=1112911993 190else 191 test_tick=$(($test_tick + 60)) 192fi 193 GIT_COMMITTER_DATE="$test_tick-0700" 194 GIT_AUTHOR_DATE="$test_tick-0700" 195export GIT_COMMITTER_DATE GIT_AUTHOR_DATE 196} 197 198# Call test_commit with the arguments "<message> [<file> [<contents>]]" 199# 200# This will commit a file with the given contents and the given commit 201# message. It will also add a tag with <message> as name. 202# 203# Both <file> and <contents> default to <message>. 204 205test_commit () { 206file=${2:-"$1.t"} 207echo"${3-$1}">"$file"&& 208 git add "$file"&& 209 test_tick && 210 git commit -m"$1"&& 211 git tag "$1" 212} 213 214# Call test_merge with the arguments "<message> <commit>", where <commit> 215# can be a tag pointing to the commit-to-merge. 216 217test_merge () { 218 test_tick && 219 git merge -m"$1""$2"&& 220 git tag "$1" 221} 222 223# You are not expected to call test_ok_ and test_failure_ directly, use 224# the text_expect_* functions instead. 225 226test_ok_ () { 227 test_count=$(expr "$test_count" + 1) 228 test_success=$(expr "$test_success" + 1) 229 say_color """ ok$test_count: $@" 230} 231 232test_failure_ () { 233 test_count=$(expr "$test_count" + 1) 234 test_failure=$(expr "$test_failure" + 1); 235 say_color error "FAIL$test_count:$1" 236shift 237echo"$@"|sed-e's/^/ /' 238test"$immediate"=""|| {trap- EXIT;exit1; } 239} 240 241test_known_broken_ok_ () { 242 test_count=$(expr "$test_count" + 1) 243 test_fixed=$(($test_fixed+1)) 244 say_color """ FIXED$test_count: $@" 245} 246 247test_known_broken_failure_ () { 248 test_count=$(expr "$test_count" + 1) 249 test_broken=$(($test_broken+1)) 250 say_color skip " still broken$test_count: $@" 251} 252 253test_debug () { 254test"$debug"=""||eval"$1" 255} 256 257test_run_ () { 258eval>&3 2>&4"$1" 259 eval_ret="$?" 260return0 261} 262 263test_skip () { 264 this_test=$(expr "./$0" : '.*/\(t[0-9]*\)-[^/]*$') 265 this_test="$this_test.$(expr "$test_count" + 1)" 266 to_skip= 267 for skp in$GIT_SKIP_TESTS 268 do 269 case "$this_test" in 270$skp) 271 to_skip=t 272 esac 273 done 274 case "$to_skip" in 275 t) 276 say_color skip >&3 "skipping test: $@" 277 test_count=$(expr "$test_count" + 1) 278 say_color skip "skip$test_count:$1" 279 : true 280 ;; 281 *) 282 false 283 ;; 284 esac 285} 286 287test_expect_failure () { 288 test "$#" = 2 || 289 error "bug in the test script: not 2 parameters to test-expect-failure" 290 if ! test_skip "$@" 291 then 292 say >&3 "checking known breakage:$2" 293 test_run_ "$2" 294 if [ "$?" = 0 -a "$eval_ret" = 0 ] 295 then 296 test_known_broken_ok_ "$1" 297 else 298 test_known_broken_failure_ "$1" 299 fi 300 fi 301 echo >&3 "" 302} 303 304test_expect_success () { 305 test "$#" = 2 || 306 error "bug in the test script: not 2 parameters to test-expect-success" 307 if ! test_skip "$@" 308 then 309 say >&3 "expecting success:$2" 310 test_run_ "$2" 311 if [ "$?" = 0 -a "$eval_ret" = 0 ] 312 then 313 test_ok_ "$1" 314 else 315 test_failure_ "$@" 316 fi 317 fi 318 echo >&3 "" 319} 320 321test_expect_code () { 322 test "$#" = 3 || 323 error "bug in the test script: not 3 parameters to test-expect-code" 324 if ! test_skip "$@" 325 then 326 say >&3 "expecting exit code$1:$3" 327 test_run_ "$3" 328 if [ "$?" = 0 -a "$eval_ret" = "$1" ] 329 then 330 test_ok_ "$2" 331 else 332 test_failure_ "$@" 333 fi 334 fi 335 echo >&3 "" 336} 337 338# test_external runs external test scripts that provide continuous 339# test output about their progress, and succeeds/fails on 340# zero/non-zero exit code. It outputs the test output on stdout even 341# in non-verbose mode, and announces the external script with "* run 342# <n>: ..." before running it. When providing relative paths, keep in 343# mind that all scripts run in "trash directory". 344# Usage: test_external description command arguments... 345# Example: test_external 'Perl API' perl ../path/to/test.pl 346test_external () { 347 test "$#" -eq 3 || 348 error >&5 "bug in the test script: not 3 parameters to test_external" 349 descr="$1" 350 shift 351 if ! test_skip "$descr" "$@" 352 then 353 # Announce the script to reduce confusion about the 354 # test output that follows. 355 say_color "" " run$(expr "$test_count" + 1):$descr($*)" 356 # Run command; redirect its stderr to &4 as in 357 # test_run_, but keep its stdout on our stdout even in 358 # non-verbose mode. 359 "$@" 2>&4 360 if [ "$?" = 0 ] 361 then 362 test_ok_ "$descr" 363 else 364 test_failure_ "$descr" "$@" 365 fi 366 fi 367} 368 369# Like test_external, but in addition tests that the command generated 370# no output on stderr. 371test_external_without_stderr () { 372 # The temporary file has no (and must have no) security 373 # implications. 374 tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi 375 stderr="$tmp/git-external-stderr.$$.tmp" 376 test_external "$@" 4> "$stderr" 377 [ -f "$stderr" ] || error "Internal error:$stderrdisappeared." 378 descr="no stderr:$1" 379 shift 380 say >&3 "expecting no stderr from previous command" 381 if [ ! -s "$stderr" ]; then 382 rm "$stderr" 383 test_ok_ "$descr" 384 else 385 if [ "$verbose" = t ]; then 386 output=`echo; echo Stderr is:; cat "$stderr"` 387 else 388 output= 389 fi 390 # rm first in case test_failure exits. 391 rm "$stderr" 392 test_failure_ "$descr" "$@" "$output" 393 fi 394} 395 396# This is not among top-level (test_expect_success | test_expect_failure) 397# but is a prefix that can be used in the test script, like: 398# 399# test_expect_success 'complain and die' ' 400# do something && 401# do something else && 402# test_must_fail git checkout ../outerspace 403# ' 404# 405# Writing this as "! git checkout ../outerspace" is wrong, because 406# the failure could be due to a segv. We want a controlled failure. 407 408test_must_fail () { 409"$@" 410test $? -gt0-a $? -le129-o $? -gt192 411} 412 413# test_cmp is a helper function to compare actual and expected output. 414# You can use it like: 415# 416# test_expect_success 'foo works' ' 417# echo expected >expected && 418# foo >actual && 419# test_cmp expected actual 420# ' 421# 422# This could be written as either "cmp" or "diff -u", but: 423# - cmp's output is not nearly as easy to read as diff -u 424# - not all diff versions understand "-u" 425 426test_cmp() { 427$GIT_TEST_CMP"$@" 428} 429 430# Most tests can use the created repository, but some may need to create more. 431# Usage: test_create_repo <directory> 432test_create_repo () { 433test"$#"=1|| 434 error "bug in the test script: not 1 parameter to test-create-repo" 435 owd=`pwd` 436 repo="$1" 437mkdir-p"$repo" 438cd"$repo"|| error "Cannot setup test environment" 439"$GIT_EXEC_PATH/git" init "--template=$GIT_EXEC_PATH/templates/blt/">&3 2>&4|| 440 error "cannot run git init -- have you built things yet?" 441mv .git/hooks .git/hooks-disabled 442cd"$owd" 443} 444 445test_done () { 446trap- EXIT 447 test_results_dir="$TEST_DIRECTORY/test-results" 448mkdir-p"$test_results_dir" 449 test_results_path="$test_results_dir/${0%-*}-$$" 450 451echo"total$test_count">>$test_results_path 452echo"success$test_success">>$test_results_path 453echo"fixed$test_fixed">>$test_results_path 454echo"broken$test_broken">>$test_results_path 455echo"failed$test_failure">>$test_results_path 456echo"">>$test_results_path 457 458iftest"$test_fixed"!=0 459then 460 say_color pass "fixed$test_fixedknown breakage(s)" 461fi 462iftest"$test_broken"!=0 463then 464 say_color error "still have$test_brokenknown breakage(s)" 465 msg="remaining$(($test_count-$test_broken)) test(s)" 466else 467 msg="$test_counttest(s)" 468fi 469case"$test_failure"in 4700) 471# We could: 472# cd .. && rm -fr 'trash directory' 473# but that means we forbid any tests that use their own 474# subdirectory from calling test_done without coming back 475# to where they started from. 476# The Makefile provided will clean this test area so 477# we will leave things as they are. 478 479 say_color pass "passed all$msg" 480 481test -d"$remove_trash"&& 482cd"$(dirname "$remove_trash")"&& 483rm-rf"$(basename "$remove_trash")" 484 485exit0;; 486 487*) 488 say_color error "failed$test_failureamong$msg" 489exit1;; 490 491esac 492} 493 494# Test the binaries we have just built. The tests are kept in 495# t/ subdirectory and are run in 'trash directory' subdirectory. 496TEST_DIRECTORY=$(pwd) 497iftest -z"$valgrind" 498then 499 PATH=$TEST_DIRECTORY/..:$PATH 500 GIT_EXEC_PATH=$TEST_DIRECTORY/.. 501else 502 make_symlink () { 503test -h"$2"&& 504test"$1"="$(readlink "$2")"|| { 505# be super paranoid 506ifmkdir"$2".lock 507then 508rm-f"$2"&& 509ln-s"$1""$2"&& 510rm-r"$2".lock 511else 512whiletest -d"$2".lock 513do 514 say "Waiting for lock on$2." 515sleep1 516done 517fi 518} 519} 520 521 make_valgrind_symlink () { 522# handle only executables 523test -x"$1"||return 524 525 base=$(basename "$1") 526 symlink_target=$TEST_DIRECTORY/../$base 527# do not override scripts 528iftest -x"$symlink_target"&& 529test!-d"$symlink_target"&& 530test"#!"!="$(head -c 2 < "$symlink_target")" 531then 532 symlink_target=../valgrind.sh 533fi 534case"$base"in 535*.sh|*.perl) 536 symlink_target=../unprocessed-script 537esac 538# create the link, or replace it if it is out of date 539 make_symlink "$symlink_target""$GIT_VALGRIND/bin/$base"||exit 540} 541 542# override all git executables in TEST_DIRECTORY/.. 543 GIT_VALGRIND=$TEST_DIRECTORY/valgrind 544mkdir-p"$GIT_VALGRIND"/bin 545forfilein$TEST_DIRECTORY/../git*$TEST_DIRECTORY/../test-* 546do 547 make_valgrind_symlink $file 548done 549 OLDIFS=$IFS 550 IFS=: 551for path in$PATH 552do 553ls"$path"/git-*2> /dev/null | 554whilereadfile 555do 556 make_valgrind_symlink "$file" 557done 558done 559 IFS=$OLDIFS 560 PATH=$GIT_VALGRIND/bin:$PATH 561 GIT_EXEC_PATH=$GIT_VALGRIND/bin 562export GIT_VALGRIND 563 564 make_symlink ../../../templates "$GIT_VALGRIND"/bin/templates ||exit 565fi 566GIT_TEMPLATE_DIR=$(pwd)/../templates/blt 567unset GIT_CONFIG 568GIT_CONFIG_NOSYSTEM=1 569GIT_CONFIG_NOGLOBAL=1 570export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOBAL 571 572GITPERLLIB=$(pwd)/../perl/blib/lib:$(pwd)/../perl/blib/arch/auto/Git 573export GITPERLLIB 574test -d ../templates/blt || { 575 error "You haven't built things yet, have you?" 576} 577 578if!test -x ../test-chmtime;then 579echo>&2'You need to build test-chmtime:' 580echo>&2'Run "make test-chmtime" in the source (toplevel) directory' 581exit1 582fi 583 584. ../GIT-BUILD-OPTIONS 585 586# Test repository 587test="trash directory.$(basename "$0" .sh)" 588test!-z"$debug"|| remove_trash="$TEST_DIRECTORY/$test" 589rm-fr"$test"|| { 590trap- EXIT 591echo>&5"FATAL: Cannot prepare test area" 592exit1 593} 594 595test_create_repo "$test" 596# Use -P to resolve symlinks in our working directory so that the cwd 597# in subprocesses like git equals our $PWD (for pathname comparisons). 598cd -P"$test"||exit1 599 600this_test=$(expr "./$0" : '.*/\(t[0-9]*\)-[^/]*$') 601for skp in$GIT_SKIP_TESTS 602do 603 to_skip= 604 for skp in$GIT_SKIP_TESTS 605 do 606 case "$this_test" in 607$skp) 608 to_skip=t 609 esac 610 done 611 case "$to_skip" in 612 t) 613 say_color skip >&3 "skipping test$this_testaltogether" 614 say_color skip "skip all tests in$this_test" 615 test_done 616 esac 617done