diff --git a/Cargo.lock b/Cargo.lock index 1fe09d2af9..f870f7da1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4576,6 +4576,7 @@ dependencies = [ "futures-util", "itertools 0.10.5", "metrics", + "paste", "rand 0.8.5", "rayon", "reth-db", diff --git a/crates/stages/Cargo.toml b/crates/stages/Cargo.toml index b06648eb08..a95661b10e 100644 --- a/crates/stages/Cargo.toml +++ b/crates/stages/Cargo.toml @@ -46,3 +46,4 @@ tokio-stream = "0.1.10" tempfile = "3.3.0" assert_matches = "1.5.0" rand = "0.8.5" +paste = "1.0" diff --git a/crates/stages/src/stages/bodies.rs b/crates/stages/src/stages/bodies.rs index 7d5a371040..8681149ece 100644 --- a/crates/stages/src/stages/bodies.rs +++ b/crates/stages/src/stages/bodies.rs @@ -278,7 +278,7 @@ mod tests { use std::collections::HashMap; use test_utils::*; - stage_test_suite_ext!(BodyTestRunner); + stage_test_suite_ext!(BodyTestRunner, body); /// Checks that the stage downloads at most `batch_size` blocks. #[tokio::test] diff --git a/crates/stages/src/stages/hashing_account.rs b/crates/stages/src/stages/hashing_account.rs index 344d63b140..7da918a0e1 100644 --- a/crates/stages/src/stages/hashing_account.rs +++ b/crates/stages/src/stages/hashing_account.rs @@ -175,7 +175,7 @@ mod tests { use reth_provider::insert_canonical_block; use test_utils::*; - stage_test_suite_ext!(AccountHashingTestRunner); + stage_test_suite_ext!(AccountHashingTestRunner, account_hashing); #[tokio::test] async fn execute_below_clean_threshold() { diff --git a/crates/stages/src/stages/hashing_storage.rs b/crates/stages/src/stages/hashing_storage.rs index 043c6062ae..2b84f37069 100644 --- a/crates/stages/src/stages/hashing_storage.rs +++ b/crates/stages/src/stages/hashing_storage.rs @@ -223,7 +223,7 @@ mod tests { SealedBlock, StorageEntry, Transaction, TransactionKind, TxLegacy, H256, U256, }; - stage_test_suite_ext!(StorageHashingTestRunner); + stage_test_suite_ext!(StorageHashingTestRunner, storage_hashing); /// Execute with low clean threshold so as to hash whole storage #[tokio::test] diff --git a/crates/stages/src/stages/headers.rs b/crates/stages/src/stages/headers.rs index 6274a34285..153d3cf2d0 100644 --- a/crates/stages/src/stages/headers.rs +++ b/crates/stages/src/stages/headers.rs @@ -295,7 +295,7 @@ mod tests { use reth_interfaces::{p2p::error::RequestError, test_utils::generators::random_header}; use test_runner::HeadersTestRunner; - stage_test_suite!(HeadersTestRunner); + stage_test_suite!(HeadersTestRunner, headers); /// Check that the execution errors on empty database or /// prev progress missing from the database. diff --git a/crates/stages/src/stages/sender_recovery.rs b/crates/stages/src/stages/sender_recovery.rs index d0ee0f245d..d94e7535f2 100644 --- a/crates/stages/src/stages/sender_recovery.rs +++ b/crates/stages/src/stages/sender_recovery.rs @@ -137,7 +137,7 @@ mod tests { TestTransaction, UnwindStageTestRunner, PREV_STAGE_ID, }; - stage_test_suite_ext!(SenderRecoveryTestRunner); + stage_test_suite_ext!(SenderRecoveryTestRunner, sender_recovery); /// Execute a block range with a single transaction #[tokio::test] diff --git a/crates/stages/src/stages/total_difficulty.rs b/crates/stages/src/stages/total_difficulty.rs index eeee0cc3c2..faa2ef4946 100644 --- a/crates/stages/src/stages/total_difficulty.rs +++ b/crates/stages/src/stages/total_difficulty.rs @@ -95,7 +95,7 @@ mod tests { TestTransaction, UnwindStageTestRunner, PREV_STAGE_ID, }; - stage_test_suite_ext!(TotalDifficultyTestRunner); + stage_test_suite_ext!(TotalDifficultyTestRunner, total_difficulty); #[tokio::test] async fn execute_with_intermediate_commit() { diff --git a/crates/stages/src/test_utils/macros.rs b/crates/stages/src/test_utils/macros.rs index 947d3a5fcb..e3849f1b4e 100644 --- a/crates/stages/src/test_utils/macros.rs +++ b/crates/stages/src/test_utils/macros.rs @@ -1,114 +1,117 @@ macro_rules! stage_test_suite { - ($runner:ident) => { - /// Check that the execution is short-circuited if the database is empty. - #[tokio::test] - async fn execute_empty_db() { - // Set up the runner - let runner = $runner::default(); + ($runner:ident, $name:ident) => { - // Execute the stage with empty database - let input = crate::stage::ExecInput::default(); + paste::item! { + /// Check that the execution is short-circuited if the database is empty. + #[tokio::test] + async fn [< execute_empty_db_ $name>] () { + // Set up the runner + let runner = $runner::default(); - // Run stage execution - let result = runner.execute(input).await; - // Check that the result is returned and the stage does not panic. - // The return result with empty db is stage-specific. - assert_matches::assert_matches!(result, Ok(_)); + // Execute the stage with empty database + let input = crate::stage::ExecInput::default(); - // Validate the stage execution - assert!(runner.validate_execution(input, result.unwrap().ok()).is_ok(), "execution validation"); - } + // Run stage execution + let result = runner.execute(input).await; + // Check that the result is returned and the stage does not panic. + // The return result with empty db is stage-specific. + assert_matches::assert_matches!(result, Ok(_)); - // Run the complete stage execution flow. - #[tokio::test] - async fn execute() { - let (previous_stage, stage_progress) = (500, 100); + // Validate the stage execution + assert!(runner.validate_execution(input, result.unwrap().ok()).is_ok(), "execution validation"); + } - // Set up the runner - let mut runner = $runner::default(); - let input = crate::stage::ExecInput { - previous_stage: Some((crate::test_utils::PREV_STAGE_ID, previous_stage)), - stage_progress: Some(stage_progress), - }; - let seed = runner.seed_execution(input).expect("failed to seed"); - let rx = runner.execute(input); + // Run the complete stage execution flow. + #[tokio::test] + async fn [< execute_ $name>] () { + let (previous_stage, stage_progress) = (500, 100); - // Run `after_execution` hook - runner.after_execution(seed).await.expect("failed to run after execution hook"); + // Set up the runner + let mut runner = $runner::default(); + let input = crate::stage::ExecInput { + previous_stage: Some((crate::test_utils::PREV_STAGE_ID, previous_stage)), + stage_progress: Some(stage_progress), + }; + let seed = runner.seed_execution(input).expect("failed to seed"); + let rx = runner.execute(input); - // Assert the successful result - let result = rx.await.unwrap(); - assert_matches::assert_matches!( - result, - Ok(ExecOutput { done, stage_progress }) - if done && stage_progress == previous_stage - ); + // Run `after_execution` hook + runner.after_execution(seed).await.expect("failed to run after execution hook"); - // Validate the stage execution - assert!(runner.validate_execution(input, result.ok()).is_ok(), "execution validation"); - } + // Assert the successful result + let result = rx.await.unwrap(); + assert_matches::assert_matches!( + result, + Ok(ExecOutput { done, stage_progress }) + if done && stage_progress == previous_stage + ); - // Check that unwind does not panic on no new entries within the input range. - #[tokio::test] - async fn unwind_no_new_entries() { - // Set up the runner - let mut runner = $runner::default(); - let input = crate::stage::UnwindInput::default(); + // Validate the stage execution + assert!(runner.validate_execution(input, result.ok()).is_ok(), "execution validation"); + } - // Seed the database - runner.seed_execution(crate::stage::ExecInput::default()).expect("failed to seed"); + // Check that unwind does not panic on no new entries within the input range. + #[tokio::test] + async fn [< unwind_no_new_entries_ $name>] () { + // Set up the runner + let mut runner = $runner::default(); + let input = crate::stage::UnwindInput::default(); - // Run stage unwind - let rx = runner.unwind(input).await; - assert_matches::assert_matches!( - rx, - Ok(UnwindOutput { stage_progress }) if stage_progress == input.unwind_to - ); + // Seed the database + runner.seed_execution(crate::stage::ExecInput::default()).expect("failed to seed"); - // Validate the stage unwind - assert!(runner.validate_unwind(input).is_ok(), "unwind validation"); - } + // Run stage unwind + let rx = runner.unwind(input).await; + assert_matches::assert_matches!( + rx, + Ok(UnwindOutput { stage_progress }) if stage_progress == input.unwind_to + ); - // Run complete execute and unwind flow. - #[tokio::test] - async fn unwind() { - let (previous_stage, stage_progress) = (500, 100); + // Validate the stage unwind + assert!(runner.validate_unwind(input).is_ok(), "unwind validation"); + } - // Set up the runner - let mut runner = $runner::default(); - let execute_input = crate::stage::ExecInput { - previous_stage: Some((crate::test_utils::PREV_STAGE_ID, previous_stage)), - stage_progress: Some(stage_progress), - }; - let seed = runner.seed_execution(execute_input).expect("failed to seed"); + // Run complete execute and unwind flow. + #[tokio::test] + async fn [< unwind_ $name>] () { + let (previous_stage, stage_progress) = (500, 100); - // Run stage execution - let rx = runner.execute(execute_input); - runner.after_execution(seed).await.expect("failed to run after execution hook"); + // Set up the runner + let mut runner = $runner::default(); + let execute_input = crate::stage::ExecInput { + previous_stage: Some((crate::test_utils::PREV_STAGE_ID, previous_stage)), + stage_progress: Some(stage_progress), + }; + let seed = runner.seed_execution(execute_input).expect("failed to seed"); - // Assert the successful execution result - let result = rx.await.unwrap(); - assert_matches::assert_matches!( - result, - Ok(ExecOutput { done, stage_progress }) - if done && stage_progress == previous_stage - ); - assert!(runner.validate_execution(execute_input, result.ok()).is_ok(), "execution validation"); + // Run stage execution + let rx = runner.execute(execute_input); + runner.after_execution(seed).await.expect("failed to run after execution hook"); - // Run stage unwind - let unwind_input = crate::stage::UnwindInput { - unwind_to: stage_progress, stage_progress: previous_stage, bad_block: None, - }; - let rx = runner.unwind(unwind_input).await; + // Assert the successful execution result + let result = rx.await.unwrap(); + assert_matches::assert_matches!( + result, + Ok(ExecOutput { done, stage_progress }) + if done && stage_progress == previous_stage + ); + assert!(runner.validate_execution(execute_input, result.ok()).is_ok(), "execution validation"); - // Assert the successful unwind result - assert_matches::assert_matches!( - rx, - Ok(UnwindOutput { stage_progress }) if stage_progress == unwind_input.unwind_to - ); + // Run stage unwind + let unwind_input = crate::stage::UnwindInput { + unwind_to: stage_progress, stage_progress: previous_stage, bad_block: None, + }; + let rx = runner.unwind(unwind_input).await; - // Validate the stage unwind - assert!(runner.validate_unwind(unwind_input).is_ok(), "unwind validation"); + // Assert the successful unwind result + assert_matches::assert_matches!( + rx, + Ok(UnwindOutput { stage_progress }) if stage_progress == unwind_input.unwind_to + ); + + // Validate the stage unwind + assert!(runner.validate_unwind(unwind_input).is_ok(), "unwind validation"); + } } }; } @@ -116,38 +119,40 @@ macro_rules! stage_test_suite { // `execute_already_reached_target` is not suitable for the headers stage thus // included in the test suite extension macro_rules! stage_test_suite_ext { - ($runner:ident) => { - crate::test_utils::stage_test_suite!($runner); + ($runner:ident, $name:ident) => { + crate::test_utils::stage_test_suite!($runner, $name); - /// Check that the execution is short-circuited if the target was already reached. - #[tokio::test] - async fn execute_already_reached_target() { - let stage_progress = 1000; + paste::item! { + /// Check that the execution is short-circuited if the target was already reached. + #[tokio::test] + async fn [< execute_already_reached_target_ $name>] () { + let stage_progress = 1000; - // Set up the runner - let mut runner = $runner::default(); - let input = crate::stage::ExecInput { - previous_stage: Some((crate::test_utils::PREV_STAGE_ID, stage_progress)), - stage_progress: Some(stage_progress), - }; - let seed = runner.seed_execution(input).expect("failed to seed"); + // Set up the runner + let mut runner = $runner::default(); + let input = crate::stage::ExecInput { + previous_stage: Some((crate::test_utils::PREV_STAGE_ID, stage_progress)), + stage_progress: Some(stage_progress), + }; + let seed = runner.seed_execution(input).expect("failed to seed"); - // Run stage execution - let rx = runner.execute(input); + // Run stage execution + let rx = runner.execute(input); - // Run `after_execution` hook - runner.after_execution(seed).await.expect("failed to run after execution hook"); + // Run `after_execution` hook + runner.after_execution(seed).await.expect("failed to run after execution hook"); - // Assert the successful result - let result = rx.await.unwrap(); - assert_matches::assert_matches!( - result, - Ok(ExecOutput { done, stage_progress }) - if done && stage_progress == stage_progress - ); + // Assert the successful result + let result = rx.await.unwrap(); + assert_matches::assert_matches!( + result, + Ok(ExecOutput { done, stage_progress }) + if done && stage_progress == stage_progress + ); - // Validate the stage execution - assert!(runner.validate_execution(input, result.ok()).is_ok(), "execution validation"); + // Validate the stage execution + assert!(runner.validate_execution(input, result.ok()).is_ok(), "execution validation"); + } } }; }