1 # Library of functions to format test scripts' output in JUnit XML
2 # format, to support Git's test suite result to be presented in an
3 # easily digestible way on Azure Pipelines.
5 # Copyright (c) 2022 Johannes Schindelin
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see http://www.gnu.org/licenses/ .
20 # The idea is for `test-lib.sh` to source this file when the user asks
21 # for JUnit XML; these functions will then override (empty) functions
22 # that are are called at the appropriate times during the test runs.
24 start_test_output
() {
25 junit_xml_dir
="$TEST_OUTPUT_DIRECTORY/out"
26 mkdir
-p "$junit_xml_dir"
27 junit_xml_base
=${1##*/}
28 junit_xml_path
="$junit_xml_dir/TEST-${junit_xml_base%.sh}.xml"
29 junit_attrs
="name=\"${junit_xml_base%.sh}\""
30 junit_attrs
="$junit_attrs timestamp=\"$(TZ=UTC \
31 date +%Y-%m-%dT%H:%M:%S)\""
32 write_junit_xml
--truncate "<testsuites>" " <testsuite $junit_attrs>"
33 junit_suite_start
=$
(test-tool
date getnanos
)
34 if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
40 start_test_case_output
() {
41 junit_start
=$
(test-tool
date getnanos
)
44 finalize_test_case_output
() {
47 case "$test_case_result" in
52 junit_insert
="<failure message=\"not ok $test_count -"
53 junit_insert
="$junit_insert $(xml_attr_encode --no-lf "$1")\">"
54 junit_insert
="$junit_insert $(xml_attr_encode \
55 "$
(if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
57 test-tool path-utils skip-n-bytes \
58 "$GIT_TEST_TEE_OUTPUT_FILE" $GIT_TEST_TEE_OFFSET
60 printf '%s\n' "$@" |
sed 1d
62 junit_insert
="$junit_insert</failure>"
63 if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
65 junit_insert
="$junit_insert<system-err>$(xml_attr_encode \
66 "$
(cat "$GIT_TEST_TEE_OUTPUT_FILE")")</system-err>"
68 set -- "$1" " $junit_insert"
71 set -- "$* (breakage fixed)"
74 set -- "$* (known breakage)"
77 message
="$(xml_attr_encode --no-lf "$skipped_reason")"
78 set -- "$1" " <skipped message=\"$message\" />"
82 junit_attrs
="name=\"$(xml_attr_encode --no-lf "$this_test.
$test_count $1")\""
84 junit_attrs
="$junit_attrs classname=\"$this_test\""
85 junit_attrs
="$junit_attrs time=\"$(test-tool \
86 date getnanos $junit_start)\""
87 write_junit_xml
"$(printf '%s\n' \
88 " <testcase
$junit_attrs>" "$@
" " </testcase
>")"
92 finalize_test_output
() {
93 if test -n "$junit_xml_path"
95 test -n "$junit_have_testcase" ||
{
96 junit_start
=$
(test-tool
date getnanos
)
97 write_junit_xml_testcase
"all tests skipped"
100 # adjust the overall time
101 junit_time
=$
(test-tool
date getnanos
$junit_suite_start)
102 sed -e "s/\(<testsuite.*\) time=\"[^\"]*\"/\1/" \
103 -e "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
104 -e '/^ *<\/testsuite/d' \
105 <"$junit_xml_path" >"$junit_xml_path.new"
106 mv "$junit_xml_path.new" "$junit_xml_path"
108 write_junit_xml
" </testsuite>" "</testsuites>"
121 printf '%s\n' "$@" >>"$junit_xml_path"
125 if test "x$1" = "x--no-lf"
128 printf '%s' "$*" | test-tool xml-encode
130 printf '%s\n' "$@" | test-tool xml-encode