Skip to content

Commit

Permalink
Write lit xml output as utf-8 (#6130)
Browse files Browse the repository at this point in the history
This commit modifies the xml output of lit so that we always open the
file as utf-8 and also encode any invalid characters with the xml
character reference.

I was hitting an encoding error on windows for some test output because
the xml file was using the windows cp1252 encoding and it ran into some
characters that could not be encoded.

In order to test the change I added a new flag to lit
`--xml-include-test-output` which will include all test output in the
xml. That way we can still expect the lit run to pass and also validate
that the xml file is properly encoded.
  • Loading branch information
dmpots authored Jan 5, 2024
1 parent b5c5b52 commit d936753
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 8 deletions.
9 changes: 7 additions & 2 deletions utils/lit/lit/Test.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ def isExpectedToFail(self):
return False


def getJUnitXML(self):
def getJUnitXML(self, includeAllTestOutput=False):
test_name = self.path_in_suite[-1]
test_path = self.path_in_suite[:-1]
safe_test_path = [x.replace(".","_") for x in test_path]
Expand All @@ -252,5 +252,10 @@ def getJUnitXML(self):
xml += ">\n\t<failure >\n" + escape(self.result.output)
xml += "\n\t</failure>\n</testcase>"
else:
xml += "/>"
if includeAllTestOutput:
xml += ">"
xml += "\n\t<system-out>\n" + escape(self.result.output)
xml += "\n\t</system-out>\n</testcase>"
else:
xml += "/>"
return xml
7 changes: 5 additions & 2 deletions utils/lit/lit/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ def main(builtinParameters = {}):
group.add_option("", "--use-threads", dest="useProcesses",
help="Run tests in parallel with threads (not processes)",
action="store_false", default=useProcessesIsDefault)
group.add_option("", "--xml-include-test-output", dest="xmlIncludeTestOutput",
help="Include system out in xml output for all tests",
action="store_true", default=False)
parser.add_option_group(group)

(opts, args) = parser.parse_args()
Expand Down Expand Up @@ -447,7 +450,7 @@ def main(builtinParameters = {}):
by_suite[suite]['failures'] += 1
else:
by_suite[suite]['passes'] += 1
xunit_output_file = open(opts.xunit_output_file, "w")
xunit_output_file = open(opts.xunit_output_file, "w", encoding="utf-8", errors="xmlcharrefreplace")
xunit_output_file.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n")
xunit_output_file.write("<testsuites>\n")
for suite_name, suite in by_suite.items():
Expand All @@ -458,7 +461,7 @@ def main(builtinParameters = {}):
xunit_output_file.write(" failures='" + str(suite['failures']) +
"'>\n")
for result_test in suite['tests']:
xunit_output_file.write(result_test.getJUnitXML() + "\n")
xunit_output_file.write(result_test.getJUnitXML(opts.xmlIncludeTestOutput) + "\n")
xunit_output_file.write("</testsuite>\n")
xunit_output_file.write("</testsuites>")
xunit_output_file.close()
Expand Down
2 changes: 1 addition & 1 deletion utils/lit/tests/Inputs/test-data/lit.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class DummyFormat(lit.formats.FileBasedTest):
source_path = test.getSourcePath()

cfg = ConfigParser.ConfigParser()
cfg.read(source_path)
cfg.read(source_path, encoding="utf-8")

# Create the basic test result.
result_code = cfg.get('global', 'result_code')
Expand Down
6 changes: 6 additions & 0 deletions utils/lit/tests/Inputs/test-data/utf8_output_message.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[global]
result_code = PASS
result_output = This test is 🔥

[results]
value0 = 1
14 changes: 11 additions & 3 deletions utils/lit/tests/xunit-output.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
# Check xunit output
# RUN: %{lit} --xunit-xml-output %t.xunit.xml %{inputs}/test-data
# RUN: %{lit} --xunit-xml-output %t.xunit.xml --xml-include-test-output %{inputs}/test-data
# RUN: FileCheck < %t.xunit.xml %s

# CHECK: <?xml version="1.0" encoding="UTF-8" ?>
# CHECK: <testsuites>
# CHECK: <testsuite name='test-data' tests='1' failures='0'>
# CHECK: <testcase classname='test-data.test-data' name='metrics.ini' time='0.{{[0-9]+}}'/>
# CHECK: <testsuite name='test-data' tests='2' failures='0'>
# CHECK: <testcase classname='test-data.test-data' name='metrics.ini' time='0.{{[0-9]+}}'>
# CHECK: <system-out>
# CHECK: Test passed.
# CHECK: </system-out>
# CHECK: <testcase classname='test-data.test-data' name='utf8_output_message.ini' time='0.{{[0-9]+}}'>
# CHECK: <system-out>
# CHECK: This test is 🔥
# CHECK: </system-out>
# CHECK: </testcase>
# CHECK: </testsuite>
# CHECK: </testsuites>

0 comments on commit d936753

Please sign in to comment.