test-lib.sh 26.6 KB
Newer Older
1 2 3 4
#!/bin/sh
#
# Copyright (c) 2005 Junio C Hamano
#
5 6 7 8 9 10 11 12 13 14 15 16
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see http://www.gnu.org/licenses/ .
17

18 19 20 21 22 23
# if --tee was passed, write the output not only to the terminal, but
# additionally to the file test-results/$BASENAME.out, too.
case "$GIT_TEST_TEE_STARTED, $* " in
done,*)
	# do not redirect again
	;;
24
*' --tee '*|*' --va'*)
25 26 27 28 29 30 31 32 33
	mkdir -p test-results
	BASE=test-results/$(basename "$0" .sh)
	(GIT_TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;
	 echo $? > $BASE.exit) | tee $BASE.out
	test "$(cat $BASE.exit)" = 0
	exit
	;;
esac

34 35 36
# Keep the original TERM for say_color
ORIGINAL_TERM=$TERM

37 38
# For repeatability, reset the environment to known value.
LANG=C
39
LC_ALL=C
40
PAGER=cat
41
TZ=UTC
42 43
TERM=dumb
export LANG LC_ALL PAGER TERM TZ
44
EDITOR=:
45
unset VISUAL
46
unset EMAIL
47 48
unset $(perl -e '
	my @env = keys %ENV;
49 50 51 52 53 54 55 56 57 58
	my $ok = join("|", qw(
		TRACE
		DEBUG
		USE_LOOKUP
		TEST
		.*_TEST
		PROVE
		VALGRIND
	));
	my @vars = grep(/^GIT_/ && !/^GIT_($ok)/o, @env);
59 60
	print join("\n", @vars);
')
61 62 63 64
GIT_AUTHOR_EMAIL=author@example.com
GIT_AUTHOR_NAME='A U Thor'
GIT_COMMITTER_EMAIL=committer@example.com
GIT_COMMITTER_NAME='C O Mitter'
65 66
GIT_MERGE_VERBOSITY=5
export GIT_MERGE_VERBOSITY
67 68
export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
69
export EDITOR
70

71 72 73 74
# Protect ourselves from common misconfiguration to export
# CDPATH into the environment
unset CDPATH

B
Bert Wesarg 已提交
75 76
unset GREP_OPTIONS

77
case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in
78 79 80 81 82 83 84 85
	1|2|true)
		echo "* warning: Some tests will not work if GIT_TRACE" \
			"is set as to trace on STDERR ! *"
		echo "* warning: Please set GIT_TRACE to something" \
			"other than 1, 2 or true ! *"
		;;
esac

86 87 88 89 90 91
# Convenience
#
# A regexp to match 5 and 40 hexdigits
_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
_x40="$_x05$_x05$_x05$_x05$_x05$_x05$_x05$_x05"

J
Junio C Hamano 已提交
92 93 94
# Zero SHA-1
_z40=0000000000000000000000000000000000000000

95 96 97 98
# Line feed
LF='
'

99 100 101 102 103 104
# Each test should start with something like this, after copyright notices:
#
# test_description='Description of this test...
# This test checks if command xyzzy does the right thing...
# '
# . ./test-lib.sh
105 106 107 108 109 110 111 112
[ "x$ORIGINAL_TERM" != "xdumb" ] && (
		TERM=$ORIGINAL_TERM &&
		export TERM &&
		[ -t 1 ] &&
		tput bold >/dev/null 2>&1 &&
		tput setaf 1 >/dev/null 2>&1 &&
		tput sgr0 >/dev/null 2>&1
	) &&
113
	color=t
114 115 116 117 118 119

while test "$#" -ne 0
do
	case "$1" in
	-d|--d|--de|--deb|--debu|--debug)
		debug=t; shift ;;
J
Junio C Hamano 已提交
120 121
	-i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate)
		immediate=t; shift ;;
122
	-l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)
J
Junio C Hamano 已提交
123
		GIT_TEST_LONG=t; export GIT_TEST_LONG; shift ;;
124
	-h|--h|--he|--hel|--help)
125
		help=t; shift ;;
126 127
	-v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
		verbose=t; shift ;;
128
	-q|--q|--qu|--qui|--quie|--quiet)
129 130 131
		# Ignore --quiet under a TAP::Harness. Saying how many tests
		# passed without the ok/not ok details is always an error.
		test -z "$HARNESS_ACTIVE" && quiet=t; shift ;;
132 133
	--with-dashes)
		with_dashes=t; shift ;;
134
	--no-color)
135
		color=; shift ;;
136
	--va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)
137
		valgrind=t; verbose=t; shift ;;
138 139
	--tee)
		shift ;; # was handled already
140 141 142
	--root=*)
		root=$(expr "z$1" : 'z[^=]*=\(.*\)')
		shift ;;
143
	*)
144
		echo "error: unknown test option '$1'" >&2; exit 1 ;;
145 146 147
	esac
done

148 149
if test -n "$color"; then
	say_color () {
150 151 152
		(
		TERM=$ORIGINAL_TERM
		export TERM
153 154 155 156 157
		case "$1" in
			error) tput bold; tput setaf 1;; # bold red
			skip)  tput bold; tput setaf 2;; # bold green
			pass)  tput setaf 2;;            # green
			info)  tput setaf 3;;            # brown
158
			*) test -n "$quiet" && return;;
159 160
		esac
		shift
161
		printf "%s" "$*"
162
		tput sgr0
163
		echo
164
		)
165 166 167
	}
else
	say_color() {
168
		test -z "$1" && test -n "$quiet" && return
169
		shift
170
		echo "$*"
171 172 173 174 175
	}
fi

error () {
	say_color error "error: $*"
176
	GIT_EXIT_OK=t
177 178 179 180 181 182 183
	exit 1
}

say () {
	say_color info "$*"
}

184 185 186 187 188 189 190 191 192
test "${test_description}" != "" ||
error "Test script did not set test_description."

if test "$help" = "t"
then
	echo "$test_description"
	exit 0
fi

193
exec 5>&1
194 195 196 197 198 199 200 201 202
if test "$verbose" = "t"
then
	exec 4>&2 3>&1
else
	exec 4>/dev/null 3>/dev/null
fi

test_failure=0
test_count=0
J
Junio C Hamano 已提交
203 204
test_fixed=0
test_broken=0
205
test_success=0
206

207 208
test_external_has_tap=0

209
die () {
210 211 212 213 214 215 216 217
	code=$?
	if test -n "$GIT_EXIT_OK"
	then
		exit $code
	else
		echo >&5 "FATAL: Unexpected exit with code $code"
		exit 1
	fi
218 219
}

220
GIT_EXIT_OK=
221
trap 'die' EXIT
222

223 224 225 226 227 228 229 230
# The semantics of the editor variables are that of invoking
# sh -c "$EDITOR \"$@\"" files ...
#
# If our trash directory contains shell metacharacters, they will be
# interpreted if we just set $EDITOR directly, so do a little dance with
# environment variables to work around this.
#
# In particular, quoting isn't enough, as the path may contain the same quote
231
# that we're using.
232 233 234
test_set_editor () {
	FAKE_EDITOR="$1"
	export FAKE_EDITOR
235 236
	EDITOR='"$FAKE_EDITOR"'
	export EDITOR
237 238
}

239
test_decode_color () {
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
	awk '
		function name(n) {
			if (n == 0) return "RESET";
			if (n == 1) return "BOLD";
			if (n == 30) return "BLACK";
			if (n == 31) return "RED";
			if (n == 32) return "GREEN";
			if (n == 33) return "YELLOW";
			if (n == 34) return "BLUE";
			if (n == 35) return "MAGENTA";
			if (n == 36) return "CYAN";
			if (n == 37) return "WHITE";
			if (n == 40) return "BLACK";
			if (n == 41) return "BRED";
			if (n == 42) return "BGREEN";
			if (n == 43) return "BYELLOW";
			if (n == 44) return "BBLUE";
			if (n == 45) return "BMAGENTA";
			if (n == 46) return "BCYAN";
			if (n == 47) return "BWHITE";
		}
		{
262
			while (match($0, /\033\[[0-9;]*m/) != 0) {
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
				printf "%s<", substr($0, 1, RSTART-1);
				codes = substr($0, RSTART+2, RLENGTH-3);
				if (length(codes) == 0)
					printf "%s", name(0)
				else {
					n = split(codes, ary, ";");
					sep = "";
					for (i = 1; i <= n; i++) {
						printf "%s%s", sep, name(ary[i]);
						sep = ";"
					}
				}
				printf ">";
				$0 = substr($0, RSTART + RLENGTH, length($0) - RSTART - RLENGTH + 1);
			}
			print
		}
	'
281 282
}

283 284 285 286
nul_to_q () {
	perl -pe 'y/\000/Q/'
}

287 288 289 290 291 292 293 294
q_to_nul () {
	perl -pe 'y/Q/\000/'
}

q_to_cr () {
	tr Q '\015'
}

J
Jonathan Nieder 已提交
295 296 297 298
q_to_tab () {
	tr Q '\011'
}

299 300 301 302 303 304 305 306
append_cr () {
	sed -e 's/$/Q/' | tr Q '\015'
}

remove_cr () {
	tr '\015' Q | sed -e 's/Q$//'
}

307 308 309 310 311 312 313 314 315 316 317
# In some bourne shell implementations, the "unset" builtin returns
# nonzero status when a variable to be unset was not set in the first
# place.
#
# Use sane_unset when that should not be considered an error.

sane_unset () {
	unset "$@"
	return 0
}

318 319 320
test_tick () {
	if test -z "${test_tick+set}"
	then
J
Junio C Hamano 已提交
321
		test_tick=1112911993
322 323 324
	else
		test_tick=$(($test_tick + 60))
	fi
J
Junio C Hamano 已提交
325 326
	GIT_COMMITTER_DATE="$test_tick -0700"
	GIT_AUTHOR_DATE="$test_tick -0700"
327 328
	export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
}
329

330 331 332 333 334 335 336 337
# Call test_commit with the arguments "<message> [<file> [<contents>]]"
#
# This will commit a file with the given contents and the given commit
# message.  It will also add a tag with <message> as name.
#
# Both <file> and <contents> default to <message>.

test_commit () {
338
	file=${2:-"$1.t"}
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
	echo "${3-$1}" > "$file" &&
	git add "$file" &&
	test_tick &&
	git commit -m "$1" &&
	git tag "$1"
}

# Call test_merge with the arguments "<message> <commit>", where <commit>
# can be a tag pointing to the commit-to-merge.

test_merge () {
	test_tick &&
	git merge -m "$1" "$2" &&
	git tag "$1"
}

355 356 357 358 359 360 361 362 363
# This function helps systems where core.filemode=false is set.
# Use it instead of plain 'chmod +x' to set or unset the executable bit
# of a file in the working directory and add it to the index.

test_chmod () {
	chmod "$@" &&
	git update-index --add "--chmod=$@"
}

364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
# Unset a configuration variable, but don't fail if it doesn't exist.
test_unconfig () {
	git config --unset-all "$@"
	config_status=$?
	case "$config_status" in
	5) # ok, nothing to unset
		config_status=0
		;;
	esac
	return $config_status
}

# Set git config, automatically unsetting it after the test is over.
test_config () {
	test_when_finished "test_unconfig '$1'" &&
	git config "$@"
}

382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
# Use test_set_prereq to tell that a particular prerequisite is available.
# The prerequisite can later be checked for in two ways:
#
# - Explicitly using test_have_prereq.
#
# - Implicitly by specifying the prerequisite tag in the calls to
#   test_expect_{success,failure,code}.
#
# The single parameter is the prerequisite tag (a simple word, in all
# capital letters by convention).

test_set_prereq () {
	satisfied="$satisfied$1 "
}
satisfied=" "

test_have_prereq () {
399 400 401 402 403
	# prerequisites can be concatenated with ','
	save_IFS=$IFS
	IFS=,
	set -- $*
	IFS=$save_IFS
404 405 406 407 408

	total_prereq=0
	ok_prereq=0
	missing_prereq=

409 410
	for prerequisite
	do
411
		total_prereq=$(($total_prereq + 1))
412 413
		case $satisfied in
		*" $prerequisite "*)
414 415
			ok_prereq=$(($ok_prereq + 1))
			;;
416
		*)
417 418 419 420 421 422 423
			# Keep a list of missing prerequisites
			if test -z "$missing_prereq"
			then
				missing_prereq=$prerequisite
			else
				missing_prereq="$prerequisite,$missing_prereq"
			fi
424 425
		esac
	done
426 427

	test $total_prereq = $ok_prereq
428 429
}

430 431 432 433 434 435 436 437 438
test_declared_prereq () {
	case ",$test_prereq," in
	*,$1,*)
		return 0
		;;
	esac
	return 1
}

J
Junio C Hamano 已提交
439 440 441 442
# You are not expected to call test_ok_ and test_failure_ directly, use
# the text_expect_* functions instead.

test_ok_ () {
443
	test_success=$(($test_success + 1))
444
	say_color "" "ok $test_count - $@"
445 446
}

J
Junio C Hamano 已提交
447
test_failure_ () {
448
	test_failure=$(($test_failure + 1))
449
	say_color error "not ok - $test_count $1"
450
	shift
451
	echo "$@" | sed -e 's/^/#	/'
452
	test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
J
Junio C Hamano 已提交
453 454
}

J
Junio C Hamano 已提交
455 456
test_known_broken_ok_ () {
	test_fixed=$(($test_fixed+1))
457
	say_color "" "ok $test_count - $@ # TODO known breakage"
J
Junio C Hamano 已提交
458 459 460 461
}

test_known_broken_failure_ () {
	test_broken=$(($test_broken+1))
462
	say_color skip "not ok $test_count - $@ # TODO known breakage"
J
Junio C Hamano 已提交
463
}
J
Junio C Hamano 已提交
464 465

test_debug () {
466
	test "$debug" = "" || eval "$1"
467 468
}

469 470 471 472 473 474
test_eval_ () {
	# This is a separate function because some tests use
	# "return" to end a test_expect_success block early.
	eval >&3 2>&4 "$*"
}

475
test_run_ () {
476
	test_cleanup=:
477
	expecting_failure=$2
478
	test_eval_ "$1"
479
	eval_ret=$?
480 481 482

	if test -z "$immediate" || test $eval_ret = 0 || test -n "$expecting_failure"
	then
483
		test_eval_ "$test_cleanup"
484
	fi
485 486 487
	if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then
		echo ""
	fi
488
	return "$eval_ret"
489 490
}

491
test_skip () {
492
	test_count=$(($test_count+1))
493 494 495
	to_skip=
	for skp in $GIT_SKIP_TESTS
	do
496
		case $this_test.$test_count in
497 498
		$skp)
			to_skip=t
499
			break
500 501
		esac
	done
502 503
	if test -z "$to_skip" && test -n "$test_prereq" &&
	   ! test_have_prereq "$test_prereq"
504 505 506
	then
		to_skip=t
	fi
507 508
	case "$to_skip" in
	t)
509
		of_prereq=
510
		if test "$missing_prereq" != "$test_prereq"
511
		then
512
			of_prereq=" of $test_prereq"
513 514
		fi

515
		say_color skip >&3 "skipping test: $@"
516
		say_color skip "ok $test_count # skip $1 (missing $missing_prereq${of_prereq})"
517 518 519 520 521 522 523 524
		: true
		;;
	*)
		false
		;;
	esac
}

525
test_expect_failure () {
526
	test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
527
	test "$#" = 2 ||
528
	error "bug in the test script: not 2 or 3 parameters to test-expect-failure"
529
	export test_prereq
530
	if ! test_skip "$@"
531
	then
J
Junio C Hamano 已提交
532
		say >&3 "checking known breakage: $2"
533
		if test_run_ "$2" expecting_failure
534
		then
J
Junio C Hamano 已提交
535
			test_known_broken_ok_ "$1"
536
		else
537
			test_known_broken_failure_ "$1"
538
		fi
539
	fi
540
	echo >&3 ""
541 542 543
}

test_expect_success () {
544
	test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
545
	test "$#" = 2 ||
546
	error "bug in the test script: not 2 or 3 parameters to test-expect-success"
547
	export test_prereq
548
	if ! test_skip "$@"
549
	then
550
		say >&3 "expecting success: $2"
551
		if test_run_ "$2"
552 553 554 555 556
		then
			test_ok_ "$1"
		else
			test_failure_ "$@"
		fi
557
	fi
558
	echo >&3 ""
559 560
}

561 562 563
# test_external runs external test scripts that provide continuous
# test output about their progress, and succeeds/fails on
# zero/non-zero exit code.  It outputs the test output on stdout even
564
# in non-verbose mode, and announces the external script with "# run
565 566 567 568 569
# <n>: ..." before running it.  When providing relative paths, keep in
# mind that all scripts run in "trash directory".
# Usage: test_external description command arguments...
# Example: test_external 'Perl API' perl ../path/to/test.pl
test_external () {
570
	test "$#" = 4 && { test_prereq=$1; shift; } || test_prereq=
571 572
	test "$#" = 3 ||
	error >&5 "bug in the test script: not 3 or 4 parameters to test_external"
573 574
	descr="$1"
	shift
575
	export test_prereq
576 577 578 579
	if ! test_skip "$descr" "$@"
	then
		# Announce the script to reduce confusion about the
		# test output that follows.
580
		say_color "" "# run $test_count: $descr ($*)"
581 582 583
		# Export TEST_DIRECTORY, TRASH_DIRECTORY and GIT_TEST_LONG
		# to be able to use them in script
		export TEST_DIRECTORY TRASH_DIRECTORY GIT_TEST_LONG
584 585 586 587 588 589
		# Run command; redirect its stderr to &4 as in
		# test_run_, but keep its stdout on our stdout even in
		# non-verbose mode.
		"$@" 2>&4
		if [ "$?" = 0 ]
		then
590 591 592 593 594 595
			if test $test_external_has_tap -eq 0; then
				test_ok_ "$descr"
			else
				say_color "" "# test_external test $descr was ok"
				test_success=$(($test_success + 1))
			fi
596
		else
597 598 599 600 601 602
			if test $test_external_has_tap -eq 0; then
				test_failure_ "$descr" "$@"
			else
				say_color error "# test_external test $descr failed: $@"
				test_failure=$(($test_failure + 1))
			fi
603 604 605 606 607 608 609 610 611
		fi
	fi
}

# Like test_external, but in addition tests that the command generated
# no output on stderr.
test_external_without_stderr () {
	# The temporary file has no (and must have no) security
	# implications.
612
	tmp=${TMPDIR:-/tmp}
613 614 615 616 617
	stderr="$tmp/git-external-stderr.$$.tmp"
	test_external "$@" 4> "$stderr"
	[ -f "$stderr" ] || error "Internal error: $stderr disappeared."
	descr="no stderr: $1"
	shift
618
	say >&3 "# expecting no stderr from previous command"
619 620
	if [ ! -s "$stderr" ]; then
		rm "$stderr"
621 622 623 624 625 626 627

		if test $test_external_has_tap -eq 0; then
			test_ok_ "$descr"
		else
			say_color "" "# test_external_without_stderr test $descr was ok"
			test_success=$(($test_success + 1))
		fi
628 629
	else
		if [ "$verbose" = t ]; then
630
			output=`echo; echo "# Stderr is:"; cat "$stderr"`
631 632 633 634 635
		else
			output=
		fi
		# rm first in case test_failure exits.
		rm "$stderr"
636 637 638 639 640 641
		if test $test_external_has_tap -eq 0; then
			test_failure_ "$descr" "$@" "$output"
		else
			say_color error "# test_external_without_stderr test $descr failed: $@: $output"
			test_failure=$(($test_failure + 1))
		fi
642 643 644
	fi
}

645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675
# debugging-friendly alternatives to "test [-f|-d|-e]"
# The commands test the existence or non-existence of $1. $2 can be
# given to provide a more precise diagnosis.
test_path_is_file () {
	if ! [ -f "$1" ]
	then
		echo "File $1 doesn't exist. $*"
		false
	fi
}

test_path_is_dir () {
	if ! [ -d "$1" ]
	then
		echo "Directory $1 doesn't exist. $*"
		false
	fi
}

test_path_is_missing () {
	if [ -e "$1" ]
	then
		echo "Path exists:"
		ls -ld "$1"
		if [ $# -ge 1 ]; then
			echo "$*"
		fi
		false
	fi
}

676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697
# test_line_count checks that a file has the number of lines it
# ought to. For example:
#
#	test_expect_success 'produce exactly one line of output' '
#		do something >output &&
#		test_line_count = 1 output
#	'
#
# is like "test $(wc -l <output) = 1" except that it passes the
# output through when the number of lines is wrong.

test_line_count () {
	if test $# != 3
	then
		error "bug in the test script: not 3 parameters to test_line_count"
	elif ! test $(wc -l <"$3") "$1" "$2"
	then
		echo "test_line_count: line count for $3 !$1 $2"
		cat "$3"
		return 1
	fi
}
698

J
Junio C Hamano 已提交
699 700 701 702 703 704 705 706 707 708 709 710 711 712
# This is not among top-level (test_expect_success | test_expect_failure)
# but is a prefix that can be used in the test script, like:
#
#	test_expect_success 'complain and die' '
#           do something &&
#           do something else &&
#	    test_must_fail git checkout ../outerspace
#	'
#
# Writing this as "! git checkout ../outerspace" is wrong, because
# the failure could be due to a segv.  We want a controlled failure.

test_must_fail () {
	"$@"
713 714 715 716 717 718 719
	exit_code=$?
	if test $exit_code = 0; then
		echo >&2 "test_must_fail: command succeeded: $*"
		return 1
	elif test $exit_code -gt 129 -a $exit_code -le 192; then
		echo >&2 "test_must_fail: died by signal: $*"
		return 1
720 721 722
	elif test $exit_code = 127; then
		echo >&2 "test_must_fail: command not found: $*"
		return 1
723 724
	fi
	return 0
J
Junio C Hamano 已提交
725 726
}

727 728 729 730 731 732 733 734 735 736 737 738 739
# Similar to test_must_fail, but tolerates success, too.  This is
# meant to be used in contexts like:
#
#	test_expect_success 'some command works without configuration' '
#		test_might_fail git config --unset all.configuration &&
#		do something
#	'
#
# Writing "git config --unset all.configuration || :" would be wrong,
# because we want to notice if it fails due to segv.

test_might_fail () {
	"$@"
740 741 742 743
	exit_code=$?
	if test $exit_code -gt 129 -a $exit_code -le 192; then
		echo >&2 "test_might_fail: died by signal: $*"
		return 1
744 745 746
	elif test $exit_code = 127; then
		echo >&2 "test_might_fail: command not found: $*"
		return 1
747 748
	fi
	return 0
749 750
}

751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
# Similar to test_must_fail and test_might_fail, but check that a
# given command exited with a given exit code. Meant to be used as:
#
#	test_expect_success 'Merge with d/f conflicts' '
#		test_expect_code 1 git merge "merge msg" B master
#	'

test_expect_code () {
	want_code=$1
	shift
	"$@"
	exit_code=$?
	if test $exit_code = $want_code
	then
		return 0
	fi
767 768 769

	echo >&2 "test_expect_code: command exited with $exit_code, we wanted $want_code $*"
	return 1
770 771
}

772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788
# test_cmp is a helper function to compare actual and expected output.
# You can use it like:
#
#	test_expect_success 'foo works' '
#		echo expected >expected &&
#		foo >actual &&
#		test_cmp expected actual
#	'
#
# This could be written as either "cmp" or "diff -u", but:
# - cmp's output is not nearly as easy to read as diff -u
# - not all diff versions understand "-u"

test_cmp() {
	$GIT_TEST_CMP "$@"
}

789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807
# This function can be used to schedule some commands to be run
# unconditionally at the end of the test to restore sanity:
#
#	test_expect_success 'test core.capslock' '
#		git config core.capslock true &&
#		test_when_finished "git config --unset core.capslock" &&
#		hello world
#	'
#
# That would be roughly equivalent to
#
#	test_expect_success 'test core.capslock' '
#		git config core.capslock true &&
#		hello world
#		git config --unset core.capslock
#	'
#
# except that the greeting and config --unset must both succeed for
# the test to pass.
808 809 810
#
# Note that under --immediate mode, no clean-up is done to help diagnose
# what went wrong.
811 812

test_when_finished () {
813 814
	test_cleanup="{ $*
		} && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
815 816
}

817
# Most tests can use the created repository, but some may need to create more.
818 819 820 821 822
# Usage: test_create_repo <directory>
test_create_repo () {
	test "$#" = 1 ||
	error "bug in the test script: not 1 parameter to test-create-repo"
	repo="$1"
823
	mkdir -p "$repo"
824 825 826 827 828 829
	(
		cd "$repo" || error "Cannot setup test environment"
		"$GIT_EXEC_PATH/git-init" "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
		error "cannot run git init -- have you built things yet?"
		mv .git/hooks .git/hooks-disabled
	) || exit
830
}
J
Junio C Hamano 已提交
831

832
test_done () {
833
	GIT_EXIT_OK=t
834

835 836 837 838 839
	if test -z "$HARNESS_ACTIVE"; then
		test_results_dir="$TEST_DIRECTORY/test-results"
		mkdir -p "$test_results_dir"
		test_results_path="$test_results_dir/${0%.sh}-$$.counts"

840 841 842 843 844 845 846 847
		cat >>"$test_results_path" <<-EOF
		total $test_count
		success $test_success
		fixed $test_fixed
		broken $test_broken
		failed $test_failure

		EOF
848
	fi
J
Junio C Hamano 已提交
849 850 851

	if test "$test_fixed" != 0
	then
852
		say_color pass "# fixed $test_fixed known breakage(s)"
J
Junio C Hamano 已提交
853 854 855
	fi
	if test "$test_broken" != 0
	then
856
		say_color error "# still have $test_broken known breakage(s)"
857 858 859
		msg="remaining $(($test_count-$test_broken)) test(s)"
	else
		msg="$test_count test(s)"
J
Junio C Hamano 已提交
860
	fi
861
	case "$test_failure" in
862
	0)
863 864 865
		# Maybe print SKIP message
		[ -z "$skip_all" ] || skip_all=" # SKIP $skip_all"

866 867 868 869
		if test $test_external_has_tap -eq 0; then
			say_color pass "# passed all $msg"
			say "1..$test_count$skip_all"
		fi
J
Johannes Schindelin 已提交
870 871 872 873 874

		test -d "$remove_trash" &&
		cd "$(dirname "$remove_trash")" &&
		rm -rf "$(basename "$remove_trash")"

875 876 877
		exit 0 ;;

	*)
878 879 880 881
		if test $test_external_has_tap -eq 0; then
			say_color error "# failed $test_failure among $msg"
			say "1..$test_count"
		fi
882

883 884 885 886 887 888
		exit 1 ;;

	esac
}

# Test the binaries we have just built.  The tests are kept in
889
# t/ subdirectory and are run in 'trash directory' subdirectory.
890 891 892 893 894 895 896
if test -z "$TEST_DIRECTORY"
then
	# We allow tests to override this, in case they want to run tests
	# outside of t/, e.g. for running tests on the test library
	# itself.
	TEST_DIRECTORY=$(pwd)
fi
897 898
GIT_BUILD_DIR="$TEST_DIRECTORY"/..

899
if test -n "$valgrind"
900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920
then
	make_symlink () {
		test -h "$2" &&
		test "$1" = "$(readlink "$2")" || {
			# be super paranoid
			if mkdir "$2".lock
			then
				rm -f "$2" &&
				ln -s "$1" "$2" &&
				rm -r "$2".lock
			else
				while test -d "$2".lock
				do
					say "Waiting for lock on $2."
					sleep 1
				done
			fi
		}
	}

	make_valgrind_symlink () {
921 922 923 924 925 926 927
		# handle only executables, unless they are shell libraries that
		# need to be in the exec-path.  We will just use "#!" as a
		# guess for a shell-script, since we have no idea what the user
		# may have configured as the shell path.
		test -x "$1" ||
		test "#!" = "$(head -c 2 <"$1")" ||
		return;
928 929

		base=$(basename "$1")
930
		symlink_target=$GIT_BUILD_DIR/$base
931 932 933 934 935 936 937
		# do not override scripts
		if test -x "$symlink_target" &&
		    test ! -d "$symlink_target" &&
		    test "#!" != "$(head -c 2 < "$symlink_target")"
		then
			symlink_target=../valgrind.sh
		fi
938 939 940 941
		case "$base" in
		*.sh|*.perl)
			symlink_target=../unprocessed-script
		esac
942 943 944 945 946 947 948
		# create the link, or replace it if it is out of date
		make_symlink "$symlink_target" "$GIT_VALGRIND/bin/$base" || exit
	}

	# override all git executables in TEST_DIRECTORY/..
	GIT_VALGRIND=$TEST_DIRECTORY/valgrind
	mkdir -p "$GIT_VALGRIND"/bin
949
	for file in $GIT_BUILD_DIR/git* $GIT_BUILD_DIR/test-*
950 951 952
	do
		make_valgrind_symlink $file
	done
953 954
	# special-case the mergetools loadables
	make_symlink "$GIT_BUILD_DIR"/mergetools "$GIT_VALGRIND/bin/mergetools"
955 956 957 958 959 960 961 962 963 964 965
	OLDIFS=$IFS
	IFS=:
	for path in $PATH
	do
		ls "$path"/git-* 2> /dev/null |
		while read file
		do
			make_valgrind_symlink "$file"
		done
	done
	IFS=$OLDIFS
966 967 968
	PATH=$GIT_VALGRIND/bin:$PATH
	GIT_EXEC_PATH=$GIT_VALGRIND/bin
	export GIT_VALGRIND
969 970 971
elif test -n "$GIT_TEST_INSTALLED" ; then
	GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path)  ||
	error "Cannot run git from $GIT_TEST_INSTALLED."
972
	PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR:$PATH
973 974
	GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH}
else # normal case, use ../bin-wrappers only unless $with_dashes:
975
	git_bin_dir="$GIT_BUILD_DIR/bin-wrappers"
976 977 978 979 980 981 982
	if ! test -x "$git_bin_dir/git" ; then
		if test -z "$with_dashes" ; then
			say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH"
		fi
		with_dashes=t
	fi
	PATH="$git_bin_dir:$PATH"
983
	GIT_EXEC_PATH=$GIT_BUILD_DIR
984
	if test -n "$with_dashes" ; then
985
		PATH="$GIT_BUILD_DIR:$PATH"
986
	fi
987
fi
988
GIT_TEMPLATE_DIR="$GIT_BUILD_DIR"/templates/blt
J
Jeff King 已提交
989 990
unset GIT_CONFIG
GIT_CONFIG_NOSYSTEM=1
991
GIT_ATTR_NOSYSTEM=1
992
export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_ATTR_NOSYSTEM
993

994
. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
J
Jeff King 已提交
995

996 997 998 999 1000 1001 1002 1003 1004 1005
if test -z "$GIT_TEST_CMP"
then
	if test -n "$GIT_TEST_CMP_USE_COPIED_CONTEXT"
	then
		GIT_TEST_CMP="$DIFF -c"
	else
		GIT_TEST_CMP="$DIFF -u"
	fi
fi

1006
GITPERLLIB="$GIT_BUILD_DIR"/perl/blib/lib:"$GIT_BUILD_DIR"/perl/blib/arch/auto/Git
1007
export GITPERLLIB
1008
test -d "$GIT_BUILD_DIR"/templates/blt || {
1009 1010
	error "You haven't built things yet, have you?"
}
1011

J
Jeff King 已提交
1012
if test -z "$GIT_TEST_INSTALLED" && test -z "$NO_PYTHON"
1013
then
1014
	GITPYTHONLIB="$GIT_BUILD_DIR/git_remote_helpers/build/lib"
1015
	export GITPYTHONLIB
1016
	test -d "$GIT_BUILD_DIR"/git_remote_helpers/build || {
1017 1018 1019 1020
		error "You haven't built git_remote_helpers yet, have you?"
	}
fi

1021
if ! test -x "$GIT_BUILD_DIR"/test-chmtime; then
E
Eric Wong 已提交
1022 1023 1024 1025 1026
	echo >&2 'You need to build test-chmtime:'
	echo >&2 'Run "make test-chmtime" in the source (toplevel) directory'
	exit 1
fi

1027
# Test repository
J
Johannes Schindelin 已提交
1028
test="trash directory.$(basename "$0" .sh)"
1029 1030 1031 1032 1033
test -n "$root" && test="$root/$test"
case "$test" in
/*) TRASH_DIRECTORY="$test" ;;
 *) TRASH_DIRECTORY="$TEST_DIRECTORY/$test" ;;
esac
1034
test ! -z "$debug" || remove_trash=$TRASH_DIRECTORY
1035
rm -fr "$test" || {
1036
	GIT_EXIT_OK=t
1037 1038 1039 1040
	echo >&5 "FATAL: Cannot prepare test area"
	exit 1
}

1041 1042 1043
HOME="$TRASH_DIRECTORY"
export HOME

1044
test_create_repo "$test"
1045 1046 1047
# Use -P to resolve symlinks in our working directory so that the cwd
# in subprocesses like git equals our $PWD (for pathname comparisons).
cd -P "$test" || exit 1
1048

1049 1050
this_test=${0##*/}
this_test=${this_test%%-*}
1051 1052
for skp in $GIT_SKIP_TESTS
do
1053 1054
	case "$this_test" in
	$skp)
1055
		say_color skip >&3 "skipping test $this_test altogether"
1056
		skip_all="skip all tests in $this_test"
1057 1058 1059
		test_done
	esac
done
1060

1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075
# Provide an implementation of the 'yes' utility
yes () {
	if test $# = 0
	then
		y=y
	else
		y="$*"
	fi

	while echo "$y"
	do
		:
	done
}

1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
# Fix some commands on Windows
case $(uname -s) in
*MINGW*)
	# Windows has its own (incompatible) sort and find
	sort () {
		/usr/bin/sort "$@"
	}
	find () {
		/usr/bin/find "$@"
	}
1086 1087 1088
	sum () {
		md5sum "$@"
	}
1089 1090 1091 1092
	# git sees Windows-style pwd
	pwd () {
		builtin pwd -W
	}
1093
	# no POSIX permissions
1094
	# backslashes in pathspec are converted to '/'
1095
	# exec does not inherit the PID
1096
	test_set_prereq MINGW
1097 1098 1099 1100 1101 1102 1103
	test_set_prereq SED_STRIPS_CR
	;;
*CYGWIN*)
	test_set_prereq POSIXPERM
	test_set_prereq EXECKEEPSPID
	test_set_prereq NOT_MINGW
	test_set_prereq SED_STRIPS_CR
1104 1105 1106
	;;
*)
	test_set_prereq POSIXPERM
1107
	test_set_prereq BSLASHPSPEC
1108
	test_set_prereq EXECKEEPSPID
P
Pat Thoyts 已提交
1109
	test_set_prereq NOT_MINGW
1110 1111
	;;
esac
1112

1113
test -z "$NO_PERL" && test_set_prereq PERL
1114
test -z "$NO_PYTHON" && test_set_prereq PYTHON
M
Michał Kiedrowicz 已提交
1115
test -n "$USE_LIBPCRE" && test_set_prereq LIBPCRE
1116

1117
# Can we rely on git's output in the C locale?
1118 1119 1120 1121 1122 1123 1124
if test -n "$GETTEXT_POISON"
then
	GIT_GETTEXT_POISON=YesPlease
	export GIT_GETTEXT_POISON
else
	test_set_prereq C_LOCALE_OUTPUT
fi
1125

1126 1127 1128 1129 1130 1131 1132 1133
# Use this instead of test_cmp to compare files that contain expected and
# actual output from git commands that can be translated.  When running
# under GETTEXT_POISON this pretends that the command produced expected
# results.
test_i18ncmp () {
	test -n "$GETTEXT_POISON" || test_cmp "$@"
}

1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
# Use this instead of "grep expected-string actual" to see if the
# output from a git command that can be translated either contains an
# expected string, or does not contain an unwanted one.  When running
# under GETTEXT_POISON this pretends that the command produced expected
# results.
test_i18ngrep () {
	if test -n "$GETTEXT_POISON"
	then
	    : # pretend success
	elif test "x!" = "x$1"
	then
		shift
		! grep "$@"
	else
		grep "$@"
	fi
}

1152 1153 1154
# test whether the filesystem supports symbolic links
ln -s x y 2>/dev/null && test -h y 2>/dev/null && test_set_prereq SYMLINKS
rm -f y
1155 1156 1157 1158

# When the tests are run as root, permission tests will report that
# things are writable when they shouldn't be.
test -w / || test_set_prereq SANITY