| # Library of functions to format test scripts' output in JUnit XML |
| # format, to support Git's test suite result to be presented in an |
| # easily digestible way on Azure Pipelines. |
| # |
| # Copyright (c) 2022 Johannes Schindelin |
| # |
| # This program is free software: you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation, either version 2 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program. If not, see https://www.gnu.org/licenses/ . |
| # |
| # The idea is for `test-lib.sh` to source this file when the user asks |
| # for JUnit XML; these functions will then override (empty) functions |
| # that are are called at the appropriate times during the test runs. |
| |
| start_test_output () { |
| junit_xml_dir="$TEST_OUTPUT_DIRECTORY/out" |
| mkdir -p "$junit_xml_dir" |
| junit_xml_base=${1##*/} |
| 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) |
| if test -n "$GIT_TEST_TEE_OUTPUT_FILE" |
| then |
| GIT_TEST_TEE_OFFSET=0 |
| fi |
| } |
| |
| start_test_case_output () { |
| junit_start=$(test-tool date getnanos) |
| } |
| |
| finalize_test_case_output () { |
| test_case_result=$1 |
| shift |
| case "$test_case_result" in |
| ok) |
| set -- "$*" |
| ;; |
| failure) |
| junit_insert="<failure message=\"not ok $test_count -" |
| junit_insert="$junit_insert $(xml_attr_encode --no-lf "$1")\">" |
| junit_insert="$junit_insert $(xml_attr_encode \ |
| "$(if test -n "$GIT_TEST_TEE_OUTPUT_FILE" |
| then |
| test-tool path-utils skip-n-bytes \ |
| "$GIT_TEST_TEE_OUTPUT_FILE" $GIT_TEST_TEE_OFFSET |
| else |
| printf '%s\n' "$@" | sed 1d |
| fi)")" |
| junit_insert="$junit_insert</failure>" |
| if test -n "$GIT_TEST_TEE_OUTPUT_FILE" |
| then |
| junit_insert="$junit_insert<system-err>$(xml_attr_encode \ |
| "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")</system-err>" |
| fi |
| set -- "$1" " $junit_insert" |
| ;; |
| fixed) |
| set -- "$* (breakage fixed)" |
| ;; |
| broken) |
| set -- "$* (known breakage)" |
| ;; |
| skip) |
| message="$(xml_attr_encode --no-lf "$skipped_reason")" |
| set -- "$1" " <skipped message=\"$message\" />" |
| ;; |
| esac |
| |
| junit_attrs="name=\"$(xml_attr_encode --no-lf "$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 |
| } |
| |
| finalize_test_output () { |
| if 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 -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 |
| } |
| |
| write_junit_xml () { |
| case "$1" in |
| --truncate) |
| >"$junit_xml_path" |
| junit_have_testcase= |
| shift |
| ;; |
| esac |
| printf '%s\n' "$@" >>"$junit_xml_path" |
| } |
| |
| xml_attr_encode () { |
| if test "x$1" = "x--no-lf" |
| then |
| shift |
| printf '%s' "$*" | test-tool xml-encode |
| else |
| printf '%s\n' "$@" | test-tool xml-encode |
| fi |
| } |