diff --git a/tines-core/tests/pair.rs b/tines-core/tests/pair.rs index 31a4cc1..b69a833 100644 --- a/tines-core/tests/pair.rs +++ b/tines-core/tests/pair.rs @@ -3,7 +3,7 @@ use common::PairTransport; use std::collections::BTreeSet; use tines_core::observation::Payload; -use tines_core::transport::{Event, FrameBuf, Transport}; +use tines_core::transport::{Event, FrameBuf, SendError, Transport}; use tines_core::{consts, LatestWins, MemStore, Node, ObserveError, Store}; #[test] @@ -206,3 +206,17 @@ fn third_party_observation_propagates_within_contact() { ); assert_eq!(nb.store().len(), 1); } + +#[test] +fn pair_transport_disconnect_enqueues_lost() { + let (mut a, _b) = PairTransport::pair(1500); + a.disconnect(); + assert_eq!(a.poll(), Some(Event::Lost(1))); +} + +#[test] +fn pair_transport_send_rejects_unreachable() { + let (mut a, _b) = PairTransport::pair(1500); + // a's only peer is 1; sending to 2 is unreachable. + assert_eq!(a.send(&2, b"hi"), Err(SendError::Unreachable)); +} diff --git a/tines-sim/src/transport.rs b/tines-sim/src/transport.rs index fbde1ee..adf8e1f 100644 --- a/tines-sim/src/transport.rs +++ b/tines-sim/src/transport.rs @@ -57,10 +57,11 @@ impl Transport for SimTransport { return Ok(()); } let buf = FrameBuf::from_slice(frame).map_err(|_| SendError::TooLarge)?; + let dup = w.rng.gen::() < w.cfg.dup; w.inboxes[*to].push_back(Event::Frame(self.me, buf.clone())); w.frames_sent += 1; - if w.rng.gen::() < w.cfg.dup { - w.inboxes[*to].push_back(Event::Frame(self.me, buf.clone())); + if dup { + w.inboxes[*to].push_back(Event::Frame(self.me, buf)); w.frames_sent += 1; } Ok(()) diff --git a/tines-sim/tests/props.rs b/tines-sim/tests/props.rs index 84b0af6..8848324 100644 --- a/tines-sim/tests/props.rs +++ b/tines-sim/tests/props.rs @@ -72,12 +72,19 @@ type Scenario = (usize, ContactTrace, Vec<(usize, Vec, Vec)>); fn scenario() -> impl Strategy { (2..=6usize).prop_flat_map(|nodes| { let trace = proptest::collection::vec(contact(nodes), 1..=12usize); - let obs = proptest::collection::vec(observation(), nodes..=nodes); - (trace, obs).prop_map(move |(contacts, per_node)| { + // Each node publishes 0..=10 observations, flattened to (node, topic, + // payload) triples so per-node counts vary across scenarios. + let per_node = proptest::collection::vec( + proptest::collection::vec(observation(), 0..=10usize), + nodes..=nodes, + ); + (trace, per_node).prop_map(move |(contacts, per_node)| { let trace = ContactTrace { contacts }; let mut list = Vec::new(); - for (node, (topic, payload)) in per_node.into_iter().enumerate() { - list.push((node, topic, payload)); + for (node, node_obs) in per_node.into_iter().enumerate() { + for (topic, payload) in node_obs { + list.push((node, topic, payload)); + } } (nodes, trace, list) })