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