@@ -10,6 +10,7 @@ use std::io::{BufRead, BufReader, Read, Write};
10
10
use std:: process:: { ChildStdout , Stdio } ;
11
11
use std:: time:: Duration ;
12
12
13
+ use build_helper:: ci:: CiEnv ;
13
14
use termcolor:: { Color , ColorSpec , WriteColor } ;
14
15
15
16
use crate :: core:: builder:: Builder ;
@@ -91,7 +92,9 @@ struct Renderer<'a> {
91
92
/// Number of tests that were skipped due to already being up-to-date
92
93
/// (i.e. no relevant changes occurred since they last ran).
93
94
up_to_date_tests : usize ,
95
+ ignored_tests : usize ,
94
96
terse_tests_in_line : usize ,
97
+ ci_latest_logged_percentage : f64 ,
95
98
}
96
99
97
100
impl < ' a > Renderer < ' a > {
@@ -104,7 +107,9 @@ impl<'a> Renderer<'a> {
104
107
tests_count : None ,
105
108
executed_tests : 0 ,
106
109
up_to_date_tests : 0 ,
110
+ ignored_tests : 0 ,
107
111
terse_tests_in_line : 0 ,
112
+ ci_latest_logged_percentage : 0.0 ,
108
113
}
109
114
}
110
115
@@ -160,8 +165,11 @@ impl<'a> Renderer<'a> {
160
165
self . executed_tests += 1 ;
161
166
162
167
// Keep this in sync with the "up-to-date" ignore message inserted by compiletest.
163
- if let Outcome :: Ignored { reason : Some ( "up-to-date" ) } = outcome {
164
- self . up_to_date_tests += 1 ;
168
+ if let Outcome :: Ignored { reason } = outcome {
169
+ self . ignored_tests += 1 ;
170
+ if reason == Some ( "up-to-date" ) {
171
+ self . up_to_date_tests += 1 ;
172
+ }
165
173
}
166
174
167
175
#[ cfg( feature = "build-metrics" ) ]
@@ -180,7 +188,11 @@ impl<'a> Renderer<'a> {
180
188
if self . builder . config . verbose_tests {
181
189
self . render_test_outcome_verbose ( outcome, test) ;
182
190
} else {
183
- self . render_test_outcome_terse ( outcome, test) ;
191
+ if CiEnv :: is_ci ( ) {
192
+ self . render_test_outcome_ci ( outcome, test) ;
193
+ } else {
194
+ self . render_test_outcome_terse ( outcome, test) ;
195
+ }
184
196
}
185
197
}
186
198
@@ -209,6 +221,31 @@ impl<'a> Renderer<'a> {
209
221
let _ = std:: io:: stdout ( ) . flush ( ) ;
210
222
}
211
223
224
+ fn render_test_outcome_ci ( & mut self , outcome : Outcome < ' _ > , test : & TestOutcome ) {
225
+ if let Some ( total) = self . tests_count {
226
+ let percent = self . executed_tests as f64 / total as f64 ;
227
+
228
+ if self . ci_latest_logged_percentage + 0.10 < percent {
229
+ let total = total. to_string ( ) ;
230
+ let executed = format ! ( "{:>width$}" , self . executed_tests - 1 , width = total. len( ) ) ;
231
+ let pretty_percent = format ! ( "{:.0}%" , percent * 100.0 ) ;
232
+ let passed_tests = self . executed_tests - self . failures . len ( ) ;
233
+ println ! (
234
+ "{:<4} -- {executed}/{total}, {:>total_indent$} passed, {} failed, {} ignored" ,
235
+ pretty_percent,
236
+ passed_tests,
237
+ self . failures. len( ) ,
238
+ self . ignored_tests,
239
+ total_indent = total. len( )
240
+ ) ;
241
+ self . ci_latest_logged_percentage += 0.10 ;
242
+ }
243
+ }
244
+
245
+ self . builder . colored_stdout ( |stdout| outcome. write_ci ( stdout, & test. name ) ) . unwrap ( ) ;
246
+ let _ = std:: io:: stdout ( ) . flush ( ) ;
247
+ }
248
+
212
249
fn render_suite_outcome ( & self , outcome : Outcome < ' _ > , suite : & SuiteOutcome ) {
213
250
// The terse output doesn't end with a newline, so we need to add it ourselves.
214
251
if !self . builder . config . verbose_tests {
@@ -378,6 +415,17 @@ impl Outcome<'_> {
378
415
}
379
416
writer. reset ( )
380
417
}
418
+
419
+ fn write_ci ( & self , writer : & mut dyn WriteColor , name : & str ) -> Result < ( ) , std:: io:: Error > {
420
+ match self {
421
+ Outcome :: Ok | Outcome :: BenchOk | Outcome :: Ignored { .. } => { }
422
+ Outcome :: Failed => {
423
+ writer. set_color ( ColorSpec :: new ( ) . set_fg ( Some ( Color :: Red ) ) ) ?;
424
+ writeln ! ( writer, " {name} ... FAILED" ) ?;
425
+ }
426
+ }
427
+ writer. reset ( )
428
+ }
381
429
}
382
430
383
431
#[ derive( serde_derive:: Deserialize ) ]
0 commit comments