diff --git a/src/builder.rs b/src/builder.rs index 03a0a32..b92a34a 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -170,6 +170,14 @@ impl Builder { self } + /// Enables running of nodes in random order. This allows exploration + /// of extra state space in multi-node simulations where race conditions + /// may arise based on message send/receive order. + pub fn enable_random_order(&mut self) -> &mut Self { + self.config.random_node_order = true; + self + } + /// Build a simulation with the settings from the builder. /// /// This will use default rng with entropy from the device running. diff --git a/src/config.rs b/src/config.rs index 5d1a0ee..09b912f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -39,6 +39,10 @@ pub(crate) struct Config { /// Enables tokio IO driver pub(crate) enable_tokio_io: bool, + + /// Enables running of host/client code in random order at each + /// simulation step + pub(crate) random_node_order: bool, } /// Configures link behavior. @@ -91,6 +95,7 @@ impl Default for Config { tcp_capacity: 64, udp_capacity: 64, enable_tokio_io: false, + random_node_order: false, } } } diff --git a/src/sim.rs b/src/sim.rs index 9fd5441..1cc69a4 100644 --- a/src/sim.rs +++ b/src/sim.rs @@ -1,3 +1,4 @@ +use rand::seq::SliceRandom; use std::cell::RefCell; use std::future::Future; use std::net::IpAddr; @@ -347,13 +348,18 @@ impl<'a> Sim<'a> { // Tick each host runtimes with running software. If the software // completes, extract the result and return early if an error is // encountered. - for (&addr, rt) in self + + let mut running: Vec<_> = self .rts .iter_mut() .filter(|(_, rt)| rt.is_software_running()) - { - let _span_guard = tracing::span!(Level::INFO, "node", name = &*rt.nodename).entered(); + .collect(); + if self.config.random_node_order { + running.shuffle(&mut self.world.borrow_mut().rng); + } + for (&addr, rt) in running { + let _span_guard = tracing::span!(Level::INFO, "node", name = &*rt.nodename,).entered(); { let mut world = self.world.borrow_mut(); // We need to move deliverable messages off the network and