summaryrefslogtreecommitdiff
path: root/t/test-lib.sh
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2019-01-29 14:19:27 (GMT)
committerJunio C Hamano <gitster@pobox.com>2019-01-29 17:26:46 (GMT)
commit222319081515f9f6a4c699bd3a406f181a6ddc3b (patch)
treecda71fef70560debe6b0d6978796e78fd69eb4b0 /t/test-lib.sh
parent4419de916493d8a4292e9b78be6c18aa3641d353 (diff)
downloadgit-222319081515f9f6a4c699bd3a406f181a6ddc3b.zip
git-222319081515f9f6a4c699bd3a406f181a6ddc3b.tar.gz
git-222319081515f9f6a4c699bd3a406f181a6ddc3b.tar.bz2
tests: optionally write results as JUnit-style .xml
This will come in handy when publishing the results of Git's test suite during an automated Azure DevOps run. Note: we need to make extra sure that invalid UTF-8 encoding is turned into valid UTF-8 (using the Replacement Character, \uFFFD) because t9902's trace contains such invalid byte sequences, and the task in the Azure Pipeline that uploads the test results would refuse to do anything if it was asked to parse an .xml file with invalid UTF-8 in it. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 't/test-lib.sh')
-rw-r--r--t/test-lib.sh91
1 files changed, 91 insertions, 0 deletions
diff --git a/t/test-lib.sh b/t/test-lib.sh
index a1abb11..a3b2166 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -139,6 +139,9 @@ do
verbose_log=t
tee=t
;;
+ --write-junit-xml)
+ write_junit_xml=t
+ ;;
--stress)
stress=t ;;
--stress=*)
@@ -622,11 +625,24 @@ trap 'exit $?' INT TERM HUP
# the test_expect_* functions instead.
test_ok_ () {
+ if test -n "$write_junit_xml"
+ then
+ write_junit_xml_testcase "$*"
+ fi
test_success=$(($test_success + 1))
say_color "" "ok $test_count - $@"
}
test_failure_ () {
+ if test -n "$write_junit_xml"
+ then
+ junit_insert="<failure message=\"not ok $test_count -"
+ junit_insert="$junit_insert $(xml_attr_encode "$1")\">"
+ junit_insert="$junit_insert $(xml_attr_encode \
+ "$(printf '%s\n' "$@" | sed 1d)")"
+ junit_insert="$junit_insert</failure>"
+ write_junit_xml_testcase "$1" " $junit_insert"
+ fi
test_failure=$(($test_failure + 1))
say_color error "not ok $test_count - $1"
shift
@@ -635,11 +651,19 @@ test_failure_ () {
}
test_known_broken_ok_ () {
+ if test -n "$write_junit_xml"
+ then
+ write_junit_xml_testcase "$* (breakage fixed)"
+ fi
test_fixed=$(($test_fixed+1))
say_color error "ok $test_count - $@ # TODO known breakage vanished"
}
test_known_broken_failure_ () {
+ if test -n "$write_junit_xml"
+ then
+ write_junit_xml_testcase "$* (known breakage)"
+ fi
test_broken=$(($test_broken+1))
say_color warn "not ok $test_count - $@ # TODO known breakage"
}
@@ -897,6 +921,10 @@ test_start_ () {
test_count=$(($test_count+1))
maybe_setup_verbose
maybe_setup_valgrind
+ if test -n "$write_junit_xml"
+ then
+ junit_start=$(test-tool date getnanos)
+ fi
}
test_finish_ () {
@@ -934,6 +962,13 @@ test_skip () {
case "$to_skip" in
t)
+ if test -n "$write_junit_xml"
+ then
+ message="$(xml_attr_encode "$skipped_reason")"
+ write_junit_xml_testcase "$1" \
+ " <skipped message=\"$message\" />"
+ fi
+
say_color skip >&3 "skipping test: $@"
say_color skip "ok $test_count # skip $1 ($skipped_reason)"
: true
@@ -949,9 +984,51 @@ test_at_end_hook_ () {
:
}
+write_junit_xml () {
+ case "$1" in
+ --truncate)
+ >"$junit_xml_path"
+ junit_have_testcase=
+ shift
+ ;;
+ esac
+ printf '%s\n' "$@" >>"$junit_xml_path"
+}
+
+xml_attr_encode () {
+ printf '%s\n' "$@" | test-tool xml-encode
+}
+
+write_junit_xml_testcase () {
+ junit_attrs="name=\"$(xml_attr_encode "$this_test.$test_count $1")\""
+ shift
+ junit_attrs="$junit_attrs classname=\"$this_test\""
+ junit_attrs="$junit_attrs time=\"$(test-tool \
+ date getnanos $junit_start)\""
+ write_junit_xml "$(printf '%s\n' \
+ " <testcase $junit_attrs>" "$@" " </testcase>")"
+ junit_have_testcase=t
+}
+
test_done () {
GIT_EXIT_OK=t
+ if test -n "$write_junit_xml" && test -n "$junit_xml_path"
+ then
+ test -n "$junit_have_testcase" || {
+ junit_start=$(test-tool date getnanos)
+ write_junit_xml_testcase "all tests skipped"
+ }
+
+ # adjust the overall time
+ junit_time=$(test-tool date getnanos $junit_suite_start)
+ sed "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
+ <"$junit_xml_path" >"$junit_xml_path.new"
+ mv "$junit_xml_path.new" "$junit_xml_path"
+
+ write_junit_xml " </testsuite>" "</testsuites>"
+ fi
+
if test -z "$HARNESS_ACTIVE"
then
mkdir -p "$TEST_RESULTS_DIR"
@@ -1178,6 +1255,7 @@ then
else
mkdir -p "$TRASH_DIRECTORY"
fi
+
# 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 "$TRASH_DIRECTORY" || exit 1
@@ -1191,6 +1269,19 @@ then
test_done
fi
+if test -n "$write_junit_xml"
+then
+ junit_xml_dir="$TEST_OUTPUT_DIRECTORY/out"
+ mkdir -p "$junit_xml_dir"
+ junit_xml_base=${0##*/}
+ junit_xml_path="$junit_xml_dir/TEST-${junit_xml_base%.sh}.xml"
+ junit_attrs="name=\"${junit_xml_base%.sh}\""
+ junit_attrs="$junit_attrs timestamp=\"$(TZ=UTC \
+ date +%Y-%m-%dT%H:%M:%S)\""
+ write_junit_xml --truncate "<testsuites>" " <testsuite $junit_attrs>"
+ junit_suite_start=$(test-tool date getnanos)
+fi
+
# Provide an implementation of the 'yes' utility
yes () {
if test $# = 0