Skip to content

Commit fe3ab75

Browse files
authored
Rollup merge of rust-lang#149437 - ilammy:patch-1, r=Mark-Simulacrum
Fix trailing newline in JUnit formatter `write_message()` expects messages to contain no newlines. Fixes rust-lang#149436
2 parents 415decd + 069cf9d commit fe3ab75

File tree

7 files changed

+95
-9
lines changed

7 files changed

+95
-9
lines changed

library/test/src/formatters/junit.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,10 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> {
189189
compilation_time: f64,
190190
) -> io::Result<()> {
191191
self.write_message(&format!(
192-
"<report total_time=\"{total_time}\" compilation_time=\"{compilation_time}\"></report>\n",
193-
))
192+
"<report total_time=\"{total_time}\" compilation_time=\"{compilation_time}\"></report>",
193+
))?;
194+
self.out.write_all(b"\n")?;
195+
Ok(())
194196
}
195197
}
196198

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="test" package="test" id="0" errors="0" failures="0" tests="3" skipped="0" ><testcase classname="doctest.rs" name="add (line 1)" time="$TIME"/><testcase classname="doctest.rs" name="add (line 5)" time="$TIME"/><testcase classname="doctest.rs" name="add (line 9)" time="$TIME"/><system-out/><system-err/></testsuite></testsuites>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="test" package="test" id="0" errors="0" failures="0" tests="2" skipped="0" ><testcase classname="doctest.rs" name="add (line 1)" time="$TIME"/><testcase classname="doctest.rs" name="add (line 5)" time="$TIME"/><system-out/><system-err/></testsuite></testsuites>
2+
<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="test" package="test" id="0" errors="0" failures="0" tests="1" skipped="0" ><testcase classname="doctest.rs" name="add (line 9)" time="$TIME"/><system-out/><system-err/></testsuite></testsuites>
3+
<report total_time="$TIME" compilation_time="$TIME"></report>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/// ```
2+
/// assert_eq!(doctest::add(2, 2), 4);
3+
/// ```
4+
///
5+
/// ```should_panic
6+
/// assert_eq!(doctest::add(2, 2), 5);
7+
/// ```
8+
///
9+
/// ```compile_fail
10+
/// assert_eq!(doctest::add(2, 2), "banana");
11+
/// ```
12+
pub fn add(a: i32, b: i32) -> i32 {
13+
a + b
14+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Check rustdoc's test JUnit (XML) output against snapshots.
2+
3+
//@ ignore-cross-compile (running doctests)
4+
//@ needs-unwind (test file contains `should_panic` test)
5+
6+
use std::path::Path;
7+
8+
use run_make_support::{cwd, diff, python_command, rustc, rustdoc};
9+
10+
fn main() {
11+
let rlib = cwd().join("libdoctest.rlib");
12+
rustc().input("doctest.rs").crate_type("rlib").output(&rlib).run();
13+
14+
run_doctests(&rlib, "2021", "doctest-2021.xml");
15+
run_doctests(&rlib, "2024", "doctest-2024.xml");
16+
}
17+
18+
#[track_caller]
19+
fn run_doctests(rlib: &Path, edition: &str, expected_xml: &str) {
20+
let rustdoc_out = rustdoc()
21+
.input("doctest.rs")
22+
.args(&[
23+
"--test",
24+
"--test-args=-Zunstable-options",
25+
"--test-args=--test-threads=1",
26+
"--test-args=--format=junit",
27+
])
28+
.edition(edition)
29+
.env("RUST_BACKTRACE", "0")
30+
.extern_("doctest", rlib.display().to_string())
31+
.run();
32+
let rustdoc_stdout = &rustdoc_out.stdout_utf8();
33+
34+
// FIXME: merged output of compile_fail tests is broken
35+
if edition != "2024" {
36+
python_command().arg("validate_junit.py").stdin_buf(rustdoc_stdout).run();
37+
}
38+
39+
diff()
40+
.expected_file(expected_xml)
41+
.actual_text("output", rustdoc_stdout)
42+
.normalize(r#"\b(time|total_time|compilation_time)="[0-9.]+""#, r#"$1="$$TIME""#)
43+
.run();
44+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env python
2+
3+
# Trivial Python script that reads lines from stdin, and checks that each line
4+
# is a well-formed XML document.
5+
#
6+
# This takes advantage of the fact that Python has a built-in XML parser,
7+
# whereas doing the same check in Rust would require us to pull in an XML
8+
# crate just for this relatively-minor test.
9+
#
10+
# If you're trying to remove Python scripts from the test suite, think twice
11+
# before removing this one. You could do so, but it's probably not worth it.
12+
13+
import sys
14+
import xml.etree.ElementTree as ET
15+
16+
# Read the entire output and try to decode it as XML.
17+
junit = sys.stdin.read()
18+
try:
19+
ET.fromstring(junit)
20+
except ET.ParseError:
21+
print("Invalid xml: %r" % junit)
22+
raise

tests/run-make/libtest-junit/validate_junit.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
import sys
1414
import xml.etree.ElementTree as ET
1515

16-
# Try to decode line in order to ensure it is a valid XML document
17-
for line in sys.stdin:
18-
try:
19-
ET.fromstring(line)
20-
except ET.ParseError:
21-
print("Invalid xml: %r" % line)
22-
raise
16+
# Read the entire output and try to decode it as XML.
17+
junit = sys.stdin.read()
18+
try:
19+
ET.fromstring(junit)
20+
except ET.ParseError:
21+
print("Invalid xml: %r" % junit)
22+
raise

0 commit comments

Comments
 (0)