diff --git a/crates/forge-runner/src/messages.rs b/crates/forge-runner/src/messages.rs index 37eeced090..0f6f9e70c9 100644 --- a/crates/forge-runner/src/messages.rs +++ b/crates/forge-runner/src/messages.rs @@ -13,6 +13,7 @@ enum TestResultStatus { Failed, Ignored, Interrupted, + ExcludedFromPartition, } impl From<&AnyTestCaseSummary> for TestResultStatus { @@ -26,6 +27,10 @@ impl From<&AnyTestCaseSummary> for TestResultStatus { | AnyTestCaseSummary::Fuzzing(TestCaseSummary::Ignored { .. }) => Self::Ignored, AnyTestCaseSummary::Single(TestCaseSummary::Interrupted { .. }) | AnyTestCaseSummary::Fuzzing(TestCaseSummary::Interrupted { .. }) => Self::Interrupted, + AnyTestCaseSummary::Single(TestCaseSummary::ExcludedFromPartition { .. }) + | AnyTestCaseSummary::Fuzzing(TestCaseSummary::ExcludedFromPartition { .. }) => { + Self::ExcludedFromPartition + } } } } @@ -110,7 +115,9 @@ impl TestResultMessage { match self.status { TestResultStatus::Passed => return format!("\n\n{msg}"), TestResultStatus::Failed => return format!("\n\nFailure data:{msg}"), - TestResultStatus::Ignored | TestResultStatus::Interrupted => return String::new(), + TestResultStatus::Ignored + | TestResultStatus::Interrupted + | TestResultStatus::ExcludedFromPartition => return String::new(), } } String::new() @@ -124,6 +131,11 @@ impl TestResultMessage { TestResultStatus::Interrupted => { unreachable!("Interrupted tests should not have visible message representation") } + TestResultStatus::ExcludedFromPartition => { + unreachable!( + "Tests excluded from partition should not have visible message representation" + ) + } } } } diff --git a/crates/forge-runner/src/package_tests/with_config_resolved.rs b/crates/forge-runner/src/package_tests/with_config_resolved.rs index 11597441ff..3e850c84d5 100644 --- a/crates/forge-runner/src/package_tests/with_config_resolved.rs +++ b/crates/forge-runner/src/package_tests/with_config_resolved.rs @@ -13,7 +13,8 @@ pub type TestTargetWithResolvedConfig = TestTarget; pub type TestCaseWithResolvedConfig = TestCase; -fn sanitize_test_case_name(name: &str) -> String { +#[must_use] +pub fn sanitize_test_case_name(name: &str) -> String { // Test names generated by `#[test]` and `#[fuzzer]` macros contain internal suffixes name.replace("__snforge_internal_test_generated", "") .replace("__snforge_internal_fuzzer_generated", "") diff --git a/crates/forge-runner/src/test_case_summary.rs b/crates/forge-runner/src/test_case_summary.rs index 980b884982..dac9f2dfb7 100644 --- a/crates/forge-runner/src/test_case_summary.rs +++ b/crates/forge-runner/src/test_case_summary.rs @@ -128,6 +128,8 @@ pub enum TestCaseSummary { }, /// Test case skipped due to exit first or execution interrupted, test result is ignored. Interrupted {}, + /// Test case excluded from current partition + ExcludedFromPartition {}, } #[derive(Debug)] @@ -145,7 +147,9 @@ impl TestCaseSummary { TestCaseSummary::Failed { name, .. } | TestCaseSummary::Passed { name, .. } | TestCaseSummary::Ignored { name, .. } => Some(name), - TestCaseSummary::Interrupted { .. } => None, + TestCaseSummary::Interrupted { .. } | TestCaseSummary::ExcludedFromPartition { .. } => { + None + } } } @@ -227,6 +231,7 @@ impl TestCaseSummary { }, TestCaseSummary::Ignored { name } => TestCaseSummary::Ignored { name: name.clone() }, TestCaseSummary::Interrupted {} => TestCaseSummary::Interrupted {}, + TestCaseSummary::ExcludedFromPartition {} => TestCaseSummary::ExcludedFromPartition {}, } } } @@ -454,6 +459,15 @@ impl AnyTestCaseSummary { | AnyTestCaseSummary::Fuzzing(TestCaseSummary::Ignored { .. }) ) } + + #[must_use] + pub fn is_excluded_from_partition(&self) -> bool { + matches!( + self, + AnyTestCaseSummary::Single(TestCaseSummary::ExcludedFromPartition { .. }) + | AnyTestCaseSummary::Fuzzing(TestCaseSummary::ExcludedFromPartition { .. }) + ) + } } #[cfg(test)] diff --git a/crates/forge/src/partition.rs b/crates/forge/src/partition.rs index 7a549e818a..4e948bfee0 100644 --- a/crates/forge/src/partition.rs +++ b/crates/forge/src/partition.rs @@ -1,13 +1,16 @@ +use cairo_lang_sierra::ids::FunctionId; +use forge_runner::package_tests::with_config_resolved::sanitize_test_case_name; use serde::Serialize; use std::{collections::HashMap, str::FromStr}; +use crate::run_tests::package::RunForPackageArgs; + #[derive(Debug, Clone, Copy, Serialize)] pub struct Partition { index: usize, total: usize, } -#[allow(dead_code)] // TODO: Removed in later PRs impl Partition { #[must_use] pub fn index(&self) -> usize { @@ -49,15 +52,57 @@ impl FromStr for Partition { #[derive(Serialize)] pub struct TestPartitionMap(HashMap); +impl TestPartitionMap { + pub fn get(&self, test_name: &str) -> Option<&usize> { + self.0.get(test_name) + } + + pub fn insert(&mut self, test_name: String, partition_index: usize) { + self.0.insert(test_name, partition_index); + } + + pub fn from_packages_args(packages_args: &[RunForPackageArgs], partition: Partition) -> Self { + let mut full_paths: Vec = packages_args + .iter() + .flat_map(|pkg| pkg.test_targets.iter()) + .flat_map(|tt| { + tt.sierra_program + .debug_info + .as_ref() + .and_then(|info| info.executables.get("snforge_internal_test_executable")) + .into_iter() + .flatten() + }) + .filter_map(|fid: &FunctionId| { + fid.debug_name + .as_ref() + .map(std::string::ToString::to_string) + }) + .collect(); + + full_paths.sort(); + + let total = partition.total(); + let mut mapping = HashMap::with_capacity(full_paths.len()); + + for (i, path) in full_paths.into_iter().enumerate() { + let partition_index_1_based = (i % total) + 1; + mapping.insert(sanitize_test_case_name(&path), partition_index_1_based); + } + + Self(mapping) + } +} + #[derive(Serialize)] pub struct PartitionConfig { partition: Partition, test_partition_map: TestPartitionMap, } -#[allow(dead_code)] // TODO: Removed in later PRs impl PartitionConfig { - pub fn new(partition: Partition, test_partition_map: TestPartitionMap) -> Self { + pub fn new(partition: Partition, packages_args: &[RunForPackageArgs]) -> Self { + let test_partition_map = TestPartitionMap::from_packages_args(packages_args, partition); Self { partition, test_partition_map, diff --git a/crates/forge/src/run_tests/package.rs b/crates/forge/src/run_tests/package.rs index dbf05e5962..f1b3dbf3ff 100644 --- a/crates/forge/src/run_tests/package.rs +++ b/crates/forge/src/run_tests/package.rs @@ -6,6 +6,7 @@ use crate::{ TestArgs, block_number_map::BlockNumberMap, combine_configs::combine_configs, + partition::PartitionConfig, run_tests::messages::{ collected_tests_count::CollectedTestsCountMessage, tests_run::TestsRunMessage, tests_summary::TestsSummaryMessage, @@ -28,7 +29,11 @@ use configuration::load_package_config; use console::Style; use forge_runner::{ forge_config::ForgeConfig, - package_tests::{raw::TestTargetRaw, with_config_resolved::TestTargetWithResolvedConfig}, + package_tests::{ + TestCase, TestTarget, + raw::TestTargetRaw, + with_config_resolved::{TestCaseResolvedConfig, TestTargetWithResolvedConfig}, + }, running::with_config::test_target_with_config, test_case_summary::AnyTestCaseSummary, test_target_summary::TestTargetSummary, @@ -163,8 +168,34 @@ async fn test_package_with_config_resolved( Ok(test_targets_with_resolved_config) } -fn sum_test_cases(test_targets: &[TestTargetWithResolvedConfig]) -> usize { - test_targets.iter().map(|tc| tc.test_cases.len()).sum() +fn sum_test_cases_from_package( + test_targets: &[TestTarget], + partition_config: Option<&PartitionConfig>, +) -> usize { + test_targets + .iter() + .map(|tt| sum_test_cases_from_test_target(tt.test_cases.clone(), partition_config)) + .sum() +} + +fn sum_test_cases_from_test_target( + test_cases: Vec>, + partition_config: Option<&PartitionConfig>, +) -> usize { + if let Some(partition_config) = partition_config { + test_cases + .into_iter() + .filter(|test_case| { + partition_config.partition().index() + == *partition_config + .test_partition_map() + .get(&test_case.name) + .expect("Test case name not found in partitions mapping") + }) + .count() + } else { + test_cases.len() + } } #[tracing::instrument(skip_all, level = "debug")] @@ -177,6 +208,7 @@ pub async fn run_for_package( package_name, }: RunForPackageArgs, block_number_map: &mut BlockNumberMap, + partition_config: Option<&PartitionConfig>, ui: Arc, ) -> Result { let mut test_targets = test_package_with_config_resolved( @@ -187,7 +219,7 @@ pub async fn run_for_package( &tests_filter, ) .await?; - let all_tests = sum_test_cases(&test_targets); + let all_tests = sum_test_cases_from_package(&test_targets, partition_config); for test_target in &mut test_targets { tests_filter.filter_tests(&mut test_target.test_cases)?; @@ -196,7 +228,8 @@ pub async fn run_for_package( warn_if_available_gas_used_with_incompatible_scarb_version(&test_targets, &ui)?; warn_if_incompatible_rpc_version(&test_targets, ui.clone()).await?; - let not_filtered = sum_test_cases(&test_targets); + let not_filtered = sum_test_cases_from_package(&test_targets, partition_config); + ui.println(&CollectedTestsCountMessage { tests_num: not_filtered, package_name: package_name.clone(), @@ -208,11 +241,17 @@ pub async fn run_for_package( let ui = ui.clone(); ui.println(&TestsRunMessage::new( test_target.tests_location, - test_target.test_cases.len(), + sum_test_cases_from_test_target(test_target.test_cases.clone(), partition_config), )); - let summary = - run_for_test_target(test_target, forge_config.clone(), &tests_filter, ui).await?; + let summary = run_for_test_target( + test_target, + forge_config.clone(), + &tests_filter, + partition_config, + ui, + ) + .await?; match summary { TestTargetRunResult::Ok(summary) => { diff --git a/crates/forge/src/run_tests/test_target.rs b/crates/forge/src/run_tests/test_target.rs index e03e6d874e..3697011ac1 100644 --- a/crates/forge/src/run_tests/test_target.rs +++ b/crates/forge/src/run_tests/test_target.rs @@ -1,3 +1,4 @@ +use crate::partition::PartitionConfig; use anyhow::Result; use forge_runner::messages::TestResultMessage; use forge_runner::{ @@ -25,6 +26,7 @@ pub async fn run_for_test_target( tests: TestTargetWithResolvedConfig, forge_config: Arc, tests_filter: &impl TestCaseFilter, + partition_config: Option<&PartitionConfig>, ui: Arc, ) -> Result { let casm_program = tests.casm_program.clone(); @@ -40,6 +42,28 @@ pub async fn run_for_test_target( for case in tests.test_cases { let case_name = case.name.clone(); + if let Some(partition_config) = &partition_config { + let test_partition = partition_config + .test_partition_map() + .get(&case.name) + .unwrap_or_else(|| { + unreachable!( + "Test '{}' should have been mapped to a partition", + case.name + ) + }); + let is_included_in_partition = *test_partition == partition_config.partition().index(); + + if !is_included_in_partition { + tasks.push(tokio::task::spawn(async { + Ok(AnyTestCaseSummary::Single( + TestCaseSummary::ExcludedFromPartition {}, + )) + })); + continue; + } + } + if !tests_filter.should_be_run(&case) { tasks.push(tokio::task::spawn(async { // TODO TestCaseType should also be encoded in the test case definition @@ -68,7 +92,7 @@ pub async fn run_for_test_target( while let Some(task) = tasks.next().await { let result = task??; - if !result.is_interrupted() { + if !result.is_interrupted() && !result.is_excluded_from_partition() { let test_result_message = TestResultMessage::new( &result, forge_config.output_config.detailed_resources, diff --git a/crates/forge/src/run_tests/workspace.rs b/crates/forge/src/run_tests/workspace.rs index 2442deec0c..756258b328 100644 --- a/crates/forge/src/run_tests/workspace.rs +++ b/crates/forge/src/run_tests/workspace.rs @@ -1,7 +1,9 @@ use super::package::RunForPackageArgs; +use crate::partition::PartitionConfig; use crate::profile_validation::check_profile_compatibility; use crate::run_tests::messages::latest_blocks_numbers::LatestBlocksNumbersMessage; use crate::run_tests::messages::overall_summary::OverallSummaryMessage; +use crate::run_tests::messages::partition::PartitionMessage; use crate::run_tests::messages::tests_failure_summary::TestsFailureSummaryMessage; use crate::warn::{ error_if_snforge_std_deprecated_missing, error_if_snforge_std_deprecated_not_compatible, @@ -29,6 +31,7 @@ use std::env; use std::sync::Arc; #[tracing::instrument(skip_all, level = "debug")] +#[expect(clippy::too_many_lines)] pub async fn run_for_workspace(args: TestArgs, ui: Arc) -> Result { match args.color { // SAFETY: This runs in a single-threaded environment. @@ -94,28 +97,62 @@ pub async fn run_for_workspace(args: TestArgs, ui: Arc) -> Result>>()?; + + let partition_config = PartitionConfig::new(*partition, &packages_args); + + for (package, args) in packages.iter().zip(packages_args) { + env::set_current_dir(&package.root)?; + + let result = run_for_package( + args, + &mut block_number_map, + Some(&partition_config), + ui.clone(), + ) + .await?; + + let filtered = result.filtered(); + all_tests.extend(result.summaries()); + + total_filtered_count = calculate_total_filtered_count(total_filtered_count, filtered); + } + } else { + for package in packages { + env::set_current_dir(&package.root)?; - let args = RunForPackageArgs::build( - package, - &scarb_metadata, - &args, - &cache_dir, - &artifacts_dir_path, - &ui, - )?; + let args = RunForPackageArgs::build( + package, + &scarb_metadata, + &args, + &cache_dir, + &artifacts_dir_path, + &ui, + )?; - let result = run_for_package(args, &mut block_number_map, ui.clone()).await?; + let result = run_for_package(args, &mut block_number_map, None, ui.clone()).await?; - let filtered = result.filtered(); - all_tests.extend(result.summaries()); + let filtered = result.filtered(); + all_tests.extend(result.summaries()); - // Accumulate filtered test counts across packages. When using --exact flag, - // result.filtered_count is None, so total_filtered_count becomes None too. - total_filtered_count = total_filtered_count - .zip(filtered) - .map(|(total, filtered)| total + filtered); + total_filtered_count = calculate_total_filtered_count(total_filtered_count, filtered); + } } let overall_summary = OverallSummaryMessage::new(&all_tests, total_filtered_count); @@ -138,6 +175,10 @@ pub async fn run_for_workspace(args: TestArgs, ui: Arc) -> Result) -> Result, + filtered: Option, +) -> Option { + // Accumulate filtered test counts across packages. When using `--exact` flag, + // `result.filtered_count` is None, so `total_filtered_count` becomes None too. + total_filtered_count + .zip(filtered) + .map(|(total, filtered)| total + filtered) +} + #[tracing::instrument(skip_all, level = "debug")] fn extract_failed_tests( tests_summaries: Vec, diff --git a/crates/forge/test_utils/src/running_tests.rs b/crates/forge/test_utils/src/running_tests.rs index 5047677194..cea7a9e55f 100644 --- a/crates/forge/test_utils/src/running_tests.rs +++ b/crates/forge/test_utils/src/running_tests.rs @@ -86,6 +86,7 @@ pub fn run_test_case( fork_targets: vec![], }, &mut BlockNumberMap::default(), + None, ui, )) .expect("Runner fail") diff --git a/crates/forge/tests/data/partitioning/Scarb.toml b/crates/forge/tests/data/partitioning/Scarb.toml new file mode 100644 index 0000000000..fba883415e --- /dev/null +++ b/crates/forge/tests/data/partitioning/Scarb.toml @@ -0,0 +1,39 @@ +[workspace] +members = [ + "crates/package_a", + "crates/package_b", +] + +[workspace.scripts] +test = "snforge" + +[workspace.tool.snforge] + +[workspace.dependencies] +starknet = "2.12.0" +snforge_std = { path = "../../../../../snforge_std" } + +[workspace.package] +version = "0.1.0" + +[package] +name = "partitioning" +version.workspace = true +edition = "2024_07" + +[scripts] +test.workspace = true + +[tool] +snforge.workspace = true + +[dependencies] +starknet.workspace = true +package_a = { path = "crates/package_a" } +package_b = { path = "crates/package_b" } + +[dev-dependencies] +snforge_std.workspace = true + +[[target.starknet-contract]] +sierra = true diff --git a/crates/forge/tests/data/partitioning/crates/package_a/Scarb.toml b/crates/forge/tests/data/partitioning/crates/package_a/Scarb.toml new file mode 100644 index 0000000000..a90f95ab8b --- /dev/null +++ b/crates/forge/tests/data/partitioning/crates/package_a/Scarb.toml @@ -0,0 +1,10 @@ +[package] +name = "package_a" +version.workspace = true +edition = "2024_07" + +[dependencies] +starknet.workspace = true + +[dev-dependencies] +snforge_std.workspace = true diff --git a/crates/forge/tests/data/partitioning/crates/package_a/src/lib.cairo b/crates/forge/tests/data/partitioning/crates/package_a/src/lib.cairo new file mode 100644 index 0000000000..2c8d367431 --- /dev/null +++ b/crates/forge/tests/data/partitioning/crates/package_a/src/lib.cairo @@ -0,0 +1,19 @@ +#[starknet::contract] +pub mod HelloStarknet { + #[storage] + struct Storage {} +} + +#[cfg(test)] +mod tests { + #[test] + fn test_a() { + assert!(1 + 1 == 2); + } + + #[test] + #[ignore] // Ignored on purpose + fn test_b() { + assert!(1 + 1 == 2); + } +} diff --git a/crates/forge/tests/data/partitioning/crates/package_a/tests/tests.cairo b/crates/forge/tests/data/partitioning/crates/package_a/tests/tests.cairo new file mode 100644 index 0000000000..8e7181b60b --- /dev/null +++ b/crates/forge/tests/data/partitioning/crates/package_a/tests/tests.cairo @@ -0,0 +1,9 @@ +#[test] +fn test_c() { + assert!(1 + 1 == 2); +} + +#[test] +fn test_d() { + assert!(1 + 1 == 2); +} diff --git a/crates/forge/tests/data/partitioning/crates/package_b/Scarb.toml b/crates/forge/tests/data/partitioning/crates/package_b/Scarb.toml new file mode 100644 index 0000000000..f09a0d86c8 --- /dev/null +++ b/crates/forge/tests/data/partitioning/crates/package_b/Scarb.toml @@ -0,0 +1,10 @@ +[package] +name = "package_b" +version.workspace = true +edition = "2024_07" + +[dependencies] +starknet.workspace = true + +[dev-dependencies] +snforge_std.workspace = true diff --git a/crates/forge/tests/data/partitioning/crates/package_b/src/lib.cairo b/crates/forge/tests/data/partitioning/crates/package_b/src/lib.cairo new file mode 100644 index 0000000000..d52c38c84a --- /dev/null +++ b/crates/forge/tests/data/partitioning/crates/package_b/src/lib.cairo @@ -0,0 +1,18 @@ +#[starknet::contract] +pub mod HelloStarknet { + #[storage] + struct Storage {} +} + +#[cfg(test)] +mod tests { + #[test] + fn test_e() { + assert!(1 + 1 == 2); + } + + #[test] + fn test_f() { + assert!(1 + 1 == 2); + } +} diff --git a/crates/forge/tests/data/partitioning/crates/package_b/tests/tests.cairo b/crates/forge/tests/data/partitioning/crates/package_b/tests/tests.cairo new file mode 100644 index 0000000000..5ed8490363 --- /dev/null +++ b/crates/forge/tests/data/partitioning/crates/package_b/tests/tests.cairo @@ -0,0 +1,9 @@ +#[test] +fn test_g() { + assert!(1 + 1 == 2); +} + +#[test] +fn test_h() { + assert!(1 + 1 == 3); // Failing on purpose +} diff --git a/crates/forge/tests/data/partitioning/src/lib.cairo b/crates/forge/tests/data/partitioning/src/lib.cairo new file mode 100644 index 0000000000..88efedd9b1 --- /dev/null +++ b/crates/forge/tests/data/partitioning/src/lib.cairo @@ -0,0 +1,18 @@ +#[starknet::contract] +pub mod HelloStarknet { + #[storage] + struct Storage {} +} + +#[cfg(test)] +mod tests { + #[test] + fn test_i() { + assert!(1 + 1 == 2); + } + + #[test] + fn test_j() { + assert!(1 + 1 == 2); + } +} diff --git a/crates/forge/tests/data/partitioning/tests/tests.cairo b/crates/forge/tests/data/partitioning/tests/tests.cairo new file mode 100644 index 0000000000..9489cc9359 --- /dev/null +++ b/crates/forge/tests/data/partitioning/tests/tests.cairo @@ -0,0 +1,15 @@ +#[test] +fn test_k() { + assert!(1 + 1 == 2); +} + +#[test] +fn test_l() { + assert!(1 + 1 == 2); +} + +#[test] +fn test_m() { + assert!(1 + 1 == 2); +} + diff --git a/crates/forge/tests/e2e/partitioning.rs b/crates/forge/tests/e2e/partitioning.rs index c82c938066..53fce81f1e 100644 --- a/crates/forge/tests/e2e/partitioning.rs +++ b/crates/forge/tests/e2e/partitioning.rs @@ -1,6 +1,6 @@ use crate::e2e::common::runner::{setup_package, test_runner}; use indoc::indoc; -use shared::test_utils::output_assert::assert_stderr_contains; +use shared::test_utils::output_assert::{assert_stderr_contains, assert_stdout_contains}; #[test] fn test_does_not_work_with_exact_flag() { @@ -17,3 +17,276 @@ fn test_does_not_work_with_exact_flag() { "}, ); } + +#[test] +fn test_whole_workspace_partition_1_2() { + let temp = setup_package("partitioning"); + let output = test_runner(&temp) + .args(["--partition", "1/2", "--workspace"]) + .assert() + .code(0); + + assert_stdout_contains( + output, + indoc! {r" + [..]Compiling[..] + [..]Finished[..] + + + Collected 2 test(s) from package_a package + Running 1 test(s) from tests/ + [PASS] package_a_integrationtest::tests::test_c ([..]) + Running 1 test(s) from src/ + [PASS] package_a::tests::test_a ([..]) + Tests: 2 passed, 0 failed, 0 ignored, 0 filtered out + + + Collected 2 test(s) from package_b package + Running 1 test(s) from src/ + [PASS] package_b::tests::test_e ([..]) + Running 1 test(s) from tests/ + [PASS] package_b_integrationtest::tests::test_g ([..]) + Tests: 2 passed, 0 failed, 0 ignored, 0 filtered out + + + Collected 3 test(s) from partitioning package + Running 2 test(s) from tests/ + [PASS] partitioning_integrationtest::tests::test_k ([..]) + [PASS] partitioning_integrationtest::tests::test_m ([..]) + Running 1 test(s) from src/ + [PASS] partitioning::tests::test_i ([..]) + Tests: 3 passed, 0 failed, 0 ignored, 0 filtered out + + + Tests summary: 7 passed, 0 failed, 0 ignored, 0 filtered out + Finished partition run: 1/2 + "}, + ); +} + +#[test] +fn test_whole_workspace_partition_2_2() { + let temp = setup_package("partitioning"); + let output = test_runner(&temp) + .args(["--partition", "2/2", "--workspace"]) + .assert() + .code(1); + + assert_stdout_contains( + output, + indoc! {r#" + [..]Compiling[..] + [..]Finished[..] + + + Collected 2 test(s) from package_a package + Running 1 test(s) from tests/ + [PASS] package_a_integrationtest::tests::test_d ([..]) + Running 1 test(s) from src/ + [IGNORE] package_a::tests::test_b + Tests: 1 passed, 0 failed, 1 ignored, 0 filtered out + + + Collected 2 test(s) from package_b package + Running 1 test(s) from src/ + [PASS] package_b::tests::test_f ([..]) + Running 1 test(s) from tests/ + [FAIL] package_b_integrationtest::tests::test_h + + Failure data: + "assertion failed: `1 + 1 == 3`." + + Tests: 1 passed, 1 failed, 0 ignored, 0 filtered out + + + Collected 2 test(s) from partitioning package + Running 1 test(s) from tests/ + [PASS] partitioning_integrationtest::tests::test_l ([..]) + Running 1 test(s) from src/ + [PASS] partitioning::tests::test_j ([..]) + Tests: 2 passed, 0 failed, 0 ignored, 0 filtered out + + Failures: + package_b_integrationtest::tests::test_h + + Tests summary: 4 passed, 1 failed, 1 ignored, 0 filtered out + Finished partition run: 2/2 + "#}, + ); +} + +#[test] +fn test_whole_workspace_partition_1_3() { + let temp = setup_package("partitioning"); + let output = test_runner(&temp) + .args(["--partition", "1/3", "--workspace"]) + .assert() + .code(0); + + assert_stdout_contains( + output, + indoc! {r" + [..]Compiling[..] + [..]Finished[..] + + + Collected 2 test(s) from package_a package + Running 1 test(s) from src/ + [PASS] package_a::tests::test_a ([..]) + Running 1 test(s) from tests/ + [PASS] package_a_integrationtest::tests::test_d ([..]) + Tests: 2 passed, 0 failed, 0 ignored, 0 filtered out + + + Collected 1 test(s) from package_b package + Running 0 test(s) from src/ + Running 1 test(s) from tests/ + [PASS] package_b_integrationtest::tests::test_g ([..]) + Tests: 1 passed, 0 failed, 0 ignored, 0 filtered out + + + Collected 2 test(s) from partitioning package + Running 1 test(s) from src/ + [PASS] partitioning::tests::test_j ([..]) + Running 1 test(s) from tests/ + [PASS] partitioning_integrationtest::tests::test_m ([..]) + Tests: 2 passed, 0 failed, 0 ignored, 0 filtered out + + + Tests summary: 5 passed, 0 failed, 0 ignored, 0 filtered out + Finished partition run: 1/3 + "}, + ); +} + +#[test] +fn test_whole_workspace_partition_2_3() { + let temp = setup_package("partitioning"); + let output = test_runner(&temp) + .args(["--partition", "2/3", "--workspace"]) + .assert() + .code(1); + + assert_stdout_contains( + output, + indoc! {r#" + [..]Compiling[..] + [..]Finished[..] + + + Collected 1 test(s) from package_a package + Running 0 test(s) from tests/ + Running 1 test(s) from src/ + [IGNORE] package_a::tests::test_b + Tests: 0 passed, 0 failed, 1 ignored, 0 filtered out + + + Collected 2 test(s) from package_b package + Running 1 test(s) from tests/ + [FAIL] package_b_integrationtest::tests::test_h + + Failure data: + "assertion failed: `1 + 1 == 3`." + + Running 1 test(s) from src/ + [PASS] package_b::tests::test_e ([..]) + Tests: 1 passed, 1 failed, 0 ignored, 0 filtered out + + + Collected 1 test(s) from partitioning package + Running 1 test(s) from tests/ + [PASS] partitioning_integrationtest::tests::test_k ([..]) + Running 0 test(s) from src/ + Tests: 1 passed, 0 failed, 0 ignored, 0 filtered out + + Failures: + package_b_integrationtest::tests::test_h + + Tests summary: 2 passed, 1 failed, 1 ignored, 0 filtered out + Finished partition run: 2/3 + "#}, + ); +} + +#[test] +fn test_whole_workspace_partition_3_3() { + let temp = setup_package("partitioning"); + let output = test_runner(&temp) + .args(["--partition", "3/3", "--workspace"]) + .assert() + .code(0); + + assert_stdout_contains( + output, + indoc! {r" + [..]Compiling[..] + [..]Finished[..] + + + Collected 1 test(s) from package_a package + Running 1 test(s) from tests/ + [PASS] package_a_integrationtest::tests::test_c ([..]) + Running 0 test(s) from src/ + Tests: 1 passed, 0 failed, 0 ignored, 0 filtered out + + + Collected 1 test(s) from package_b package + Running 1 test(s) from src/ + [PASS] package_b::tests::test_f ([..]) + Running 0 test(s) from tests/ + Tests: 1 passed, 0 failed, 0 ignored, 0 filtered out + + + Collected 2 test(s) from partitioning package + Running 1 test(s) from tests/ + [PASS] partitioning_integrationtest::tests::test_l ([..]) + Running 1 test(s) from src/ + [PASS] partitioning::tests::test_i ([..]) + Tests: 2 passed, 0 failed, 0 ignored, 0 filtered out + + + Tests summary: 4 passed, 0 failed, 0 ignored, 0 filtered out + Finished partition run: 3/3 + "}, + ); +} + +#[test] +fn test_works_with_name_filter() { + let temp = setup_package("partitioning"); + let output = test_runner(&temp) + .args(["--partition", "1/3", "--workspace", "test_a"]) + .assert() + .code(0); + + assert_stdout_contains( + output, + indoc! {r" + [..]Compiling[..] + [..]Finished[..] + + + Collected 1 test(s) from package_a package + Running 0 test(s) from tests/ + Running 1 test(s) from src/ + [PASS] package_a::tests::test_a ([..]) + Tests: 1 passed, 0 failed, 0 ignored, 1 filtered out + + + Collected 0 test(s) from package_b package + Running 0 test(s) from src/ + Running 0 test(s) from tests/ + Tests: 0 passed, 0 failed, 0 ignored, 1 filtered out + + + Collected 0 test(s) from partitioning package + Running 0 test(s) from tests/ + Running 0 test(s) from src/ + Tests: 0 passed, 0 failed, 0 ignored, 2 filtered out + + + Tests summary: 1 passed, 0 failed, 0 ignored, 4 filtered out + Finished partition run: 1/3 + "}, + ); +} diff --git a/crates/forge/tests/integration/setup_fork.rs b/crates/forge/tests/integration/setup_fork.rs index eb7e9175e3..1bbaea3af1 100644 --- a/crates/forge/tests/integration/setup_fork.rs +++ b/crates/forge/tests/integration/setup_fork.rs @@ -175,6 +175,7 @@ fn fork_aliased_decorator() { }], }, &mut BlockNumberMap::default(), + None, ui, )) .expect("Runner fail") @@ -268,6 +269,7 @@ fn fork_aliased_decorator_overrding() { }], }, &mut BlockNumberMap::default(), + None, ui, )) .expect("Runner fail")