diff options
| author | tv <tv@krebsco.de> | 2026-10-26 06:09:02 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-26 06:09:02 +0100 |
| commit | d8738b3a74591587b0efc00edae37e5d46a02d4b (patch) | |
| tree | 0591869128a78ddd991a7c6d9410bf0e2ce81774 /src/simtest | |
| parent | 3be4ec3aa0e076e5386cfd1b93b07d12c40a88cb (diff) | |
forgotten nodes cancel their own records
Diffstat (limited to 'src/simtest')
| -rw-r--r-- | src/simtest/timing.rs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/simtest/timing.rs b/src/simtest/timing.rs index 4247090..06a2f12 100644 --- a/src/simtest/timing.rs +++ b/src/simtest/timing.rs @@ -375,3 +375,42 @@ async fn late_epoch_does_not_flip_a_peers_epoch() { assert_eq!(a.local_epoch(), Epoch::GENESIS); assert!(a.is_ready().await); } + +/// A swarm-wide forget of a node that is alive: nobody forgets it, and it cancels the +/// record itself. +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn forgotten_node_that_is_alive_cancels_its_record() { + use crate::document::store; + use crate::swarm::peer::forgotten_path; + + let sim = Sim::new(9); + 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], SOON).await; + + let record = forgotten_path(b.local_id()); + let written = record.clone(); + a.mutate_doc(move |doc| store::write_path(doc, &written, &json!({"at": 0, "by": "a"}))) + .await + .expect("write forget record"); + + // The forget check runs every 5 s. + for node in [a, b, c] { + let record = record.clone(); + sim.wait_until("the record is cancelled", SOON + SOON, move || { + let record = record.clone(); + async move { + store::read_path(&node.doc.read().await.doc, &record) + .expect("read") + .is_none() + } + }) + .await; + } + for node in [a, c] { + assert!(node.get_peer_state(b.local_id()).await.is_some()); + } + sim.wait_converged(&[a, b, c], SOON).await; +} |
