Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 19 additions & 28 deletions src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{ops::RangeInclusive, time::SystemTime};

use rand::{RngCore, SeedableRng};
use rand::{rngs::SmallRng, SeedableRng};

use crate::*;

Expand Down Expand Up @@ -50,27 +50,15 @@ use crate::*;
///
/// ## Entropy and randomness
///
/// By default, the builder will use its own `rng` to determine the variation
/// in random factors that affect the simulation, like message latency, and
/// failure distributions. To make your tests deterministic, you can use your
/// own seeded `rng` provider when building the simulation through
/// `build_with_rng`.
///
/// For example:
///
/// ```
/// use rand::rngs::SmallRng;
/// use rand::SeedableRng;
///
/// let rng = SmallRng::seed_from_u64(0);
/// let sim = turmoil::Builder::new().build_with_rng(Box::new(rng));
/// ```
/// Turmoil uses a random number generator to determine the variation in random
/// factors that affect the simulation, like message latency, and failure
/// distributions. By default, this rng is randomly seeded. To make your tests
/// deterministic, you can provide your own seed through [`Builder::rng_seed`].
pub struct Builder {
config: Config,

ip_version: IpVersion,

link: config::Link,
rng_seed: Option<u64>,
}

impl Default for Builder {
Expand All @@ -88,6 +76,7 @@ impl Builder {
latency: Some(config::Latency::default()),
message_loss: Some(config::MessageLoss::default()),
},
rng_seed: None,
}
}

Expand Down Expand Up @@ -178,24 +167,26 @@ impl Builder {
self
}

/// Build a simulation with the settings from the builder.
///
/// This will use default rng with entropy from the device running.
pub fn build<'a>(&self) -> Sim<'a> {
self.build_with_rng(Box::new(rand::rngs::SmallRng::from_entropy()))
/// Seed for random numbers generated by turmoil.
pub fn rng_seed(&mut self, value: u64) -> &mut Self {
self.rng_seed = Some(value);
self
}

/// Build a sim with a provided `rng`.
///
/// This allows setting the random number generator used to fuzz
pub fn build_with_rng<'a>(&self, rng: Box<dyn RngCore>) -> Sim<'a> {
/// Build a simulation with the settings from the builder.
pub fn build<'a>(&self) -> Sim<'a> {
if self.link.latency().max_message_latency < self.link.latency().min_message_latency {
panic!("Maximum message latency must be greater than minimum.");
}

let rng = match self.rng_seed {
Some(seed) => SmallRng::seed_from_u64(seed),
None => SmallRng::from_entropy(),
};

let world = World::new(
self.link.clone(),
rng,
Box::new(rng),
self.ip_version.iter(),
self.config.tick,
);
Expand Down
2 changes: 1 addition & 1 deletion src/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub(crate) struct World {
pub(crate) current: Option<IpAddr>,

/// Random number generator used for all decisions. To make execution
/// determinstic, reuse the same seed.
/// deterministic, reuse the same seed.
pub(crate) rng: Box<dyn RngCore>,

/// Run duration for each host on every step.
Expand Down
Loading