diff options
| author | tv <tv@krebsco.de> | 2026-10-25 22:24:20 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-25 22:24:20 +0100 |
| commit | 0c8e2565b4c80c09f0ba5076b1e27762f2b16eeb (patch) | |
| tree | 08e06fd15ab6555101f8fb0fa19f92a4a83166de /src | |
| parent | cd9f068270e2258c571bbc01465fcf39f054848b (diff) | |
add convergence over lossy-links test
Diffstat (limited to 'src')
| -rw-r--r-- | src/simtest/timing.rs | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/simtest/timing.rs b/src/simtest/timing.rs index 2633235..df7849f 100644 --- a/src/simtest/timing.rs +++ b/src/simtest/timing.rs @@ -14,6 +14,8 @@ use crate::transport::{HeadsSummary, HelloRequest, Keepalive, ParsedMessage, Run /// Long enough for anything that should happen within a few keepalives. const SOON: Duration = Duration::from_secs(10); +/// With lost messages: several reply timeouts (1 s, doubling) and heals in a row. +const LOSSY: Duration = Duration::from_secs(30); #[tokio::test(flavor = "multi_thread", worker_threads = 4)] async fn three_nodes_join_and_converge() { @@ -74,6 +76,37 @@ async fn converges_with_duplicated_and_reordered_messages() { assert!(sim.net.counts().duplicated > 0); } +/// Lost messages are made up for: sync messages by the reply timeout, sessions out of +/// step by the keepalive heal. Joining under loss too: HELLOs are retried. +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn converges_over_lossy_links() { + let sim = Sim::new(5); + sim.net.set_default_link(LinkParams { + loss: 0.15, + duplicate: 0.05, + delay: (Duration::from_millis(1), Duration::from_millis(30)), + }); + let a = sim.start("a", &[], Start::Genesis); + let b = sim.start("b", &["a"], Start::Join); + let c = sim.start("c", &["a"], Start::Join); + let (a, b, c) = (&a, &b, &c); + sim.wait_ready(&[a, b, c], LOSSY).await; + + for round in 0..10 { + write(a, &format!("a/{round}"), json!(round)).await; + write(b, &format!("b/{round}"), json!(round)).await; + write(c, &format!("c/{round}"), json!(round)).await; + tokio::time::sleep(Duration::from_millis(50)).await; + } + sim.wait_converged(&[a, b, c], LOSSY).await; + for node in [a, b, c] { + for prefix in ["a", "b", "c"] { + assert_eq!(read(node, &format!("{prefix}/9")).await, Some(json!(9))); + } + } + assert!(sim.net.counts().lost > 0); +} + /// A peer that hears nothing for `dormant_after` is dormant; once messages flow again /// it is active, re-handshakes, and syncs what it missed. #[tokio::test(flavor = "multi_thread", worker_threads = 4)] |
