Skip to content

Commit cdabcbd

Browse files
committed
Rework the whole progress rendering scheme to be more robust
1 parent 8d4b5e8 commit cdabcbd

File tree

3 files changed

+239
-144
lines changed

3 files changed

+239
-144
lines changed

src/lib.rs

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ pub use filter::Match;
2222
use per_test_config::TestConfig;
2323
use spanned::Spanned;
2424
use status_emitter::RevisionStyle;
25+
use status_emitter::SilentStatus;
2526
use status_emitter::{StatusEmitter, TestStatus};
2627
use std::collections::VecDeque;
28+
use std::panic::AssertUnwindSafe;
2729
use std::path::Path;
2830
#[cfg(feature = "rustc")]
2931
use std::process::Command;
@@ -230,25 +232,26 @@ pub fn run_tests_generic(
230232
}
231233
} else if let Some(matched) = file_filter(&path, build_manager.config()) {
232234
if matched {
233-
let status = status_emitter.register_test(path);
235+
let status = status_emitter.register_test(path.clone());
234236
// Forward .rs files to the test workers.
235237
submit
236238
.send(Box::new(move |finished_files_sender: &Sender<TestRun>| {
237-
let path = status.path();
238-
let file_contents = Spanned::read_from_file(path).unwrap();
239+
let file_contents = Spanned::read_from_file(&path).unwrap();
239240
let mut config = build_manager.config().clone();
240241
let abort_check = config.abort_check.clone();
241242
per_file_config(&mut config, &file_contents);
243+
let status = AssertUnwindSafe(status);
242244
let result = match std::panic::catch_unwind(|| {
245+
let status = status;
243246
parse_and_test_file(
244247
build_manager,
245-
&status,
248+
status.0,
246249
config,
247250
file_contents,
248251
)
249252
}) {
250253
Ok(Ok(res)) => res,
251-
Ok(Err(err)) => {
254+
Ok(Err((status, err))) => {
252255
finished_files_sender.send(TestRun {
253256
result: Err(err),
254257
status,
@@ -271,7 +274,10 @@ pub fn run_tests_generic(
271274
stderr: vec![],
272275
stdout: vec![],
273276
}),
274-
status,
277+
status: Box::new(SilentStatus {
278+
revision: String::new(),
279+
path,
280+
}),
275281
abort_check,
276282
})?;
277283
return Ok(());
@@ -360,44 +366,65 @@ pub fn run_tests_generic(
360366

361367
fn parse_and_test_file(
362368
build_manager: Arc<BuildManager>,
363-
status: &dyn TestStatus,
369+
status: Box<dyn TestStatus>,
364370
config: Config,
365371
file_contents: Spanned<Vec<u8>>,
366-
) -> Result<Vec<TestRun>, Errored> {
367-
let comments = Comments::parse(file_contents.as_ref(), &config)
368-
.map_err(|errors| Errored::new(errors, "parse comments"))?;
372+
) -> Result<Vec<TestRun>, (Box<dyn TestStatus>, Errored)> {
373+
let comments = match Comments::parse(file_contents.as_ref(), &config) {
374+
Ok(t) => t,
375+
Err(errors) => return Err((status, Errored::new(errors, "parse comments"))),
376+
};
369377
let comments = Arc::new(comments);
370-
const EMPTY: &[String] = &[String::new()];
371378
// Run the test for all revisions
372-
let revisions = comments.revisions.as_deref().unwrap_or(EMPTY);
373379
let mut runs = vec![];
374-
for revision in revisions {
375-
let status = status.for_revision(revision, RevisionStyle::Show);
376-
// Ignore file if only/ignore rules do (not) apply
377-
if !config.test_file_conditions(&comments, revision) {
378-
runs.push(TestRun {
379-
result: Ok(TestOk::Ignored),
380-
status,
381-
abort_check: config.abort_check.clone(),
382-
});
383-
continue;
380+
for i in 0.. {
381+
match comments.revisions.as_deref() {
382+
Some(revisions) => {
383+
let Some(revision) = revisions.get(i) else {
384+
status.done(&Ok(TestOk::Ok), build_manager.aborted());
385+
break;
386+
};
387+
let status = status.for_revision(revision, RevisionStyle::Show);
388+
test_file(&config, &comments, status, &mut runs, &build_manager)
389+
}
390+
None => {
391+
test_file(&config, &comments, status, &mut runs, &build_manager);
392+
break;
393+
}
384394
}
395+
}
396+
Ok(runs)
397+
}
385398

386-
let mut test_config = TestConfig {
387-
config: config.clone(),
388-
comments: comments.clone(),
389-
aux_dir: status.path().parent().unwrap().join("auxiliary"),
390-
status,
391-
};
392-
393-
let result = test_config.run_test(&build_manager);
399+
fn test_file(
400+
config: &Config,
401+
comments: &Arc<Comments>,
402+
status: Box<dyn TestStatus>,
403+
runs: &mut Vec<TestRun>,
404+
build_manager: &Arc<BuildManager>,
405+
) {
406+
if !config.test_file_conditions(comments, status.revision()) {
394407
runs.push(TestRun {
395-
result,
396-
status: test_config.status,
397-
abort_check: test_config.config.abort_check,
398-
})
408+
result: Ok(TestOk::Ignored),
409+
status,
410+
abort_check: config.abort_check.clone(),
411+
});
412+
return;
399413
}
400-
Ok(runs)
414+
let mut test_config = TestConfig {
415+
config: config.clone(),
416+
comments: comments.clone(),
417+
aux_dir: status.path().parent().unwrap().join("auxiliary"),
418+
status,
419+
};
420+
let result = test_config.run_test(build_manager);
421+
// Ignore file if only/ignore rules do (not) apply
422+
423+
runs.push(TestRun {
424+
result,
425+
status: test_config.status,
426+
abort_check: test_config.config.abort_check,
427+
});
401428
}
402429

403430
fn display(path: &Path) -> String {

0 commit comments

Comments
 (0)