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*) 98break;; 99esac 100done 101 102iftest -n"$color";then 103 say_color () { 104( 105 TERM=$ORIGINAL_TERM 106export TERM 107case"$1"in 108 error)tput bold;tput setaf 1;;# bold red 109 skip)tput bold;tput setaf 2;;# bold green 110 pass)tput setaf 2;;# green 111 info)tput setaf 3;;# brown 112*)test -n"$quiet"&&return;; 113esac 114shift 115printf"* %s""$*" 116tput sgr0 117echo 118) 119} 120else 121 say_color() { 122test -z"$1"&&test -n"$quiet"&&return 123shift 124echo"* $*" 125} 126fi 127 128error () { 129 say_color error "error: $*" 130trap- EXIT 131exit1 132} 133 134say () { 135 say_color info "$*" 136} 137 138test"${test_description}"!=""|| 139error "Test script did not set test_description." 140 141iftest"$help"="t" 142then 143echo"$test_description" 144exit0 145fi 146 147exec5>&1 148iftest"$verbose"="t" 149then 150exec4>&2 3>&1 151else 152exec4>/dev/null 3>/dev/null 153fi 154 155test_failure=0 156test_count=0 157test_fixed=0 158test_broken=0 159test_success=0 160 161die () { 162echo>&5"FATAL: Unexpected exit with code $?" 163exit1 164} 165 166trap'die' EXIT 167 168# The semantics of the editor variables are that of invoking 169# sh -c "$EDITOR \"$@\"" files ... 170# 171# If our trash directory contains shell metacharacters, they will be 172# interpreted if we just set $EDITOR directly, so do a little dance with 173# environment variables to work around this. 174# 175# In particular, quoting isn't enough, as the path may contain the same quote 176# that we're using. 177test_set_editor () { 178 FAKE_EDITOR="$1" 179export FAKE_EDITOR 180 VISUAL='"$FAKE_EDITOR"' 181export VISUAL 182} 183 184test_tick () { 185iftest -z"${test_tick+set}" 186then 187 test_tick=1112911993 188else 189 test_tick=$(($test_tick + 60)) 190fi 191 GIT_COMMITTER_DATE="$test_tick-0700" 192 GIT_AUTHOR_DATE="$test_tick-0700" 193export GIT_COMMITTER_DATE GIT_AUTHOR_DATE 194} 195 196# Call test_commit with the arguments "<message> [<file> [<contents>]]" 197# 198# This will commit a file with the given contents and the given commit 199# message. It will also add a tag with <message> as name. 200# 201# Both <file> and <contents> default to <message>. 202 203test_commit () { 204file=${2:-$(echo "$1" | tr 'A-Z' 'a-z')} 205echo"${3-$1}">"$file"&& 206 git add "$file"&& 207 test_tick && 208 git commit -m"$1"&& 209 git tag "$1" 210} 211 212# Call test_merge with the arguments "<message> <commit>", where <commit> 213# can be a tag pointing to the commit-to-merge. 214 215test_merge () { 216 test_tick && 217 git merge -m"$1""$2"&& 218 git tag "$1" 219} 220 221# You are not expected to call test_ok_ and test_failure_ directly, use 222# the text_expect_* functions instead. 223 224test_ok_ () { 225 test_count=$(expr "$test_count" + 1) 226 test_success=$(expr "$test_success" + 1) 227 say_color """ ok$test_count: $@" 228} 229 230test_failure_ () { 231 test_count=$(expr "$test_count" + 1) 232 test_failure=$(expr "$test_failure" + 1); 233 say_color error "FAIL$test_count:$1" 234shift 235echo"$@"|sed-e's/^/ /' 236test"$immediate"=""|| {trap- EXIT;exit1; } 237} 238 239test_known_broken_ok_ () { 240 test_count=$(expr "$test_count" + 1) 241 test_fixed=$(($test_fixed+1)) 242 say_color """ FIXED$test_count: $@" 243} 244 245test_known_broken_failure_ () { 246 test_count=$(expr "$test_count" + 1) 247 test_broken=$(($test_broken+1)) 248 say_color skip " still broken$test_count: $@" 249} 250 251test_debug () { 252test"$debug"=""||eval"$1" 253} 254 255test_run_ () { 256eval>&3 2>&4"$1" 257 eval_ret="$?" 258return0 259} 260 261test_skip () { 262 this_test=$(expr "./$0" : '.*/\(t[0-9]*\)-[^/]*$') 263 this_test="$this_test.$(expr "$test_count" + 1)" 264 to_skip= 265 for skp in$GIT_SKIP_TESTS 266 do 267 case "$this_test" in 268$skp) 269 to_skip=t 270 esac 271 done 272 case "$to_skip" in 273 t) 274 say_color skip >&3 "skipping test: $@" 275 test_count=$(expr "$test_count" + 1) 276 say_color skip "skip$test_count:$1" 277 : true 278 ;; 279 *) 280 false 281 ;; 282 esac 283} 284 285test_expect_failure () { 286 test "$#" = 2 || 287 error "bug in the test script: not 2 parameters to test-expect-failure" 288 if ! test_skip "$@" 289 then 290 say >&3 "checking known breakage:$2" 291 test_run_ "$2" 292 if [ "$?" = 0 -a "$eval_ret" = 0 ] 293 then 294 test_known_broken_ok_ "$1" 295 else 296 test_known_broken_failure_ "$1" 297 fi 298 fi 299 echo >&3 "" 300} 301 302test_expect_success () { 303 test "$#" = 2 || 304 error "bug in the test script: not 2 parameters to test-expect-success" 305 if ! test_skip "$@" 306 then 307 say >&3 "expecting success:$2" 308 test_run_ "$2" 309 if [ "$?" = 0 -a "$eval_ret" = 0 ] 310 then 311 test_ok_ "$1" 312 else 313 test_failure_ "$@" 314 fi 315 fi 316 echo >&3 "" 317} 318 319test_expect_code () { 320 test "$#" = 3 || 321 error "bug in the test script: not 3 parameters to test-expect-code" 322 if ! test_skip "$@" 323 then 324 say >&3 "expecting exit code$1:$3" 325 test_run_ "$3" 326 if [ "$?" = 0 -a "$eval_ret" = "$1" ] 327 then 328 test_ok_ "$2" 329 else 330 test_failure_ "$@" 331 fi 332 fi 333 echo >&3 "" 334} 335 336# test_external runs external test scripts that provide continuous 337# test output about their progress, and succeeds/fails on 338# zero/non-zero exit code. It outputs the test output on stdout even 339# in non-verbose mode, and announces the external script with "* run 340# <n>: ..." before running it. When providing relative paths, keep in 341# mind that all scripts run in "trash directory". 342# Usage: test_external description command arguments... 343# Example: test_external 'Perl API' perl ../path/to/test.pl 344test_external () { 345 test "$#" -eq 3 || 346 error >&5 "bug in the test script: not 3 parameters to test_external" 347 descr="$1" 348 shift 349 if ! test_skip "$descr" "$@" 350 then 351 # Announce the script to reduce confusion about the 352 # test output that follows. 353 say_color "" " run$(expr "$test_count" + 1):$descr($*)" 354 # Run command; redirect its stderr to &4 as in 355 # test_run_, but keep its stdout on our stdout even in 356 # non-verbose mode. 357 "$@" 2>&4 358 if [ "$?" = 0 ] 359 then 360 test_ok_ "$descr" 361 else 362 test_failure_ "$descr" "$@" 363 fi 364 fi 365} 366 367# Like test_external, but in addition tests that the command generated 368# no output on stderr. 369test_external_without_stderr () { 370 # The temporary file has no (and must have no) security 371 # implications. 372 tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi 373 stderr="$tmp/git-external-stderr.$$.tmp" 374 test_external "$@" 4> "$stderr" 375 [ -f "$stderr" ] || error "Internal error:$stderrdisappeared." 376 descr="no stderr:$1" 377 shift 378 say >&3 "expecting no stderr from previous command" 379 if [ ! -s "$stderr" ]; then 380 rm "$stderr" 381 test_ok_ "$descr" 382 else 383 if [ "$verbose" = t ]; then 384 output=`echo; echo Stderr is:; cat "$stderr"` 385 else 386 output= 387 fi 388 # rm first in case test_failure exits. 389 rm "$stderr" 390 test_failure_ "$descr" "$@" "$output" 391 fi 392} 393 394# This is not among top-level (test_expect_success | test_expect_failure) 395# but is a prefix that can be used in the test script, like: 396# 397# test_expect_success 'complain and die' ' 398# do something && 399# do something else && 400# test_must_fail git checkout ../outerspace 401# ' 402# 403# Writing this as "! git checkout ../outerspace" is wrong, because 404# the failure could be due to a segv. We want a controlled failure. 405 406test_must_fail () { 407"$@" 408test $? -gt0-a $? -le129-o $? -gt192 409} 410 411# test_cmp is a helper function to compare actual and expected output. 412# You can use it like: 413# 414# test_expect_success 'foo works' ' 415# echo expected >expected && 416# foo >actual && 417# test_cmp expected actual 418# ' 419# 420# This could be written as either "cmp" or "diff -u", but: 421# - cmp's output is not nearly as easy to read as diff -u 422# - not all diff versions understand "-u" 423 424test_cmp() { 425$GIT_TEST_CMP"$@" 426} 427 428# Most tests can use the created repository, but some may need to create more. 429# Usage: test_create_repo <directory> 430test_create_repo () { 431test"$#"=1|| 432 error "bug in the test script: not 1 parameter to test-create-repo" 433 owd=`pwd` 434 repo="$1" 435mkdir-p"$repo" 436cd"$repo"|| error "Cannot setup test environment" 437"$GIT_EXEC_PATH/git" init "--template=$GIT_EXEC_PATH/templates/blt/">&3 2>&4|| 438 error "cannot run git init -- have you built things yet?" 439mv .git/hooks .git/hooks-disabled 440cd"$owd" 441} 442 443test_done () { 444trap- EXIT 445 test_results_dir="$TEST_DIRECTORY/test-results" 446mkdir-p"$test_results_dir" 447 test_results_path="$test_results_dir/${0%-*}-$$" 448 449echo"total$test_count">>$test_results_path 450echo"success$test_success">>$test_results_path 451echo"fixed$test_fixed">>$test_results_path 452echo"broken$test_broken">>$test_results_path 453echo"failed$test_failure">>$test_results_path 454echo"">>$test_results_path 455 456iftest"$test_fixed"!=0 457then 458 say_color pass "fixed$test_fixedknown breakage(s)" 459fi 460iftest"$test_broken"!=0 461then 462 say_color error "still have$test_brokenknown breakage(s)" 463 msg="remaining$(($test_count-$test_broken)) test(s)" 464else 465 msg="$test_counttest(s)" 466fi 467case"$test_failure"in 4680) 469# We could: 470# cd .. && rm -fr 'trash directory' 471# but that means we forbid any tests that use their own 472# subdirectory from calling test_done without coming back 473# to where they started from. 474# The Makefile provided will clean this test area so 475# we will leave things as they are. 476 477 say_color pass "passed all$msg" 478 479test -d"$remove_trash"&& 480cd"$(dirname "$remove_trash")"&& 481rm-rf"$(basename "$remove_trash")" 482 483exit0;; 484 485*) 486 say_color error "failed$test_failureamong$msg" 487exit1;; 488 489esac 490} 491 492# Test the binaries we have just built. The tests are kept in 493# t/ subdirectory and are run in 'trash directory' subdirectory. 494TEST_DIRECTORY=$(pwd) 495PATH=$TEST_DIRECTORY/..:$PATH 496GIT_EXEC_PATH=$(pwd)/.. 497GIT_TEMPLATE_DIR=$(pwd)/../templates/blt 498unset GIT_CONFIG 499GIT_CONFIG_NOSYSTEM=1 500GIT_CONFIG_NOGLOBAL=1 501export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOBAL 502 503GITPERLLIB=$(pwd)/../perl/blib/lib:$(pwd)/../perl/blib/arch/auto/Git 504export GITPERLLIB 505test -d ../templates/blt || { 506 error "You haven't built things yet, have you?" 507} 508 509if!test -x ../test-chmtime;then 510echo>&2'You need to build test-chmtime:' 511echo>&2'Run "make test-chmtime" in the source (toplevel) directory' 512exit1 513fi 514 515. ../GIT-BUILD-OPTIONS 516 517# Test repository 518test="trash directory.$(basename "$0" .sh)" 519test!-z"$debug"|| remove_trash="$TEST_DIRECTORY/$test" 520rm-fr"$test"|| { 521trap- EXIT 522echo>&5"FATAL: Cannot prepare test area" 523exit1 524} 525 526test_create_repo "$test" 527# Use -P to resolve symlinks in our working directory so that the cwd 528# in subprocesses like git equals our $PWD (for pathname comparisons). 529cd -P"$test"||exit1 530 531this_test=$(expr "./$0" : '.*/\(t[0-9]*\)-[^/]*$') 532for skp in$GIT_SKIP_TESTS 533do 534 to_skip= 535 for skp in$GIT_SKIP_TESTS 536 do 537 case "$this_test" in 538$skp) 539 to_skip=t 540 esac 541 done 542 case "$to_skip" in 543 t) 544 say_color skip >&3 "skipping test$this_testaltogether" 545 say_color skip "skip all tests in$this_test" 546 test_done 547 esac 548done