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