Thread (9 messages) 9 messages, 1 author, 14h ago

[RFC/PATCH 8/8] test-lib: drop the shell JUnit XML reporting code

flat view
DORMANTno replies

From: Jeff King <hidden>
Date: 2026-10-27 17:42:33
Subsystem: kernel build + files below scripts/ (unless maintained elsewhere), the rest · Maintainers: Nathan Chancellor, Nicolas Schier, Linus Torvalds

Our shell tests can produce JUnit XML with --write-junit-xml, but we
don't have any in-tree callers. The Azure Pipelines consumer went away,
with the remaining CI references removed in e39e332e50 (ci: remove stale
code for Azure Pipelines, 2025-01-10).

GitLab CI does still consume JUnit XML, but that's generated by Meson in
meson-logs/testlog.junit.xml, not by us directly.

It's possible that somebody is invoking the tests with --write-junit-xml
themselves, but we have no easy way of knowing. If so then we'd need to
drop/revert this patch. I tend to doubt it somewhat, though. We fixed a
bug earlier in the series that would cause several tests to fail when
run with "set -e", and we enable that feature automatically when the
test suite is run under recent versions of bash. So there's a reasonable
chance anybody using it would have been seeing test failures since
ffe8005b9d (t: detect errors outside of test cases, 2026-04-21).

Getting rid of the option lets us also drop the test-lib-junit.sh file
and the test-tool xml encoder. Note that the start_test_case_output and
finalize_test_output hooks in test-lib.sh aren't used by anybody, but
I've left them for now. In theory they're generally useful, and they
don't cost very much to support. The other hooks are still used for
GitHub workflow annotations.

Signed-off-by: Jeff King <redacted>
---
 Makefile                   |   1 -
 t/helper/meson.build       |   1 -
 t/helper/test-tool.c       |   1 -
 t/helper/test-tool.h       |   1 -
 t/helper/test-xml-encode.c |  80 ------------------------
 t/test-lib-junit.sh        | 125 -------------------------------------
 t/test-lib.sh              |   5 +-
 7 files changed, 1 insertion(+), 213 deletions(-)
 delete mode 100644 t/helper/test-xml-encode.c
 delete mode 100644 t/test-lib-junit.sh
diff --git a/Makefile b/Makefile
index a96be506b5..20ccdb7fa7 100644
--- a/Makefile
+++ b/Makefile
@@ -879,7 +879,6 @@ TEST_BUILTINS_OBJS += test-userdiff.o
 TEST_BUILTINS_OBJS += test-wildmatch.o
 TEST_BUILTINS_OBJS += test-windows-named-pipe.o
 TEST_BUILTINS_OBJS += test-write-cache.o
-TEST_BUILTINS_OBJS += test-xml-encode.o
 TEST_BUILTINS_OBJS += test-zlib.o
 
 # Do not add more tests here unless they have extra dependencies. Add
diff --git a/t/helper/meson.build b/t/helper/meson.build
index ae513b4cdc..3dcc4d5219 100644
--- a/t/helper/meson.build
+++ b/t/helper/meson.build
@@ -77,7 +77,6 @@ test_tool_sources = [
   'test-wildmatch.c',
   'test-windows-named-pipe.c',
   'test-write-cache.c',
-  'test-xml-encode.c',
   'test-zlib.c',
 ]
 
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index b71a22b43b..b1be64da06 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -86,7 +86,6 @@ static struct test_cmd cmds[] = {
 	{ "trace2", cmd__trace2 },
 	{ "truncate", cmd__truncate },
 	{ "userdiff", cmd__userdiff },
-	{ "xml-encode", cmd__xml_encode },
 	{ "wildmatch", cmd__wildmatch },
 #ifdef GIT_WINDOWS_NATIVE
 	{ "windows-named-pipe", cmd__windows_named_pipe },
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index f2885b33d5..17b72276a1 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -79,7 +79,6 @@ int cmd__synthesize(int argc, const char **argv);
 int cmd__trace2(int argc, const char **argv);
 int cmd__truncate(int argc, const char **argv);
 int cmd__userdiff(int argc, const char **argv);
-int cmd__xml_encode(int argc, const char **argv);
 int cmd__wildmatch(int argc, const char **argv);
 #ifdef GIT_WINDOWS_NATIVE
 int cmd__windows_named_pipe(int argc, const char **argv);
diff --git a/t/helper/test-xml-encode.c b/t/helper/test-xml-encode.c
deleted file mode 100644
index b2f330d1a4..0000000000
--- a/t/helper/test-xml-encode.c
+++ /dev/null
@@ -1,80 +0,0 @@
-#include "test-tool.h"
-
-static const char *utf8_replace_character = "&#xfffd;";
-
-/*
- * Encodes (possibly incorrect) UTF-8 on <stdin> to <stdout>, to be embedded
- * in an XML file.
- */
-int cmd__xml_encode(int argc UNUSED, const char **argv UNUSED)
-{
-	unsigned char buf[1024], tmp[4], *tmp2 = NULL;
-	ssize_t cur = 0, len = 1, remaining = 0;
-	unsigned char ch;
-
-	for (;;) {
-		if (++cur == len) {
-			len = xread(0, buf, sizeof(buf));
-			if (!len)
-				return 0;
-			if (len < 0)
-				die_errno("Could not read <stdin>");
-			cur = 0;
-		}
-		ch = buf[cur];
-
-		if (tmp2) {
-			if ((ch & 0xc0) != 0x80) {
-				fputs(utf8_replace_character, stdout);
-				tmp2 = NULL;
-				cur--;
-				continue;
-			}
-			*tmp2 = ch;
-			tmp2++;
-			if (--remaining == 0) {
-				fwrite(tmp, tmp2 - tmp, 1, stdout);
-				tmp2 = NULL;
-			}
-			continue;
-		}
-
-		if (!(ch & 0x80)) {
-			/* 0xxxxxxx */
-			if (ch == '&')
-				fputs("&amp;", stdout);
-			else if (ch == '\'')
-				fputs("&apos;", stdout);
-			else if (ch == '"')
-				fputs("&quot;", stdout);
-			else if (ch == '<')
-				fputs("&lt;", stdout);
-			else if (ch == '>')
-				fputs("&gt;", stdout);
-			else if (ch >= 0x20)
-				fputc(ch, stdout);
-			else if (ch == 0x09 || ch == 0x0a || ch == 0x0d)
-				fprintf(stdout, "&#x%02x;", ch);
-			else
-				fputs(utf8_replace_character, stdout);
-		} else if ((ch & 0xe0) == 0xc0) {
-			/* 110XXXXx 10xxxxxx */
-			tmp[0] = ch;
-			remaining = 1;
-			tmp2 = tmp + 1;
-		} else if ((ch & 0xf0) == 0xe0) {
-			/* 1110XXXX 10Xxxxxx 10xxxxxx */
-			tmp[0] = ch;
-			remaining = 2;
-			tmp2 = tmp + 1;
-		} else if ((ch & 0xf8) == 0xf0) {
-			/* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */
-			tmp[0] = ch;
-			remaining = 3;
-			tmp2 = tmp + 1;
-		} else
-			fputs(utf8_replace_character, stdout);
-	}
-
-	return 0;
-}
diff --git a/t/test-lib-junit.sh b/t/test-lib-junit.sh
deleted file mode 100644
index 03a7360198..0000000000
--- a/t/test-lib-junit.sh
+++ /dev/null
@@ -1,125 +0,0 @@
-# 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 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>")"
-}
-
-finalize_test_output () {
-	if test -n "$junit_xml_path"
-	then
-		# 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"
-		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
-}
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 3754db0ea7..c107fd687a 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -195,7 +195,7 @@ mark_option_requires_arg () {
 	store_arg_to=$2
 }
 
-# These functions can be overridden e.g. to output JUnit XML
+# These functions can be overridden e.g. to add CI workflow annotations
 start_test_output () { :; }
 start_test_case_output () { :; }
 finalize_test_case_output () { :; }
@@ -260,9 +260,6 @@ parse_option () {
 		verbose_log=t
 		tee=t
 		;;
-	--write-junit-xml)
-		. "$TEST_DIRECTORY/test-lib-junit.sh"
-		;;
 	--github-workflow-markup)
 		. "$TEST_DIRECTORY/test-lib-github-workflow-markup.sh"
 		;;
-- 
2.56.0.559.g7c1a1d8168
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help