Skip to content

Commit

Permalink
Add 'dry run' mode to test endpoint
Browse files Browse the repository at this point in the history
This update introduces a 'dry run' mode to the test endpoint, allowing users to simulate the execution of tests without actually running them. The 'dry' boolean flag has been added to the 'TestReport' struct, and its value can be adjusted to enable or disable this mode. Adjustments have also been made to the test display output to enhance clarity.
  • Loading branch information
Barsik-sus committed Feb 26, 2024
1 parent 2e2f35a commit c261d7b
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 19 deletions.
1 change: 1 addition & 0 deletions module/move/willbe/src/command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub( crate ) mod private
.long_hint( "this command runs tests in designated packages based on the provided path. It allows for inclusion and exclusion of features, testing on different Rust version channels, parallel execution, and feature combination settings." )
.phrase( "test" )
.subject( "A path to directories with packages. If no path is provided, the current directory is used.", Type::Path, true )
.property( "dry", "Enables 'dry run'. Does not run tests, only simulates. Default is `true`.", Type::Bool, true )
.property( "include", "A list of features to include in testing. Separate multiple features by comma.", Type::List( Type::String.into(), ',' ), true )
.property( "exclude", "A list of features to exclude from testing. Separate multiple features by comma.", Type::List( Type::String.into(), ',' ), true )
.property( "with_stable", "Specifies whether or not to run tests on stable Rust version. Default is `true`", Type::Bool, true )
Expand Down
7 changes: 5 additions & 2 deletions module/move/willbe/src/command/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ mod private
#[ derive( Former ) ]
struct TestsProperties
{
#[ default( true ) ]
dry : bool,
#[ default( true ) ]
with_stable : bool,
#[ default( true ) ]
Expand All @@ -34,7 +36,7 @@ mod private
{
let path : PathBuf = args.get_owned( 0 ).unwrap_or_else( || "./".into() );
let path = AbsolutePath::try_from( path )?;
let TestsProperties { with_stable, with_nightly, parallel, power, include, exclude } = properties.try_into()?;
let TestsProperties { dry, with_stable, with_nightly, parallel, power, include, exclude } = properties.try_into()?;

let crate_dir = CrateDir::try_from( path )?;

Expand All @@ -51,7 +53,7 @@ mod private
.include_features( include )
.form();

match endpoint::test( args )
match endpoint::test( args, dry )
{
Ok( report ) =>
{
Expand All @@ -74,6 +76,7 @@ mod private
{
let mut this = Self::former();

this = if let Some( v ) = value.get_owned( "dry" ) { this.dry::< bool >( v ) } else { this };
this = if let Some( v ) = value.get_owned( "with_stable" ) { this.with_stable::< bool >( v ) } else { this };
this = if let Some( v ) = value.get_owned( "with_nightly" ) { this.with_nightly::< bool >( v ) } else { this };
this = if let Some( v ) = value.get_owned( "parallel" ) { this.parallel::< bool >( v ) } else { this };
Expand Down
61 changes: 44 additions & 17 deletions module/move/willbe/src/endpoint/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ mod private
#[ derive( Debug, Default, Clone ) ]
pub struct TestReport
{
/// A boolean flag indicating whether or not the code is being run in dry mode.
///
/// Dry mode is a mode in which the code performs a dry run, simulating the execution
/// of certain tasks without actually making any changes. When the `dry` flag is set to
/// `true`, the code will not perform any actual actions, but instead only output the
/// results it would have produced.
///
/// This flag can be useful for testing and debugging purposes, as well as for situations
/// where it is important to verify the correctness of the actions being performed before
/// actually executing them.
pub dry : bool,
/// A string containing the name of the package being tested.
pub package_name : String,
/// A `BTreeMap` where the keys are `cargo::Channel` enums representing the channels
Expand All @@ -36,29 +47,42 @@ mod private
{
fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result
{
f.write_fmt( format_args!( "Package: [ {} ]:\n", self.package_name ) )?;
writeln!( f, "The tests will be executed using the following configurations:" )?;
for ( channel, feature ) in self.tests.iter().flat_map( | ( c, f ) | f.iter().map ( |( f, _ )| ( *c, f ) ) )
{
writeln!( f, "channel: {channel} | feature(-s): [{}]", if feature.is_empty() { "no-features" } else { feature } )?;
}
writeln!( f, "\nPackage: [ {} ]:", self.package_name )?;
if self.tests.is_empty()
{
f.write_fmt( format_args!( "unlucky" ) )?;
f.write_fmt( format_args!( "unlucky" ) )?;
return Ok( () );
}

for ( channel, features ) in &self.tests
{
for (feature, result) in features
{
// if tests failed or if build failed
let failed = result.out.contains( "failures" ) || result.err.contains( "error" );
if !failed
{
let feature = if feature.is_empty() { "no-features" } else { feature };
f.write_fmt(format_args!(" [ {} | {} ]: {}\n", channel, feature, if failed { "❌ failed" } else { "✅ successful" } ) )?;
}
else
{
let feature = if feature.is_empty() { "no-features" } else { feature };
f.write_fmt( format_args!( " Feature: [ {} | {} ]:\n Tests status: {}\n{}\n{}", channel, feature, if failed { "❌ failed" } else { "✅ successful" }, result.out, result.err ) )?;
}
if self.dry
{
let feature = if feature.is_empty() { "no-features" } else { feature };
writeln!( f, "[{channel} | {feature}]: `{}`", result.command )?
}
else
{
// if tests failed or if build failed
let failed = result.out.contains( "failures" ) || result.err.contains( "error" );
if !failed
{
let feature = if feature.is_empty() { "no-features" } else { feature };
writeln!( f, " [ {} | {} ]: {}", channel, feature, if failed { "❌ failed" } else { "✅ successful" } )?;
}
else
{
let feature = if feature.is_empty() { "no-features" } else { feature };
write!( f, " Feature: [ {} | {} ]:\n Tests status: {}\n{}\n{}", channel, feature, if failed { "❌ failed" } else { "✅ successful" }, result.out, result.err )?;
}
}
}
}

Expand Down Expand Up @@ -92,7 +116,7 @@ mod private
/// 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 test( args : TestsArgs ) -> Result< TestReport, ( TestReport, Error ) >
pub fn test( args : TestsArgs, dry : bool ) -> Result< TestReport, ( TestReport, Error ) >
{
let report = TestReport::default();
// fail fast if some additional installations required
Expand All @@ -104,8 +128,11 @@ mod private
}

let report = Arc::new( Mutex::new( report ) );
{
report.lock().unwrap().dry = dry;
}

let path = args.dir.absolute_path().join("Cargo.toml");
let path = args.dir.absolute_path().join( "Cargo.toml" );
let metadata = Workspace::with_crate_dir( args.dir.clone() ).map_err( | e | ( report.lock().unwrap().clone(), e ) )?;

let package = metadata
Expand Down Expand Up @@ -141,7 +168,7 @@ mod private
let r = report.clone();
s.spawn( move | _ |
{
let cmd_rep = cargo::test( dir, cargo::TestArgs::former().channel( channel ).with_default_features( false ).enable_features( feature.clone() ).form(), false ).unwrap_or_else( | rep | rep.downcast().unwrap() );
let cmd_rep = cargo::test( dir, cargo::TestArgs::former().channel( channel ).with_default_features( false ).enable_features( feature.clone() ).form(), dry ).unwrap_or_else( | rep | rep.downcast().unwrap() );
r.lock().unwrap().tests.entry( channel ).or_default().insert( feature.iter().join( "," ), cmd_rep );
});
}
Expand Down

0 comments on commit c261d7b

Please sign in to comment.