summaryrefslogtreecommitdiff
path: root/t/test-lib.sh
diff options
context:
space:
mode:
Diffstat (limited to 't/test-lib.sh')
-rw-r--r--t/test-lib.sh212
1 files changed, 160 insertions, 52 deletions
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 562c57e685..0bb1105ec3 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -57,6 +57,13 @@ fi
. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
export PERL_PATH SHELL_PATH
+# Disallow the use of abbreviated options in the test suite by default
+if test -z "${GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS}"
+then
+ GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=true
+ export GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS
+fi
+
################################################################
# It appears that people try to run tests without building...
"${GIT_TEST_INSTALLED:-$GIT_BUILD_DIR}/git$X" >/dev/null
@@ -71,20 +78,23 @@ then
exit 1
fi
-# Parse options while taking care to leave $@ intact, so we will still
-# have all the original command line options when executing the test
-# script again for '--tee' and '--verbose-log' below.
store_arg_to=
-prev_opt=
-for opt
-do
- if test -n "$store_arg_to"
+opt_required_arg=
+# $1: option string
+# $2: name of the var where the arg will be stored
+mark_option_requires_arg () {
+ if test -n "$opt_required_arg"
then
- eval $store_arg_to=\$opt
- store_arg_to=
- prev_opt=
- continue
+ echo "error: options that require args cannot be bundled" \
+ "together: '$opt_required_arg' and '$1'" >&2
+ exit 1
fi
+ opt_required_arg=$1
+ store_arg_to=$2
+}
+
+parse_option () {
+ local opt="$1"
case "$opt" in
-d|--d|--de|--deb|--debu|--debug)
@@ -94,7 +104,7 @@ do
-l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)
GIT_TEST_LONG=t; export GIT_TEST_LONG ;;
-r)
- store_arg_to=run_list
+ mark_option_requires_arg "$opt" run_list
;;
--run=*)
run_list=${opt#--*=} ;;
@@ -178,12 +188,42 @@ do
*)
echo "error: unknown test option '$opt'" >&2; exit 1 ;;
esac
+}
+
+# Parse options while taking care to leave $@ intact, so we will still
+# have all the original command line options when executing the test
+# script again for '--tee' and '--verbose-log' later.
+for opt
+do
+ if test -n "$store_arg_to"
+ then
+ eval $store_arg_to=\$opt
+ store_arg_to=
+ opt_required_arg=
+ continue
+ fi
- prev_opt=$opt
+ case "$opt" in
+ --*|-?)
+ parse_option "$opt" ;;
+ -?*)
+ # bundled short options must be fed separately to parse_option
+ opt=${opt#-}
+ while test -n "$opt"
+ do
+ extra=${opt#?}
+ this=${opt%$extra}
+ opt=$extra
+ parse_option "-$this"
+ done
+ ;;
+ *)
+ echo "error: unknown test option '$opt'" >&2; exit 1 ;;
+ esac
done
if test -n "$store_arg_to"
then
- echo "error: $prev_opt requires an argument" >&2
+ echo "error: $opt_required_arg requires an argument" >&2
exit 1
fi
@@ -205,6 +245,8 @@ fi
TEST_STRESS_JOB_SFX="${GIT_TEST_STRESS_JOB_NR:+.stress-$GIT_TEST_STRESS_JOB_NR}"
TEST_NAME="$(basename "$0" .sh)"
+TEST_NUMBER="${TEST_NAME%%-*}"
+TEST_NUMBER="${TEST_NUMBER#t}"
TEST_RESULTS_DIR="$TEST_OUTPUT_DIRECTORY/test-results"
TEST_RESULTS_BASE="$TEST_RESULTS_DIR/$TEST_NAME$TEST_STRESS_JOB_SFX"
TRASH_DIRECTORY="trash directory.$TEST_NAME$TEST_STRESS_JOB_SFX"
@@ -395,9 +437,13 @@ unset VISUAL EMAIL LANGUAGE COLUMNS $("$PERL_PATH" -e '
unset XDG_CACHE_HOME
unset XDG_CONFIG_HOME
unset GITPERLLIB
-GIT_AUTHOR_EMAIL=author@example.com
+TEST_AUTHOR_LOCALNAME=author
+TEST_AUTHOR_DOMAIN=example.com
+GIT_AUTHOR_EMAIL=${TEST_AUTHOR_LOCALNAME}@${TEST_AUTHOR_DOMAIN}
GIT_AUTHOR_NAME='A U Thor'
-GIT_COMMITTER_EMAIL=committer@example.com
+TEST_COMMITTER_LOCALNAME=committer
+TEST_COMMITTER_DOMAIN=example.com
+GIT_COMMITTER_EMAIL=${TEST_COMMITTER_LOCALNAME}@${TEST_COMMITTER_DOMAIN}
GIT_COMMITTER_NAME='C O Mitter'
GIT_MERGE_VERBOSITY=5
GIT_MERGE_AUTOEDIT=no
@@ -481,25 +527,13 @@ case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in
;;
esac
-# Convenience
-#
-# A regexp to match 5, 35 and 40 hexdigits
-_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
-_x35="$_x05$_x05$_x05$_x05$_x05$_x05$_x05"
-_x40="$_x35$_x05"
-
-# Zero SHA-1
-_z40=0000000000000000000000000000000000000000
-
-OID_REGEX="$_x40"
-ZERO_OID=$_z40
-EMPTY_TREE=4b825dc642cb6eb9a060e54bf8d69288fbee4904
-EMPTY_BLOB=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
-
# Line feed
LF='
'
+# Single quote
+SQ=\'
+
# UTF-8 ZERO WIDTH NON-JOINER, which HFS+ ignores
# when case-folding filenames
u200c=$(printf '\342\200\214')
@@ -560,6 +594,7 @@ export TERM
error () {
say_color error "error: $*"
+ finalize_junit_xml
GIT_EXIT_OK=t
exit 1
}
@@ -627,6 +662,10 @@ test_external_has_tap=0
die () {
code=$?
+ # This is responsible for running the atexit commands even when a
+ # test script run with '--immediate' fails, or when the user hits
+ # ctrl-C, i.e. when 'test_done' is not invoked at all.
+ test_atexit_handler || code=$?
if test -n "$GIT_EXIT_OK"
then
exit $code
@@ -638,7 +677,10 @@ die () {
GIT_EXIT_OK=
trap 'die' EXIT
-trap 'exit $?' INT TERM HUP
+# Disable '-x' tracing, because with some shells, notably dash, it
+# prevents running the cleanup commands when a test script run with
+# '--verbose-log -x' is interrupted.
+trap '{ code=$?; set +x; } 2>/dev/null; exit $code' INT TERM HUP
# The user-facing functions are loaded from a separate file so that
# test_perf subshells can have them too
@@ -681,7 +723,7 @@ test_failure_ () {
say_color error "not ok $test_count - $1"
shift
printf '%s\n' "$*" | sed -e 's/^/# /'
- test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
+ test "$immediate" = "" || { finalize_junit_xml; GIT_EXIT_OK=t; exit 1; }
}
test_known_broken_ok_ () {
@@ -858,6 +900,7 @@ maybe_setup_valgrind () {
fi
}
+trace_level_=0
want_trace () {
test "$trace" = t && {
test "$verbose" = t || test "$verbose_log" = t
@@ -871,7 +914,7 @@ want_trace () {
test_eval_inner_ () {
# Do not add anything extra (including LF) after '$*'
eval "
- want_trace && set -x
+ want_trace && trace_level_=$(($trace_level_+1)) && set -x
$*"
}
@@ -902,7 +945,8 @@ test_eval_ () {
test_eval_ret_=$?
if want_trace
then
- set +x
+ test 1 = $trace_level_ && set +x
+ trace_level_=$(($trace_level_-1))
fi
} 2>/dev/null 4>&2
@@ -980,6 +1024,12 @@ test_skip () {
to_skip=t
skipped_reason="GIT_SKIP_TESTS"
fi
+ if test -z "$to_skip" && test -n "$run_list" &&
+ ! match_test_selector_list '--run' $test_count "$run_list"
+ then
+ to_skip=t
+ skipped_reason="--run"
+ fi
if test -z "$to_skip" && test -n "$test_prereq" &&
! test_have_prereq "$test_prereq"
then
@@ -992,12 +1042,6 @@ test_skip () {
fi
skipped_reason="missing $missing_prereq${of_prereq}"
fi
- if test -z "$to_skip" && test -n "$run_list" &&
- ! match_test_selector_list '--run' $test_count "$run_list"
- then
- to_skip=t
- skipped_reason="--run"
- fi
case "$to_skip" in
t)
@@ -1049,9 +1093,7 @@ write_junit_xml_testcase () {
junit_have_testcase=t
}
-test_done () {
- GIT_EXIT_OK=t
-
+finalize_junit_xml () {
if test -n "$write_junit_xml" && test -n "$junit_xml_path"
then
test -n "$junit_have_testcase" || {
@@ -1061,12 +1103,40 @@ test_done () {
# adjust the overall time
junit_time=$(test-tool date getnanos $junit_suite_start)
- sed "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
+ sed -e "s/\(<testsuite.*\) time=\"[^\"]*\"/\1/" \
+ -e "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
+ -e '/^ *<\/testsuite/d' \
<"$junit_xml_path" >"$junit_xml_path.new"
mv "$junit_xml_path.new" "$junit_xml_path"
write_junit_xml " </testsuite>" "</testsuites>"
+ write_junit_xml=
fi
+}
+
+test_atexit_cleanup=:
+test_atexit_handler () {
+ # In a succeeding test script 'test_atexit_handler' is invoked
+ # twice: first from 'test_done', then from 'die' in the trap on
+ # EXIT.
+ # This condition and resetting 'test_atexit_cleanup' below makes
+ # sure that the registered cleanup commands are run only once.
+ test : != "$test_atexit_cleanup" || return 0
+
+ setup_malloc_check
+ test_eval_ "$test_atexit_cleanup"
+ test_atexit_cleanup=:
+ teardown_malloc_check
+}
+
+test_done () {
+ GIT_EXIT_OK=t
+
+ # Run the atexit commands _before_ the trash directory is
+ # removed, so the commands can access pidfiles and socket files.
+ test_atexit_handler
+
+ finalize_junit_xml
if test -z "$HARNESS_ACTIVE"
then
@@ -1334,6 +1404,20 @@ then
fi
fi
+# Convenience
+# A regexp to match 5, 35 and 40 hexdigits
+_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
+_x35="$_x05$_x05$_x05$_x05$_x05$_x05$_x05"
+_x40="$_x35$_x05"
+
+test_oid_init
+
+ZERO_OID=$(test_oid zero)
+OID_REGEX=$(echo $ZERO_OID | sed -e 's/0/[0-9a-f]/g')
+EMPTY_TREE=$(test_oid empty_tree)
+EMPTY_BLOB=$(test_oid empty_blob)
+_z40=$ZERO_OID
+
# Provide an implementation of the 'yes' utility; the upper bound
# limit is there to help Windows that cannot stop this loop from
# wasting cycles when the downstream stops reading, so do not be
@@ -1355,7 +1439,26 @@ yes () {
done
}
-# Fix some commands on Windows
+# The GIT_TEST_FAIL_PREREQS code hooks into test_set_prereq(), and
+# thus needs to be set up really early, and set an internal variable
+# for convenience so the hot test_set_prereq() codepath doesn't need
+# to call "git env--helper" (via test_bool_env). Only do that work
+# if needed by seeing if GIT_TEST_FAIL_PREREQS is set at all.
+GIT_TEST_FAIL_PREREQS_INTERNAL=
+if test -n "$GIT_TEST_FAIL_PREREQS"
+then
+ if test_bool_env GIT_TEST_FAIL_PREREQS false
+ then
+ GIT_TEST_FAIL_PREREQS_INTERNAL=true
+ test_set_prereq FAIL_PREREQS
+ fi
+else
+ test_lazy_prereq FAIL_PREREQS '
+ test_bool_env GIT_TEST_FAIL_PREREQS false
+ '
+fi
+
+# Fix some commands on Windows, and other OS-specific things
uname_s=$(uname -s)
case $uname_s in
*MINGW*)
@@ -1386,6 +1489,12 @@ case $uname_s in
test_set_prereq SED_STRIPS_CR
test_set_prereq GREP_STRIPS_CR
;;
+FreeBSD)
+ test_set_prereq REGEX_ILLSEQ
+ test_set_prereq POSIXPERM
+ test_set_prereq BSLASHPSPEC
+ test_set_prereq EXECKEEPSPID
+ ;;
*)
test_set_prereq POSIXPERM
test_set_prereq BSLASHPSPEC
@@ -1405,14 +1514,13 @@ test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
if test -n "$GIT_TEST_GETTEXT_POISON_ORIG"
then
GIT_TEST_GETTEXT_POISON=$GIT_TEST_GETTEXT_POISON_ORIG
+ export GIT_TEST_GETTEXT_POISON
unset GIT_TEST_GETTEXT_POISON_ORIG
fi
-# Can we rely on git's output in the C locale?
-if test -z "$GIT_TEST_GETTEXT_POISON"
-then
- test_set_prereq C_LOCALE_OUTPUT
-fi
+test_lazy_prereq C_LOCALE_OUTPUT '
+ ! test_bool_env GIT_TEST_GETTEXT_POISON false
+'
if test -z "$GIT_TEST_CHECK_CACHE_TREE"
then
@@ -1487,7 +1595,7 @@ test_lazy_prereq NOT_ROOT '
'
test_lazy_prereq JGIT '
- type jgit
+ jgit --version
'
# SANITY is about "can you correctly predict what the filesystem would