diff --git a/CHANGELOG.md b/CHANGELOG.md index 04fdf2b5a88..382313d1e96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,7 @@ Description of the upcoming release here. ### Added -- Something new here 1 -- Something new here 2 +- [#1286](https://github.com/FuelLabs/fuel-core/pull/1286): Include readable names for test cases where missing. ### Changed diff --git a/crates/services/consensus_module/poa/src/service_test/manually_produce_tests.rs b/crates/services/consensus_module/poa/src/service_test/manually_produce_tests.rs index 7ac8cb25881..47bb8d5e30f 100644 --- a/crates/services/consensus_module/poa/src/service_test/manually_produce_tests.rs +++ b/crates/services/consensus_module/poa/src/service_test/manually_produce_tests.rs @@ -6,30 +6,39 @@ use test_case::test_case; use super::*; -#[test_case(Tai64::now(), 10, vec![Tai64::now(); 10], Trigger::Never, 0)] -#[test_case(Tai64::now(), 10, vec![Tai64::now(); 10], Trigger::Instant, 0)] +#[test_case(Tai64::now(), 10, vec![Tai64::now(); 10], Trigger::Never, 0; +"can manually produce blocks even when trigger is Never")] +#[test_case(Tai64::now(), 10, vec![Tai64::now(); 10], Trigger::Instant, 0; +"can manually produce blocks when trigger is Instant")] #[test_case( Tai64::now(), 3, vec![Tai64::now(), Tai64::now() + 10, Tai64::now() + 20], Trigger::Interval { block_time: Duration::from_secs(10) }, 0 -)] -#[test_case(Tai64::now() + 100, 10, vec![Tai64::now() + 100; 10], Trigger::Never, 0)] -#[test_case(Tai64::now() + 100, 10, vec![Tai64::now() + 100; 10], Trigger::Instant, 0)] +; "can manually produce blocks with different times")] +#[test_case(Tai64::now() + 100, 10, vec![Tai64::now() + 100; 10], Trigger::Never, 0; +"can manually produce blocks starting in the future even when trigger is Never")] +#[test_case(Tai64::now() + 100, 10, vec![Tai64::now() + 100; 10], Trigger::Instant, 0; +"can manually produce blocks starting in the future when trigger is Instant")] #[test_case( Tai64::now() + 100, 3, vec![Tai64::now() + 100, Tai64::now() + 110, Tai64::now() + 120], - Trigger::Interval { block_time: Duration::from_secs(10) }, 0 -)] -#[test_case(Tai64::now(), 10, vec![Tai64::now(); 10], Trigger::Never, 10)] -#[test_case(Tai64::now(), 10, vec![Tai64::now(); 10], Trigger::Instant, 10)] + Trigger::Interval { block_time: Duration::from_secs(10) }, 0; +"can manually produce blocks starting in the future with different times")] +#[test_case(Tai64::now(), 10, vec![Tai64::now(); 10], Trigger::Never, 10; +"can manually produce blocks with txs even when trigger is Never")] +#[test_case(Tai64::now(), 10, vec![Tai64::now(); 10], Trigger::Instant, 10; +"can manually produce blocks with txs when trigger is Instant")] #[test_case( Tai64::now(), 3, vec![Tai64::now(), Tai64::now() + 10, Tai64::now() + 20], Trigger::Interval { block_time: Duration::from_secs(10) }, 10 -)] -#[test_case(Tai64::now() + 100, 10, vec![Tai64::now() + 100; 10], Trigger::Never, 10)] -#[test_case(Tai64::now() + 100, 10, vec![Tai64::now() + 100; 10], Trigger::Instant, 10)] +; +"can manually produce blocks with different times with txs")] +#[test_case(Tai64::now() + 100, 10, vec![Tai64::now() + 100; 10], Trigger::Never, 10; +"can manually produce blocks with txs starting in the future even when trigger is Never")] +#[test_case(Tai64::now() + 100, 10, vec![Tai64::now() + 100; 10], Trigger::Instant, 10; +"can manually produce blocks with txs starting in the future when trigger is Instant")] #[test_case( Tai64::now() + 100, 3, vec![Tai64::now() + 100, Tai64::now() + 110, Tai64::now() + 120], - Trigger::Interval { block_time: Duration::from_secs(10) }, 10 -)] + Trigger::Interval { block_time: Duration::from_secs(10) }, 10; +"can manually produce blocks with txs starting in the future with different times")] #[tokio::test] async fn can_manually_produce_block( start_time: Tai64, diff --git a/crates/services/consensus_module/poa/src/verifier/tests.rs b/crates/services/consensus_module/poa/src/verifier/tests.rs index 594513440aa..9adae44743f 100644 --- a/crates/services/consensus_module/poa/src/verifier/tests.rs +++ b/crates/services/consensus_module/poa/src/verifier/tests.rs @@ -52,7 +52,7 @@ fn correct() -> Input { } } -#[test_case(correct() => matches Ok(_) ; "Correct block")] +#[test_case(correct() => matches Ok(_) ; "genesis verify correct block")] #[test_case( { let mut i = correct(); @@ -65,28 +65,28 @@ fn correct() -> Input { let mut i = correct(); i.ch.prev_root = [3u8; 32].into(); i - } => matches Err(_) ; "Prev root mis-match" + } => matches Err(_) ; "genesis verify prev root mis-match should error" )] #[test_case( { let mut i = correct(); i.ah.da_height = 1u64.into(); i - } => matches Err(_) ; "da height lower then prev header" + } => matches Err(_) ; "genesis verify da height lower then prev header should error" )] #[test_case( { let mut i = correct(); i.ch.generated.application_hash = [0u8; 32].into(); i - } => matches Err(_) ; "application hash mis-match" + } => matches Err(_) ; "genesis verify application hash mis-match should error" )] #[test_case( { let mut i = correct(); i.ch.time = Tai64(1); i - } => matches Err(_) ; "time before prev header" + } => matches Err(_) ; "genesis verify time before prev header should error" )] fn test_verify_genesis_block_fields(input: Input) -> anyhow::Result<()> { let Input { diff --git a/crates/services/importer/src/importer/test.rs b/crates/services/importer/src/importer/test.rs index ed3654fa10c..6dee917d3fe 100644 --- a/crates/services/importer/src/importer/test.rs +++ b/crates/services/importer/src/importer/test.rs @@ -219,37 +219,43 @@ where genesis(0), underlying_db(not_found), executor_db(ok(0), ok(None), 1) - => Ok(()) + => Ok(()); + "successfully imports genesis block when latest block not found" )] #[test_case( genesis(113), underlying_db(not_found), executor_db(ok(113), ok(None), 1) - => Ok(()) + => Ok(()); + "successfully imports block at arbitrary height when executor db expects it and last block not found" )] #[test_case( genesis(0), underlying_db(storage_failure), executor_db(ok(0), ok(None), 0) - => Err(Error::InvalidUnderlyingDatabaseGenesisState) + => Err(Error::InvalidUnderlyingDatabaseGenesisState); + "fails to import genesis when underlying database fails" )] #[test_case( genesis(0), underlying_db(ok(0)), executor_db(ok(0), ok(None), 0) - => Err(Error::InvalidUnderlyingDatabaseGenesisState) + => Err(Error::InvalidUnderlyingDatabaseGenesisState); + "fails to import genesis block when already exists" )] #[test_case( genesis(1), underlying_db(not_found), executor_db(ok(0), ok(None), 0) - => Err(Error::InvalidDatabaseStateAfterExecution(1u32.into(), 0u32.into())) + => Err(Error::InvalidDatabaseStateAfterExecution(1u32.into(), 0u32.into())); + "fails to import genesis block when next height is not 0" )] #[test_case( genesis(0), underlying_db(not_found), - executor_db(ok(0), ok(Some(Default::default())), 0) - => Err(Error::NotUnique(0u32.into())) + executor_db(ok(0), ok(Some(Consensus::Genesis(Default::default()))), 0) + => Err(Error::NotUnique(0u32.into())); + "fails to import genesis block when consensus exists for height 0" )] fn commit_result_genesis( sealed_block: SealedBlock, @@ -264,55 +270,64 @@ fn commit_result_genesis( poa_block(1), underlying_db(ok(0)), executor_db(ok(1), ok(None), 1) - => Ok(()) + => Ok(()); + "successfully imports block at height 1 when latest block is genesis" )] #[test_case( poa_block(113), underlying_db(ok(112)), executor_db(ok(113), ok(None), 1) - => Ok(()) + => Ok(()); + "successfully imports block at arbitrary height when latest block height is one fewer and executor db expects it" )] #[test_case( poa_block(0), underlying_db(ok(0)), executor_db(ok(1), ok(None), 0) - => Err(Error::ZeroNonGenericHeight) + => Err(Error::ZeroNonGenericHeight); + "fails to import PoA block with height 0" )] #[test_case( poa_block(113), underlying_db(ok(111)), executor_db(ok(113), ok(None), 0) - => Err(Error::IncorrectBlockHeight(112u32.into(), 113u32.into())) + => Err(Error::IncorrectBlockHeight(112u32.into(), 113u32.into())); + "fails to import block at height 113 when latest block height is 111" )] #[test_case( poa_block(113), underlying_db(ok(114)), executor_db(ok(113), ok(None), 0) - => Err(Error::IncorrectBlockHeight(115u32.into(), 113u32.into())) + => Err(Error::IncorrectBlockHeight(115u32.into(), 113u32.into())); + "fails to import block at height 113 when latest block height is 114" )] #[test_case( poa_block(113), underlying_db(ok(112)), executor_db(ok(114), ok(None), 0) - => Err(Error::InvalidDatabaseStateAfterExecution(113u32.into(), 114u32.into())) + => Err(Error::InvalidDatabaseStateAfterExecution(113u32.into(), 114u32.into())); + "fails to import block 113 when executor db expects height 114" )] #[test_case( poa_block(113), underlying_db(ok(112)), executor_db(storage_failure, ok(None), 0) - => Err(storage_failure_error()) + => Err(storage_failure_error()); + "fails to import block when executor db fails to find latest block" )] #[test_case( poa_block(113), underlying_db(ok(112)), - executor_db(ok(113), ok(Some(Default::default())), 0) - => Err(Error::NotUnique(113u32.into())) + executor_db(ok(113), ok(Some(Consensus::PoA(Default::default()))), 0) + => Err(Error::NotUnique(113u32.into())); + "fails to import block when consensus exists for block" )] #[test_case( poa_block(113), underlying_db(ok(112)), executor_db(ok(113), storage_failure, 0) - => Err(storage_failure_error()) + => Err(storage_failure_error()); + "fails to import block when executor db fails to find consensus" )] fn commit_result_and_execute_and_commit_poa( sealed_block: SealedBlock, @@ -439,31 +454,38 @@ fn one_lock_at_the_same_time() { ///////// New block, Block After Execution, Verification result, commits ///////// #[test_case( genesis(113), ok(ex_result(113, 0)), ok(()), 0 - => Err(Error::ExecuteGenesis) + => Err(Error::ExecuteGenesis); + "cannot execute genesis block" )] #[test_case( poa_block(1), ok(ex_result(1, 0)), ok(()), 1 - => Ok(()) + => Ok(()); + "commits block 1" )] #[test_case( poa_block(113), ok(ex_result(113, 0)), ok(()), 1 - => Ok(()) + => Ok(()); + "commits block 113" )] #[test_case( poa_block(113), ok(ex_result(114, 0)), ok(()), 0 - => Err(Error::BlockIdMismatch(poa_block(113).entity.id(), poa_block(114).entity.id())) + => Err(Error::BlockIdMismatch(poa_block(113).entity.id(), poa_block(114).entity.id())); + "execution result should match block height" )] #[test_case( poa_block(113), execution_failure, ok(()), 0 - => Err(execution_failure_error()) + => Err(execution_failure_error()); + "commit fails if execution fails" )] #[test_case( poa_block(113), ok(ex_result(113, 1)), ok(()), 0 - => Err(Error::SkippedTransactionsNotEmpty) + => Err(Error::SkippedTransactionsNotEmpty); + "commit fails if there are skipped transactions" )] #[test_case( poa_block(113), ok(ex_result(113, 0)), verification_failure, 0 - => Err(verification_failure_error()) + => Err(verification_failure_error()); + "commit fails if verification fails" )] fn execute_and_commit_and_verify_and_execute_block_poa( sealed_block: SealedBlock, diff --git a/crates/services/relayer/src/ports/tests.rs b/crates/services/relayer/src/ports/tests.rs index fc9e100d768..bb2f46221b1 100644 --- a/crates/services/relayer/src/ports/tests.rs +++ b/crates/services/relayer/src/ports/tests.rs @@ -69,13 +69,13 @@ fn insert_always_raises_da_height_monotonically() { db.insert_messages(&5u64.into(), &messages[..5]).unwrap(); } -#[test_case(None, 0, 0)] -#[test_case(None, 10, 10)] -#[test_case(0, 10, 10)] -#[test_case(0, None, 0)] -#[test_case(10, 11, 11)] -#[test_case(11, None, 11)] -#[test_case(11, None, 10)] +#[test_case(None, 0, 0; "can set DA height to 0 when there is none available")] +#[test_case(None, 10, 10; "can set DA height to 10 when there is none available")] +#[test_case(0, 10, 10; "can set DA height to 10 when it is 0")] +#[test_case(0, None, 0; "inserts are bypassed when height goes from 0 to 0")] +#[test_case(10, 11, 11; "can set DA height to 11 when it is 10")] +#[test_case(11, None, 11; "inserts are bypassed when height goes from 11 to 11")] +#[test_case(11, None, 10; "inserts are bypassed when height reverted from 11 to 10")] fn set_raises_da_height_monotonically( get: impl Into>, inserts: impl Into>, diff --git a/crates/services/relayer/src/service/state/test.rs b/crates/services/relayer/src/service/state/test.rs index 701181dfdb7..1c5901e8003 100644 --- a/crates/services/relayer/src/service/state/test.rs +++ b/crates/services/relayer/src/service/state/test.rs @@ -58,38 +58,36 @@ async fn test_eth_state_needs_to_sync_eth( .map(|g| g.0 .0) } -#[test_case(EthSyncGap::new(0, 0), 0 => None)] -#[test_case(EthSyncGap::new(0, 0), 1 => Some((0, 0)))] -#[test_case(EthSyncGap::new(0, 1), 0 => None)] -#[test_case(EthSyncGap::new(0, 1), 1 => Some((0, 0)))] -#[test_case(EthSyncGap::new(0, 1), 2 => Some((0, 1)))] -#[test_case(EthSyncGap::new(31, 31), 2 => Some((31, 31)))] -#[test_case(EthSyncGap::new(30, 31), 2 => Some((30, 31)))] -#[test_case(EthSyncGap::new(29, 31), 2 => Some((29, 30)))] -#[test_case(EthSyncGap::new(28, 31), 2 => Some((28, 29)))] -fn test_page(page: EthSyncGap, size: u64) -> Option<(u64, u64)> { - let page = page.page(size)?; +#[test_case(EthSyncGap::new(0, 0), 0 => None; "0 page size results in no page with no gap")] +#[test_case(EthSyncGap::new(0, 0), 1 => Some((0, 0)); "page includes 0 to 0 when size is 1")] +#[test_case(EthSyncGap::new(0, 1), 0 => None; "0 page size results in no page with gap")] +#[test_case(EthSyncGap::new(0, 1), 1 => Some((0, 0)); "gap shrunk to size 1 with size 1")] +#[test_case(EthSyncGap::new(0, 1), 2 => Some((0, 1)); "page matches gap when size is the same")] +#[test_case(EthSyncGap::new(31, 31), 2 => Some((31, 31)); "page includes 31 to 31 when size is 2")] +#[test_case(EthSyncGap::new(30, 31), 2 => Some((30, 31)); "page includes 30 to 31 when size is 2")] +#[test_case(EthSyncGap::new(29, 31), 2 => Some((29, 30)); "for 29 to 31 page only includes 29 to 30 when size is 2")] +#[test_case(EthSyncGap::new(28, 31), 2 => Some((28, 29)); "for 28 to 31 page only includes 28 to 29 when size is 2")] +fn test_page(eth_sync_gap: EthSyncGap, size: u64) -> Option<(u64, u64)> { + let page = eth_sync_gap.page(size)?; Some((page.oldest(), page.latest())) } -#[test_case(EthSyncGap::new(0, 0), 0, 1 => None)] -#[test_case(EthSyncGap::new(0, 0), 1, 1 => None)] -#[test_case(EthSyncGap::new(0, 1), 0, 1 => None)] -#[test_case(EthSyncGap::new(0, 1), 1, 1 => Some((1, 1)))] -#[test_case(EthSyncGap::new(0, 1), 1, 2 => None)] -#[test_case(EthSyncGap::new(0, 1), 2, 0 => Some((0, 1)))] -#[test_case(EthSyncGap::new(0, 1), 2, 1 => None)] -#[test_case(EthSyncGap::new(0, 1), 2, 2 => None)] -#[test_case(EthSyncGap::new(0, 3), 2, 0 => Some((0, 1)))] -#[test_case(EthSyncGap::new(0, 3), 2, 1 => Some((2, 3)))] -#[test_case(EthSyncGap::new(0, 3), 2, 2 => None)] -#[test_case(EthSyncGap::new(1, 8), 3, 0 => Some((1, 3)))] -#[test_case(EthSyncGap::new(1, 8), 3, 1 => Some((4, 6)))] -#[test_case(EthSyncGap::new(1, 8), 3, 2 => Some((7, 8)))] -#[test_case(EthSyncGap::new(1, 8), 3, 3 => None)] -fn test_page_reduce(page: EthSyncGap, size: u64, n: usize) -> Option<(u64, u64)> { - let mut page = page.page(size)?; - for _ in 0..n { +#[test_case(EthSyncGap::new(0, 0), 1, 1 => None; "size one page can't be reduced")] +#[test_case(EthSyncGap::new(0, 1), 1, 1 => Some((1, 1)); "page of size 1 for gap of size 2 can be reduced")] +#[test_case(EthSyncGap::new(0, 1), 1, 2 => None; "page of size 1 for gap of size 2 can't be reduced twice")] +#[test_case(EthSyncGap::new(0, 1), 2, 1 => None; "page of size 2 for gap of size 2 can't be reduced")] +#[test_case(EthSyncGap::new(0, 3), 2, 1 => Some((2, 3)); "page of size 2 for gap of size 4 can be reduced")] +#[test_case(EthSyncGap::new(0, 3), 2, 2 => None; "page of size 2 for gap of size 4 can't be reduced twice")] +#[test_case(EthSyncGap::new(1, 8), 3, 1 => Some((4, 6)); "page of size 3 for gap of size 8 can be reduced")] +#[test_case(EthSyncGap::new(1, 8), 3, 2 => Some((7, 8)); "page of size 3 for gap of size 8 can be reduced twice")] +#[test_case(EthSyncGap::new(1, 8), 3, 3 => None; "page of size 3 for gap of size 8 can't be reduced three times")] +fn test_page_reduce( + eth_page_gap: EthSyncGap, + size: u64, + reduce_count: usize, +) -> Option<(u64, u64)> { + let mut page = eth_page_gap.page(size)?; + for _ in 0..reduce_count { page = page.reduce()?; } Some((page.oldest(), page.latest())) diff --git a/crates/services/relayer/src/service/synced.rs b/crates/services/relayer/src/service/synced.rs index e240edd56cb..f9573e353e9 100644 --- a/crates/services/relayer/src/service/synced.rs +++ b/crates/services/relayer/src/service/synced.rs @@ -19,12 +19,15 @@ pub fn update_synced(synced: &NotifySynced, state: &EthState) { /// state has become synced. fn update_synced_inner( synced: &watch::Sender>, - is_synced: Option, + new_sync_state: Option, ) { synced.send_if_modified(|last_state| { - let r = is_synced.is_some(); - *last_state = is_synced.map(DaBlockHeight::from); - r + if let Some(val) = new_sync_state { + *last_state = Some(DaBlockHeight::from(val)); + true + } else { + false + } }); } @@ -40,16 +43,16 @@ mod tests { // until a future state change that puts the relayer in sync // with the ethereum node. // - // previous_state, new_state => (state, should_wait) - #[test_case(false, false => (false, true))] - #[test_case(false, true => (true, false))] - #[test_case(true, true => (true, false))] - #[test_case(true, false => (false, true))] - fn can_update_sync(was_synced: bool, is_synced: bool) -> (bool, bool) { - let (tx, rx) = watch::channel(was_synced.then_some(0u64.into())); + // previous_state, new_state => keep waiting + #[test_case(None, None => true; "if nothing updated with nothing then keep waiting")] + #[test_case(None, Some(0) => false; "if nothing updated with something then stop waiting")] + #[test_case(Some(0), Some(0) => false; "if something updated with same thing then stop waiting")] + #[test_case(Some(0), None => true; "if something updated with nothing then keep waiting")] + #[test_case(Some(0), Some(1) => false; "if something updated with something new then stop waiting")] + fn can_update_sync(previous_state: Option, new_state: Option) -> bool { + let (tx, rx) = watch::channel(previous_state.map(Into::into)); assert!(!rx.has_changed().unwrap()); - update_synced_inner(&tx, is_synced.then_some(0u64)); - let is_in_sync = rx.borrow().is_some(); - (is_in_sync, !rx.has_changed().unwrap()) + update_synced_inner(&tx, new_state); + !rx.has_changed().unwrap() } } diff --git a/tests/tests/sync.rs b/tests/tests/sync.rs index e4962bf8423..eb806c77a89 100644 --- a/tests/tests/sync.rs +++ b/tests/tests/sync.rs @@ -60,9 +60,9 @@ async fn test_producer_getting_own_blocks_back() { validator.consistency_10s(&expected).await; } -#[test_case(1)] -#[test_case(10)] -#[test_case(100)] +#[test_case(1; "partition with 1 tx")] +#[test_case(10; "partition with 10 txs")] +#[test_case(100; "partition with 100 txs")] #[tokio::test(flavor = "multi_thread")] async fn test_partition_single(num_txs: usize) { // Create a random seed based on the test parameters. @@ -118,12 +118,12 @@ async fn test_partition_single(num_txs: usize) { validators["Carol"].consistency_20s(&expected).await; } -#[test_case(1, 3, 3)] -#[test_case(10, 3, 3)] -#[test_case(100, 3, 3)] -#[test_case(1, 8, 4)] -#[test_case(10, 8, 4)] -#[test_case(100, 8, 4)] +#[test_case(1, 3, 3; "partition with 1 tx 3 validators 3 partitions")] +#[test_case(10, 3, 3; "partition with 10 txs 3 validators 3 partitions")] +#[test_case(100, 3, 3; "partition with 100 txs 3 validators 3 partitions")] +#[test_case(1, 8, 4; "partition with 1 tx 8 validators 4 partitions")] +#[test_case(10, 8, 4; "partition with 10 txs 8 validators 4 partitions")] +#[test_case(100, 8, 4; "partition with 100 txs 8 validators 4 partitions")] #[tokio::test(flavor = "multi_thread")] async fn test_partitions_larger_groups( num_txs: usize,