aboutsummaryrefslogtreecommitdiffstats
path: root/src/simtest/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/simtest/mod.rs')
-rw-r--r--src/simtest/mod.rs52
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