Skip to content

Commit 1b157a0

Browse files
authored
Rollup merge of #113518 - jyn514:streaming-failures, r=cuviper
bootstrap/libtest: print test name eagerly on failure even with `verbose-tests=false` / `--quiet` Previously, libtest would wait until all tests finished running to print the progress, which made it annoying to run many tests at once (since you don't know which have failed). Change it to print the names as soon as they fail. This makes it much easier to know which test failed without having to wait for compiletest to completely finish running. Before: ``` Testing stage0 compiletest suite=ui mode=ui (x86_64-unknown-linux-gnu) running 15274 tests iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii 88/15274 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii 176/15274 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii 264/15274 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii 352/15274 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii 440/15274 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii 528/15274 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiFFiiiiiii ... ``` After: ``` Testing stage0 compiletest suite=ui mode=ui (x86_64-unknown-linux-gnu) running 15274 tests iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii 88/15274 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii 176/15274 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii 264/15274 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii 352/15274 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii 440/15274 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii 528/15274 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii [ui] tests/ui/associated-type-bounds/implied-in-supertrait.rs ... F [ui] tests/ui/associated-type-bounds/return-type-notation/basic.rs#next_with ... F iiiiiiiiiiiii ... ``` This serves a similar use case to the existing RUSTC_TEST_FAIL_FAST, but is on by default and as a result much more discoverable. We should consider unifying RUSTC_TEST_FAIL_FAST with the `--no-fail-fast` flag in the future for consistency and discoverability.
2 parents bfe762e + 8bfe9db commit 1b157a0

File tree

4 files changed

+191
-11
lines changed

4 files changed

+191
-11
lines changed

library/test/src/formatters/terse.rs

+28-7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub(crate) struct TerseFormatter<T> {
2323
max_name_len: usize,
2424

2525
test_count: usize,
26+
test_column: usize,
2627
total_test_count: usize,
2728
}
2829

@@ -39,6 +40,7 @@ impl<T: Write> TerseFormatter<T> {
3940
max_name_len,
4041
is_multithreaded,
4142
test_count: 0,
43+
test_column: 0,
4244
total_test_count: 0, // initialized later, when write_run_start is called
4345
}
4446
}
@@ -47,8 +49,20 @@ impl<T: Write> TerseFormatter<T> {
4749
self.write_short_result(".", term::color::GREEN)
4850
}
4951

50-
pub fn write_failed(&mut self) -> io::Result<()> {
51-
self.write_short_result("F", term::color::RED)
52+
pub fn write_failed(&mut self, name: &str) -> io::Result<()> {
53+
// Put failed tests on their own line and include the test name, so that it's faster
54+
// to see which test failed without having to wait for them all to run.
55+
56+
// normally, we write the progress unconditionally, even if the previous line was cut short.
57+
// but if this is the very first column, no short results will have been printed and we'll end up with *only* the progress on the line.
58+
// avoid this.
59+
if self.test_column != 0 {
60+
self.write_progress()?;
61+
}
62+
self.test_count += 1;
63+
self.write_plain(format!("{name} --- "))?;
64+
self.write_pretty("FAILED", term::color::RED)?;
65+
self.write_plain("\n")
5266
}
5367

5468
pub fn write_ignored(&mut self) -> io::Result<()> {
@@ -65,15 +79,22 @@ impl<T: Write> TerseFormatter<T> {
6579
color: term::color::Color,
6680
) -> io::Result<()> {
6781
self.write_pretty(result, color)?;
68-
if self.test_count % QUIET_MODE_MAX_COLUMN == QUIET_MODE_MAX_COLUMN - 1 {
82+
self.test_count += 1;
83+
self.test_column += 1;
84+
if self.test_column % QUIET_MODE_MAX_COLUMN == QUIET_MODE_MAX_COLUMN - 1 {
6985
// We insert a new line regularly in order to flush the
7086
// screen when dealing with line-buffered output (e.g., piping to
7187
// `stamp` in the rust CI).
72-
let out = format!(" {}/{}\n", self.test_count + 1, self.total_test_count);
73-
self.write_plain(out)?;
88+
self.write_progress()?;
7489
}
7590

76-
self.test_count += 1;
91+
Ok(())
92+
}
93+
94+
fn write_progress(&mut self) -> io::Result<()> {
95+
let out = format!(" {}/{}\n", self.test_count, self.total_test_count);
96+
self.write_plain(out)?;
97+
self.test_column = 0;
7798
Ok(())
7899
}
79100

@@ -213,7 +234,7 @@ impl<T: Write> OutputFormatter for TerseFormatter<T> {
213234
match *result {
214235
TestResult::TrOk => self.write_ok(),
215236
TestResult::TrFailed | TestResult::TrFailedMsg(_) | TestResult::TrTimedFail => {
216-
self.write_failed()
237+
self.write_failed(desc.name.as_slice())
217238
}
218239
TestResult::TrIgnored => self.write_ignored(),
219240
TestResult::TrBench(ref bs) => {

src/bootstrap/src/utils/render_tests.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl<'a> Renderer<'a> {
166166
println!();
167167
}
168168

169-
fn render_test_outcome_terse(&mut self, outcome: Outcome<'_>, _: &TestOutcome) {
169+
fn render_test_outcome_terse(&mut self, outcome: Outcome<'_>, test: &TestOutcome) {
170170
if self.terse_tests_in_line != 0 && self.terse_tests_in_line % TERSE_TESTS_PER_LINE == 0 {
171171
if let Some(total) = self.tests_count {
172172
let total = total.to_string();
@@ -178,7 +178,7 @@ impl<'a> Renderer<'a> {
178178
}
179179

180180
self.terse_tests_in_line += 1;
181-
self.builder.colored_stdout(|stdout| outcome.write_short(stdout)).unwrap();
181+
self.builder.colored_stdout(|stdout| outcome.write_short(stdout, &test.name)).unwrap();
182182
let _ = std::io::stdout().flush();
183183
}
184184

@@ -300,7 +300,7 @@ enum Outcome<'a> {
300300
}
301301

302302
impl Outcome<'_> {
303-
fn write_short(&self, writer: &mut dyn WriteColor) -> Result<(), std::io::Error> {
303+
fn write_short(&self, writer: &mut dyn WriteColor, name: &str) -> Result<(), std::io::Error> {
304304
match self {
305305
Outcome::Ok => {
306306
writer.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?;
@@ -311,8 +311,11 @@ impl Outcome<'_> {
311311
write!(writer, "b")?;
312312
}
313313
Outcome::Failed => {
314+
// Put failed tests on their own line and include the test name, so that it's faster
315+
// to see which test failed without having to wait for them all to run.
316+
writeln!(writer)?;
314317
writer.set_color(ColorSpec::new().set_fg(Some(Color::Red)))?;
315-
write!(writer, "F")?;
318+
writeln!(writer, "{name} ... F")?;
316319
}
317320
Outcome::Ignored { .. } => {
318321
writer.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?;

tests/ui/test-attrs/terse.rs

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
//@ compile-flags: --test
2+
//@ run-fail
3+
//@ run-flags: --test-threads=1 --quiet
4+
//@ check-run-results
5+
//@ exec-env:RUST_BACKTRACE=0
6+
//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
7+
//@ ignore-emscripten no threads support
8+
//@ needs-unwind
9+
10+
#[test]
11+
fn abc() {
12+
panic!();
13+
}
14+
15+
#[test]
16+
fn foo() {
17+
panic!();
18+
}
19+
20+
#[test]
21+
fn foo2() {
22+
panic!();
23+
}
24+
25+
// run a whole bunch of tests so we can see what happens when we go over 88 columns
26+
#[test] fn f0() {}
27+
#[test] fn f1() {}
28+
#[test] fn f2() {}
29+
#[test] fn f3() {}
30+
#[test] fn f4() {}
31+
#[test] fn f5() {}
32+
#[test] fn f6() {}
33+
#[test] fn f7() {}
34+
#[test] fn f8() {}
35+
#[test] fn f9() {}
36+
#[test] fn f10() {}
37+
#[test] fn f11() {}
38+
#[test] fn f12() {}
39+
#[test] fn f13() {}
40+
#[test] fn f14() {}
41+
#[test] fn f15() {}
42+
#[test] fn f16() {}
43+
#[test] fn f17() {}
44+
#[test] fn f18() {}
45+
#[test] fn f19() {}
46+
#[test] fn f20() {}
47+
#[test] fn f21() {}
48+
#[test] fn f22() {}
49+
#[test] fn f23() {}
50+
#[test] fn f24() {}
51+
#[test] fn f25() {}
52+
#[test] fn f26() {}
53+
#[test] fn f27() {}
54+
#[test] fn f28() {}
55+
#[test] fn f29() {}
56+
#[test] fn f30() {}
57+
#[test] fn f31() {}
58+
#[test] fn f32() {}
59+
#[test] fn f33() {}
60+
#[test] fn f34() {}
61+
#[test] fn f35() {}
62+
#[test] fn f36() {}
63+
#[test] fn f37() {}
64+
#[test] fn f38() {}
65+
#[test] fn f39() {}
66+
#[test] fn f40() {}
67+
#[test] fn f41() {}
68+
#[test] fn f42() {}
69+
#[test] fn f43() {}
70+
#[test] fn f44() {}
71+
#[test] fn f45() {}
72+
#[test] fn f46() {}
73+
#[test] fn f47() {}
74+
#[test] fn f48() {}
75+
#[test] fn f49() {}
76+
#[test] fn f50() {}
77+
#[test] fn f51() {}
78+
#[test] fn f52() {}
79+
#[test] fn f53() {}
80+
#[test] fn f54() {}
81+
#[test] fn f55() {}
82+
#[test] fn f56() {}
83+
#[test] fn f57() {}
84+
#[test] fn f58() {}
85+
#[test] fn f59() {}
86+
#[test] fn f60() {}
87+
#[test] fn f61() {}
88+
#[test] fn f62() {}
89+
#[test] fn f63() {}
90+
#[test] fn f64() {}
91+
#[test] fn f65() {}
92+
#[test] fn f66() {}
93+
#[test] fn f67() {}
94+
#[test] fn f68() {}
95+
#[test] fn f69() {}
96+
#[test] fn f70() {}
97+
#[test] fn f71() {}
98+
#[test] fn f72() {}
99+
#[test] fn f73() {}
100+
#[test] fn f74() {}
101+
#[test] fn f75() {}
102+
#[test] fn f76() {}
103+
#[test] fn f77() {}
104+
#[test] fn f78() {}
105+
#[test] fn f79() {}
106+
#[test] fn f80() {}
107+
#[test] fn f81() {}
108+
#[test] fn f82() {}
109+
#[test] fn f83() {}
110+
#[test] fn f84() {}
111+
#[test] fn f85() {}
112+
#[test] fn f86() {}
113+
#[test] fn f87() {}
114+
#[test] fn f88() {}
115+
#[test] fn f89() {}
116+
#[test] fn f90() {}
117+
#[test] fn f91() {}
118+
#[test] fn f92() {}
119+
#[test] fn f93() {}
120+
#[test] fn f94() {}
121+
#[test] fn f95() {}
122+
#[test] fn f96() {}
123+
#[test] fn f97() {}
124+
#[test] fn f98() {}
125+
#[test] fn f99() {}

tests/ui/test-attrs/terse.run.stdout

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
running 103 tests
3+
abc --- FAILED
4+
....................................................................................... 88/103
5+
............. 101/103
6+
foo --- FAILED
7+
foo2 --- FAILED
8+
9+
failures:
10+
11+
---- abc stdout ----
12+
thread 'abc' panicked at $DIR/terse.rs:12:5:
13+
explicit panic
14+
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
15+
16+
---- foo stdout ----
17+
thread 'foo' panicked at $DIR/terse.rs:17:5:
18+
explicit panic
19+
20+
---- foo2 stdout ----
21+
thread 'foo2' panicked at $DIR/terse.rs:22:5:
22+
explicit panic
23+
24+
25+
failures:
26+
abc
27+
foo
28+
foo2
29+
30+
test result: FAILED. 100 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
31+

0 commit comments

Comments
 (0)