From db13110f33b65976f19548f22ffd8571463bd52c Mon Sep 17 00:00:00 2001 From: Barsik Date: Fri, 23 Feb 2024 16:24:57 +0200 Subject: [PATCH] Update error handling in test runner The error handling mechanism of the test runner has been improved. Errors now return both the TestReport and the Error, allowing higher-level functions to access both. Adjustments have been made in related code to accommodate this change. --- module/move/willbe/src/command/run_tests.rs | 9 +++--- module/move/willbe/src/endpoint/run_tests.rs | 29 ++++++++++++------- module/move/willbe/tests/inc/commands/mod.rs | 2 +- .../willbe/tests/inc/endpoints/tests_run.rs | 6 ++-- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/module/move/willbe/src/command/run_tests.rs b/module/move/willbe/src/command/run_tests.rs index c044c3bf83..3d02298619 100644 --- a/module/move/willbe/src/command/run_tests.rs +++ b/module/move/willbe/src/command/run_tests.rs @@ -56,14 +56,15 @@ mod private Ok( report ) => { println!( "{report} "); + + Ok( () ) } - Err( e ) => + Err( ( report, e ) ) => { - return Err( e.context( "package test command" ) ); + eprintln!( "{report}" ); + Err( e.context( "package test command" ) ) } } - - Ok(()) } impl TryFrom< Props > for RunTestsProperties diff --git a/module/move/willbe/src/endpoint/run_tests.rs b/module/move/willbe/src/endpoint/run_tests.rs index 22791e329f..2bfc1600f5 100644 --- a/module/move/willbe/src/endpoint/run_tests.rs +++ b/module/move/willbe/src/endpoint/run_tests.rs @@ -11,11 +11,11 @@ mod private }; use rayon::ThreadPoolBuilder; - use former::Former; + use former::Former; use wtools:: { iter::Itertools, - error::{ Result, for_app::format_err }, + error::{ Result, for_app::{ format_err, Error } }, }; use process::CmdReport; @@ -86,28 +86,33 @@ mod private exclude_features : Vec< String >, } - /// The function runs tests with a different set of features in the selected crate (the path to the crate is specified in the dir variable). + /// The function runs tests with a different set of features in the selected crate (the path to the crate is specified in the dir variable). /// Tests are run with each feature separately, with all features together, and without any features. /// The tests are run in nightly and stable versions of Rust. /// It is possible to enable and disable various features of the crate. /// The function also has the ability to run tests in parallel using `Rayon` crate. /// The result of the tests is written to the structure `TestReport` and returned as a result of the function execution. - pub fn run_tests( args : TestsArgs ) -> Result< TestReport > + pub fn run_tests( args : TestsArgs ) -> Result< TestReport, ( TestReport, Error ) > { + let report = TestReport::default(); // fail fast if some additional installations required - let channels = cargo::available_channels( args.dir.as_ref() )?; + let channels = cargo::available_channels( args.dir.as_ref() ).map_err( | e | ( report.clone(), e ) )?; let channels_diff = args.channels.difference( &channels ).collect::< Vec< _ > >(); if !channels_diff.is_empty() { - return Err( format_err!( "Missing toolchain(-s) that was required: [{}]. Try to install it with `rustup install {{toolchain name}}` command(-s)", channels_diff.into_iter().join( ", " ) ) ) + return Err(( report, format_err!( "Missing toolchain(-s) that was required: [{}]. Try to install it with `rustup install {{toolchain name}}` command(-s)", channels_diff.into_iter().join( ", " ) ) )) } - let report = Arc::new( Mutex::new( TestReport::default() ) ); + let report = Arc::new( Mutex::new( report ) ); let path = args.dir.absolute_path().join("Cargo.toml"); - let metadata = Workspace::with_crate_dir( args.dir.clone() )?; + let metadata = Workspace::with_crate_dir( args.dir.clone() ).map_err( | e | ( report.lock().unwrap().clone(), e ) )?; - let package = metadata.packages_get()?.into_iter().find( |x| x.manifest_path == path.as_ref() ).ok_or( format_err!( "Package not found" ) )?; + let package = metadata + .packages_get() + .map_err( | e | ( report.lock().unwrap().clone(), format_err!( e ) ) )? + .into_iter() + .find( |x| x.manifest_path == path.as_ref() ).ok_or(( report.lock().unwrap().clone(), format_err!( "Package not found" ) ) )?; report.lock().unwrap().package_name = package.name.clone(); let exclude = args.exclude_features.iter().cloned().collect(); @@ -146,7 +151,9 @@ mod private // unpack. all tasks must be completed until now let report = Mutex::into_inner( Arc::into_inner( report ).unwrap() ).unwrap(); - Ok( report ) + let at_least_one_failed = report.tests.iter().flat_map( |( _, v )| v.iter().map( |( _, v)| v ) ).any( | r | r.out.contains( "failures" ) || r.err.contains( "error" ) ); + if at_least_one_failed { Err(( report, format_err!( "Some tests was failed" ) )) } + else { Ok( report ) } } } @@ -156,4 +163,4 @@ crate::mod_interface! prelude use run_tests; protected use TestsArgs; protected use TestReport; -} \ No newline at end of file +} diff --git a/module/move/willbe/tests/inc/commands/mod.rs b/module/move/willbe/tests/inc/commands/mod.rs index 45091e1aa4..f2a3ced109 100644 --- a/module/move/willbe/tests/inc/commands/mod.rs +++ b/module/move/willbe/tests/inc/commands/mod.rs @@ -1,3 +1,3 @@ pub const BINARY_NAME: &'static str = "will"; -mod tests_run; \ No newline at end of file +mod tests_run; diff --git a/module/move/willbe/tests/inc/endpoints/tests_run.rs b/module/move/willbe/tests/inc/endpoints/tests_run.rs index 7269a4e8db..57f51ae53a 100644 --- a/module/move/willbe/tests/inc/endpoints/tests_run.rs +++ b/module/move/willbe/tests/inc/endpoints/tests_run.rs @@ -32,13 +32,13 @@ fn fail_test() .channels([ cargo::Channel::Stable ]) .form(); - let rep: TestReport = run_tests( args ).unwrap_err().downcast().unwrap(); + let rep : TestReport = run_tests( args ).unwrap_err().0; println!( "========= OUTPUT =========\n{}\n==========================", rep ); let stable = rep.tests.get( &cargo::Channel::Stable ).unwrap(); let no_features = stable.get( "" ).unwrap(); - assert!( no_features.err.contains( "failures" ) ); + assert!( no_features.out.contains( "failures" ) ); } #[ test ] @@ -66,7 +66,7 @@ fn fail_build() .channels([ cargo::Channel::Stable ]) .form(); - let rep: TestReport = run_tests( args ).unwrap_err().downcast().unwrap(); + let rep: TestReport = run_tests( args ).unwrap_err().0; println!( "========= OUTPUT =========\n{}\n==========================", rep ); let stable = rep.tests.get( &cargo::Channel::Stable ).unwrap();