Skip to content

Commit

Permalink
test: add stage name to test suite functions (#934)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse authored Jan 19, 2023
1 parent 013eb51 commit 2a77e08
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 148 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/stages/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
2 changes: 1 addition & 1 deletion crates/stages/src/stages/bodies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion crates/stages/src/stages/hashing_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion crates/stages/src/stages/hashing_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion crates/stages/src/stages/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion crates/stages/src/stages/sender_recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion crates/stages/src/stages/total_difficulty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
289 changes: 147 additions & 142 deletions crates/stages/src/test_utils/macros.rs
Original file line number Diff line number Diff line change
@@ -1,153 +1,158 @@
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();

// Execute the stage with empty database
let input = crate::stage::ExecInput::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(_));

// Validate the stage execution
assert!(runner.validate_execution(input, result.unwrap().ok()).is_ok(), "execution validation");
}

// Run the complete stage execution flow.
#[tokio::test]
async fn execute() {
let (previous_stage, stage_progress) = (500, 100);

// 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 `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 == previous_stage
);

// Validate the stage execution
assert!(runner.validate_execution(input, result.ok()).is_ok(), "execution validation");
}

// 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();

// Seed the database
runner.seed_execution(crate::stage::ExecInput::default()).expect("failed to seed");

// Run stage unwind
let rx = runner.unwind(input).await;
assert_matches::assert_matches!(
rx,
Ok(UnwindOutput { stage_progress }) if stage_progress == input.unwind_to
);

// Validate the stage unwind
assert!(runner.validate_unwind(input).is_ok(), "unwind validation");
}

// Run complete execute and unwind flow.
#[tokio::test]
async fn unwind() {
let (previous_stage, stage_progress) = (500, 100);

// 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 stage execution
let rx = runner.execute(execute_input);
runner.after_execution(seed).await.expect("failed to run after execution hook");

// 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 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 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");
($runner:ident, $name:ident) => {

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();

// Execute the stage with empty database
let input = crate::stage::ExecInput::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(_));

// Validate the stage execution
assert!(runner.validate_execution(input, result.unwrap().ok()).is_ok(), "execution validation");
}

// Run the complete stage execution flow.
#[tokio::test]
async fn [< execute_ $name>] () {
let (previous_stage, stage_progress) = (500, 100);

// 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 `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 == previous_stage
);

// Validate the stage execution
assert!(runner.validate_execution(input, result.ok()).is_ok(), "execution validation");
}

// 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();

// Seed the database
runner.seed_execution(crate::stage::ExecInput::default()).expect("failed to seed");

// Run stage unwind
let rx = runner.unwind(input).await;
assert_matches::assert_matches!(
rx,
Ok(UnwindOutput { stage_progress }) if stage_progress == input.unwind_to
);

// Validate the stage unwind
assert!(runner.validate_unwind(input).is_ok(), "unwind validation");
}

// Run complete execute and unwind flow.
#[tokio::test]
async fn [< unwind_ $name>] () {
let (previous_stage, stage_progress) = (500, 100);

// 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 stage execution
let rx = runner.execute(execute_input);
runner.after_execution(seed).await.expect("failed to run after execution hook");

// 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 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 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");
}
}
};
}

// `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);

/// 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;

// 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 `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
);

// Validate the stage execution
assert!(runner.validate_execution(input, result.ok()).is_ok(), "execution validation");
($runner:ident, $name:ident) => {
crate::test_utils::stage_test_suite!($runner, $name);

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");

// Run stage execution
let rx = runner.execute(input);

// 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
);

// Validate the stage execution
assert!(runner.validate_execution(input, result.ok()).is_ok(), "execution validation");
}
}
};
}
Expand Down

0 comments on commit 2a77e08

Please sign in to comment.