From 30931eeecb047d1729d7c709af4036e20f20c5ea Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 18 Jul 2022 09:02:40 +0000 Subject: [PATCH 1/3] Add a dedicated thread for output printing --- ui_test/src/lib.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/ui_test/src/lib.rs b/ui_test/src/lib.rs index 4318e8a8e0..ee20920e54 100644 --- a/ui_test/src/lib.rs +++ b/ui_test/src/lib.rs @@ -123,11 +123,22 @@ pub fn run_tests(mut config: Config) -> Result<()> { drop(submit); }); + // A channel for the messages emitted by the individual test threads. + let (finish_file, finished_files) = crossbeam::channel::unbounded(); + + s.spawn(|_| { + for msg in finished_files { + eprintln!("{msg}"); + } + }); + let mut threads = vec![]; // Create N worker threads that receive files to test. for _ in 0..std::thread::available_parallelism().unwrap().get() { + let finish_file = finish_file.clone(); threads.push(s.spawn(|_| -> Result<()> { + let finish_file = finish_file; for path in &receive { if !config.path_filter.is_empty() { let path_display = path.display().to_string(); @@ -140,11 +151,12 @@ pub fn run_tests(mut config: Config) -> Result<()> { // Ignore file if only/ignore rules do (not) apply if !test_file_conditions(&comments, &target, &config) { ignored.fetch_add(1, Ordering::Relaxed); - eprintln!( + let msg = format!( "{} ... {}", path.display(), "ignored (in-test comment)".yellow() ); + finish_file.send(msg)?; continue; } // Run the test for all revisions @@ -161,10 +173,10 @@ pub fn run_tests(mut config: Config) -> Result<()> { } write!(msg, "... ").unwrap(); if errors.is_empty() { - eprintln!("{msg}{}", "ok".green()); + write!(msg, "{}", "ok".green()).unwrap(); succeeded.fetch_add(1, Ordering::Relaxed); } else { - eprintln!("{msg}{}", "FAILED".red().bold()); + write!(msg, "{}", "FAILED".red().bold()).unwrap(); failures.lock().unwrap().push(( path.clone(), m, @@ -173,11 +185,13 @@ pub fn run_tests(mut config: Config) -> Result<()> { stderr, )); } + finish_file.send(msg)?; } } Ok(()) })); } + for thread in threads { thread.join().unwrap()?; } From 68041b42fc4a915321c31895f4544e8e70a0c4c8 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 18 Jul 2022 09:19:20 +0000 Subject: [PATCH 2/3] Print one character per test instead of one line --- tests/compiletest.rs | 14 +++++++++++-- ui_test/src/lib.rs | 47 +++++++++++++++++++++++++++++++++----------- ui_test/src/tests.rs | 1 + 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/tests/compiletest.rs b/tests/compiletest.rs index 37b9de7327..72aa140d66 100644 --- a/tests/compiletest.rs +++ b/tests/compiletest.rs @@ -48,8 +48,17 @@ fn run_tests(mode: Mode, path: &str, target: Option) -> Result<()> { (true, true) => panic!("cannot use MIRI_BLESS and MIRI_SKIP_UI_CHECKS at the same time"), }; - // Pass on all arguments as filters. - let path_filter = std::env::args().skip(1); + // Pass on all unknown arguments as filters. + let mut quiet = false; + let path_filter = std::env::args().skip(1).filter(|arg| { + match &**arg { + "--quiet" => { + quiet = true; + false + } + _ => true, + } + }); let use_std = env::var_os("MIRI_NO_STD").is_none(); @@ -76,6 +85,7 @@ fn run_tests(mode: Mode, path: &str, target: Option) -> Result<()> { ], envs: vec![], }), + quiet, }; ui_test::run_tests(config) } diff --git a/ui_test/src/lib.rs b/ui_test/src/lib.rs index ee20920e54..f33f8cd83f 100644 --- a/ui_test/src/lib.rs +++ b/ui_test/src/lib.rs @@ -46,6 +46,8 @@ pub struct Config { /// Can be used to override what command to run instead of `cargo` to build the /// dependencies in `manifest_path` pub dependency_builder: Option, + /// Print one character per test instead of one line + pub quiet: bool, } #[derive(Debug)] @@ -125,10 +127,38 @@ pub fn run_tests(mut config: Config) -> Result<()> { // A channel for the messages emitted by the individual test threads. let (finish_file, finished_files) = crossbeam::channel::unbounded(); + enum TestResult { + Ok, + Failed, + Ignored, + } s.spawn(|_| { - for msg in finished_files { - eprintln!("{msg}"); + if config.quiet { + for (i, (_, result)) in finished_files.into_iter().enumerate() { + // Humans start counting at 1 + let i = i + 1; + match result { + TestResult::Ok => eprint!("{}", ".".green()), + TestResult::Failed => eprint!("{}", "F".red().bold()), + TestResult::Ignored => eprint!("{}", "i".yellow()), + } + if i % 100 == 0 { + eprintln!(" {i}"); + } + } + } else { + for (msg, result) in finished_files { + eprint!("{msg} ... "); + eprintln!( + "{}", + match result { + TestResult::Ok => "ok".green(), + TestResult::Failed => "FAILED".red().bold(), + TestResult::Ignored => "ignored (in-test comment)".yellow(), + } + ); + } } }); @@ -151,12 +181,7 @@ pub fn run_tests(mut config: Config) -> Result<()> { // Ignore file if only/ignore rules do (not) apply if !test_file_conditions(&comments, &target, &config) { ignored.fetch_add(1, Ordering::Relaxed); - let msg = format!( - "{} ... {}", - path.display(), - "ignored (in-test comment)".yellow() - ); - finish_file.send(msg)?; + finish_file.send((path.display().to_string(), TestResult::Ignored))?; continue; } // Run the test for all revisions @@ -171,12 +196,11 @@ pub fn run_tests(mut config: Config) -> Result<()> { if !revision.is_empty() { write!(msg, "(revision `{revision}`) ").unwrap(); } - write!(msg, "... ").unwrap(); if errors.is_empty() { - write!(msg, "{}", "ok".green()).unwrap(); + finish_file.send((msg, TestResult::Ok))?; succeeded.fetch_add(1, Ordering::Relaxed); } else { - write!(msg, "{}", "FAILED".red().bold()).unwrap(); + finish_file.send((msg, TestResult::Failed))?; failures.lock().unwrap().push(( path.clone(), m, @@ -185,7 +209,6 @@ pub fn run_tests(mut config: Config) -> Result<()> { stderr, )); } - finish_file.send(msg)?; } } Ok(()) diff --git a/ui_test/src/tests.rs b/ui_test/src/tests.rs index 8b0bd517a1..2032988ed3 100644 --- a/ui_test/src/tests.rs +++ b/ui_test/src/tests.rs @@ -18,6 +18,7 @@ fn config() -> Config { output_conflict_handling: OutputConflictHandling::Error, dependencies_crate_manifest_path: None, dependency_builder: None, + quiet: false, } } From ecacc56843ae0bd1ba264a9abf95c31ee66a9f8b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Jul 2022 07:39:54 +0000 Subject: [PATCH 3/3] Use names suggestive of channel endpoints --- ui_test/src/lib.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ui_test/src/lib.rs b/ui_test/src/lib.rs index f33f8cd83f..06a84cfbf3 100644 --- a/ui_test/src/lib.rs +++ b/ui_test/src/lib.rs @@ -126,7 +126,7 @@ pub fn run_tests(mut config: Config) -> Result<()> { }); // A channel for the messages emitted by the individual test threads. - let (finish_file, finished_files) = crossbeam::channel::unbounded(); + let (finished_files_sender, finished_files_recv) = crossbeam::channel::unbounded(); enum TestResult { Ok, Failed, @@ -135,7 +135,7 @@ pub fn run_tests(mut config: Config) -> Result<()> { s.spawn(|_| { if config.quiet { - for (i, (_, result)) in finished_files.into_iter().enumerate() { + for (i, (_, result)) in finished_files_recv.into_iter().enumerate() { // Humans start counting at 1 let i = i + 1; match result { @@ -148,7 +148,7 @@ pub fn run_tests(mut config: Config) -> Result<()> { } } } else { - for (msg, result) in finished_files { + for (msg, result) in finished_files_recv { eprint!("{msg} ... "); eprintln!( "{}", @@ -166,9 +166,9 @@ pub fn run_tests(mut config: Config) -> Result<()> { // Create N worker threads that receive files to test. for _ in 0..std::thread::available_parallelism().unwrap().get() { - let finish_file = finish_file.clone(); + let finished_files_sender = finished_files_sender.clone(); threads.push(s.spawn(|_| -> Result<()> { - let finish_file = finish_file; + let finished_files_sender = finished_files_sender; for path in &receive { if !config.path_filter.is_empty() { let path_display = path.display().to_string(); @@ -181,7 +181,8 @@ pub fn run_tests(mut config: Config) -> Result<()> { // Ignore file if only/ignore rules do (not) apply if !test_file_conditions(&comments, &target, &config) { ignored.fetch_add(1, Ordering::Relaxed); - finish_file.send((path.display().to_string(), TestResult::Ignored))?; + finished_files_sender + .send((path.display().to_string(), TestResult::Ignored))?; continue; } // Run the test for all revisions @@ -197,10 +198,10 @@ pub fn run_tests(mut config: Config) -> Result<()> { write!(msg, "(revision `{revision}`) ").unwrap(); } if errors.is_empty() { - finish_file.send((msg, TestResult::Ok))?; + finished_files_sender.send((msg, TestResult::Ok))?; succeeded.fetch_add(1, Ordering::Relaxed); } else { - finish_file.send((msg, TestResult::Failed))?; + finished_files_sender.send((msg, TestResult::Failed))?; failures.lock().unwrap().push(( path.clone(), m,