From 1b33229dd2d6f80cc544a3a5709c5355e6afa2bd Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Wed, 6 Aug 2025 12:25:49 +0100 Subject: [PATCH] radicle: test Announcer::timed_out on success Ensure that if the Announcer has reached a success case, that if `Announcer::timed_out` is called, it will still return the success. --- crates/radicle/src/node/sync/announce.rs | 46 ++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/crates/radicle/src/node/sync/announce.rs b/crates/radicle/src/node/sync/announce.rs index ece7f722..701dbb72 100644 --- a/crates/radicle/src/node/sync/announce.rs +++ b/crates/radicle/src/node/sync/announce.rs @@ -1104,6 +1104,52 @@ mod test { ); } + #[test] + fn timed_out_after_reaching_success() { + let local = arbitrary::gen::(0); + let unsynced = arbitrary::set::(3..=3) + .into_iter() + .collect::>(); + + let config = AnnouncerConfig::public( + local, + ReplicationFactor::must_reach(2), + BTreeSet::new(), + BTreeSet::new(), + unsynced.clone(), + ); + + let mut announcer = Announcer::new(config).unwrap(); + + // Sync with enough nodes to reach the target + let mut synced_nodes = BTreeMap::new(); + for node in unsynced { + let duration = time::Duration::from_secs(1); + synced_nodes.insert(node, SyncStatus::Synced { duration }); + + match announcer.synced_with(node, duration) { + ControlFlow::Continue(_) => continue, + ControlFlow::Break(_) => break, // Reached target + } + } + + // Now call timed_out even though we reached success + match announcer.timed_out() { + AnnouncerResult::Success(success) => { + // Should return Success since target was reached + assert_eq!( + success.outcome(), + SuccessfulOutcome::MinReplicationFactor { + preferred: 0, + synced: 2 + }, + "Should return success outcome even when called via timed_out" + ); + } + other => panic!("Expected Success via timed_out, got: {other:?}"), + } + } + #[test] fn cannot_construct_announcer() { let local = arbitrary::gen::(0);