git-prompt: use here-doc instead of here-string
[git/gitster.git] / t / test-lib-junit.sh
blob76cbbd3299d64a82276c0aa30241479388014af8
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 https://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"
35 then
36 GIT_TEST_TEE_OFFSET=0
40 start_test_case_output () {
41 junit_start=$(test-tool date getnanos)
44 finalize_test_case_output () {
45 test_case_result=$1
46 shift
47 case "$test_case_result" in
48 ok)
49 set -- "$*"
51 failure)
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"
56 then
57 test-tool path-utils skip-n-bytes \
58 "$GIT_TEST_TEE_OUTPUT_FILE" $GIT_TEST_TEE_OFFSET
59 else
60 printf '%s\n' "$@" | sed 1d
61 fi)")"
62 junit_insert="$junit_insert</failure>"
63 if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
64 then
65 junit_insert="$junit_insert<system-err>$(xml_attr_encode \
66 "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")</system-err>"
68 set -- "$1" " $junit_insert"
70 fixed)
71 set -- "$* (breakage fixed)"
73 broken)
74 set -- "$* (known breakage)"
76 skip)
77 message="$(xml_attr_encode --no-lf "$skipped_reason")"
78 set -- "$1" " <skipped message=\"$message\" />"
80 esac
82 junit_attrs="name=\"$(xml_attr_encode --no-lf "$this_test.$test_count $1")\""
83 shift
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>")"
89 junit_have_testcase=t
92 finalize_test_output () {
93 if test -n "$junit_xml_path"
94 then
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>"
109 write_junit_xml=
113 write_junit_xml () {
114 case "$1" in
115 --truncate)
116 >"$junit_xml_path"
117 junit_have_testcase=
118 shift
120 esac
121 printf '%s\n' "$@" >>"$junit_xml_path"
124 xml_attr_encode () {
125 if test "x$1" = "x--no-lf"
126 then
127 shift
128 printf '%s' "$*" | test-tool xml-encode
129 else
130 printf '%s\n' "$@" | test-tool xml-encode