diff options
Diffstat (limited to 'src/simtest/mod.rs')
| -rw-r--r-- | src/simtest/mod.rs | 52 |
1 files changed, 44 insertions, 8 deletions
diff --git a/src/simtest/mod.rs b/src/simtest/mod.rs index be2dc7b..61c81d1 100644 --- a/src/simtest/mod.rs +++ b/src/simtest/mod.rs @@ -20,12 +20,12 @@ use std::future::Future; use std::sync::Arc; use std::time::Duration; -use automerge::{AutoCommit, ChangeHash}; use serde_json::Value as JsonValue; use tokio::time::Instant; use crate::document::replica::Epoch; use crate::document::store; +use crate::document::{ChangeHash, Document}; use crate::files::Files; use crate::identity::NodeKey; use crate::locks::RwLockExt; @@ -33,7 +33,7 @@ use crate::node::{self, Node, NodeConfig}; use crate::state::{AppState, PeerState, Timing}; use crate::swarm::bootstrap::{self, Start}; use crate::transport::identity::IdentityConfig; -use crate::transport::sim::SimNet; +use crate::transport::sim::{DELIVERY_LIMIT, SimNet}; /// Keepalive of simulated nodes: dormancy after 1 s, probes of dormant peers every /// 2.5 s (`Timing::new`). @@ -41,9 +41,9 @@ pub(crate) const KEEPALIVE: Duration = Duration::from_millis(250); /// First wait for a sync answer before sending again (10 s in production, where large /// messages take a while): a lost sync message costs a test 1 s, a heal 2 s. pub(crate) const SYNC_REPLY_TIMEOUT: Duration = Duration::from_secs(1); -/// How long the simulated net may take to deliver a message: well above its delays. -/// A catch-up source that stops sending sync messages is given up after this. -pub(crate) const DELIVERY_LIMIT: Duration = Duration::from_secs(3); +/// How long tests wait for what should happen within a few keepalives: joining, +/// registering, converging. +pub(crate) const SOON: Duration = Duration::from_secs(10); /// A simulated swarm: the net and the nodes started on it. pub(crate) struct Sim { @@ -65,6 +65,16 @@ impl Sim { } } + /// [`new`](Self::new), with messages put into bytes by `codec` (a transport's + /// envelope) instead of the wire encoding alone. + #[cfg_attr(not(feature = "mycelium"), allow(dead_code))] + pub(crate) fn with_codec(seed: u64, codec: crate::transport::sim::Codec) -> Self { + Self { + net: SimNet::with_codec(seed, codec), + ..Self::new(seed) + } + } + /// [`new`](Self::new), with every node under the identity layer: its key derived /// from its name, its node ID as `local_id`. pub(crate) fn with_identity(seed: u64) -> Self { @@ -97,12 +107,14 @@ impl Sim { more: Vec::new(), }), initial_epoch: Epoch::GENESIS, - initial_doc: AutoCommit::new(), + initial_doc: Document::new(), earlier_actors: Vec::new(), timing: Timing::new(KEEPALIVE, SYNC_REPLY_TIMEOUT, DELIVERY_LIMIT), neighbours_k: 8, alias: Some(id.to_owned()), electorate_window: Duration::from_secs(30 * 24 * 3600), + clock_skew_warn: Duration::from_secs(2), + superseded_writes: Default::default(), blob_chunk_bytes: 64 * 1024, swarm_key: None, protocol_writers: HashSet::new(), @@ -132,6 +144,30 @@ impl Sim { } } +impl Sim { + /// Restarts node `id`: its process is gone, as if it crashed (`SimNet::restart`: + /// what it still sends is lost), and a new one starts on the same ID, as + /// [`start_with`](Self::start_with) starts one. Nothing carries over but what + /// `adjust` gives it (its node key, under the identity layer, by its name). + pub(crate) fn restart_with( + &self, + id: &str, + seeds: &[&str], + start: Start, + adjust: impl FnOnce(&mut NodeConfig), + ) -> AppState { + { + let mut nodes = self.nodes.lock().unwrap(); + for (_, old) in nodes.iter().filter(|(name, _)| name == id) { + old.closing.send_replace(true); + } + nodes.retain(|(name, _)| name != id); + } + self.net.restart(id); + self.start_with(id, seeds, start, adjust) + } +} + /// Logs to the test output if `RUST_LOG` is set. fn init_logging() { if std::env::var_os("RUST_LOG").is_some() { @@ -242,11 +278,11 @@ impl Sim { ago(p.last_seen), ago(p.last_sync_rx), p.is_unreachable(), - p.sync.automerge_view().0.map(|heads| heads + p.sync.sync_view().0.map(|heads| heads .iter() .map(|head| head.to_string()[..8].to_owned()) .collect::<Vec<_>>()), - p.sync.automerge_view().1, + p.sync.sync_view().1, p.sync.sending.is_some(), p.sync .reply |
