]>
Commit | Line | Data |
---|---|---|
78d5e4cf JS |
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. | |
4 | # | |
5 | # Copyright (c) 2022 Johannes Schindelin | |
6 | # | |
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. | |
11 | # | |
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. | |
16 | # | |
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/ . | |
19 | # | |
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. | |
23 | ||
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 | |
37 | fi | |
38 | } | |
39 | ||
40 | start_test_case_output () { | |
41 | junit_start=$(test-tool date getnanos) | |
42 | } | |
43 | ||
44 | finalize_test_case_output () { | |
45 | test_case_result=$1 | |
46 | shift | |
47 | case "$test_case_result" in | |
48 | ok) | |
7253f7ca | 49 | set -- "$*" |
78d5e4cf JS |
50 | ;; |
51 | failure) | |
52 | junit_insert="<failure message=\"not ok $test_count -" | |
270ccd2a | 53 | junit_insert="$junit_insert $(xml_attr_encode --no-lf "$1")\">" |
78d5e4cf JS |
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>" | |
67 | fi | |
7253f7ca | 68 | set -- "$1" " $junit_insert" |
78d5e4cf JS |
69 | ;; |
70 | fixed) | |
7253f7ca | 71 | set -- "$* (breakage fixed)" |
78d5e4cf JS |
72 | ;; |
73 | broken) | |
7253f7ca | 74 | set -- "$* (known breakage)" |
78d5e4cf JS |
75 | ;; |
76 | skip) | |
270ccd2a | 77 | message="$(xml_attr_encode --no-lf "$skipped_reason")" |
7253f7ca | 78 | set -- "$1" " <skipped message=\"$message\" />" |
78d5e4cf JS |
79 | ;; |
80 | esac | |
81 | ||
270ccd2a | 82 | junit_attrs="name=\"$(xml_attr_encode --no-lf "$this_test.$test_count $1")\"" |
78d5e4cf JS |
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 | |
90 | } | |
91 | ||
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" | |
98 | } | |
99 | ||
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" | |
107 | ||
108 | write_junit_xml " </testsuite>" "</testsuites>" | |
109 | write_junit_xml= | |
110 | fi | |
111 | } | |
112 | ||
113 | write_junit_xml () { | |
114 | case "$1" in | |
115 | --truncate) | |
116 | >"$junit_xml_path" | |
117 | junit_have_testcase= | |
118 | shift | |
119 | ;; | |
120 | esac | |
121 | printf '%s\n' "$@" >>"$junit_xml_path" | |
122 | } | |
123 | ||
124 | xml_attr_encode () { | |
270ccd2a JS |
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 | |
131 | fi | |
78d5e4cf | 132 | } |