Skip to content

Commit

Permalink
Early exit and tracing for no clients (#213)
Browse files Browse the repository at this point in the history
  • Loading branch information
mcches authored Jan 30, 2025
1 parent bd05dad commit db51c71
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 14 deletions.
8 changes: 4 additions & 4 deletions src/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use super::Result;
type Software<'a> = Box<dyn Fn() -> Pin<Box<dyn Future<Output = Result>>> + 'a>;

/// Runtime kinds.
enum Kind<'a> {
pub enum Kind<'a> {
/// A runtime for executing test code.
Client,

Expand All @@ -33,8 +33,8 @@ enum Kind<'a> {
/// The tokio runtime is paused (see [`Builder::start_paused`]), which gives us
/// control over when and how to advance time. In particular, see [`Rt::tick`],
/// which lets the runtime do a bit more work.
pub(crate) struct Rt<'a> {
kind: Kind<'a>,
pub struct Rt<'a> {
pub kind: Kind<'a>,

/// Handle to the Tokio runtime driving this simulated host. Each runtime
/// may have a different sense of "now" which simulates clock skew.
Expand All @@ -44,7 +44,7 @@ pub(crate) struct Rt<'a> {
local: LocalSet,

/// A user readable name to identify the node.
pub(crate) nodename: Arc<str>,
pub nodename: Arc<str>,

/// Optional handle to a host's software. When software finishes, the handle is
/// consumed to check for error, which is propagated up to fail the simulation.
Expand Down
32 changes: 22 additions & 10 deletions src/sim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use tokio::time::Duration;
use tracing::Level;

use crate::host::HostTimer;
use crate::{for_pairs, Config, LinksIter, Result, Rt, ToIpAddr, ToIpAddrs, World, TRACING_TARGET};
use crate::{
for_pairs, rt, Config, LinksIter, Result, Rt, ToIpAddr, ToIpAddrs, World, TRACING_TARGET,
};

/// A handle for interacting with the simulation.
pub struct Sim<'a> {
Expand Down Expand Up @@ -333,11 +335,21 @@ impl<'a> Sim<'a> {
f(top.iter_mut())
}

/// Run the simulation to completion.
/// Run the simulation until all client hosts have completed.
///
/// Executes a simple event loop that calls [step](#method.step) each iteration,
/// returning early if any host software errors.
/// Executes a simple event loop that calls [step](#method.step) each
/// iteration, returning early if any host software errors.
pub fn run(&mut self) -> Result {
// check if we have any clients
if !self
.rts
.iter()
.any(|(_, rt)| matches!(rt.kind, rt::Kind::Client))
{
tracing::info!(target: TRACING_TARGET, "No client hosts registered, exiting simulation");
return Ok(());
}

loop {
let is_finished = self.step()?;

Expand All @@ -357,7 +369,7 @@ impl<'a> Sim<'a> {
///
/// Returns whether or not all clients have completed.
pub fn step(&mut self) -> Result<bool> {
tracing::trace!("step {}", self.steps);
tracing::trace!(target: TRACING_TARGET, "step {}", self.steps);

let tick = self.config.tick;
let mut is_finished = true;
Expand Down Expand Up @@ -884,11 +896,11 @@ mod test {
}
});

sim.run()?;
sim.step()?;
assert_eq!(tick_ms - 1, actual.load(Ordering::SeqCst));

sim.bounce("host");
sim.run()?;
sim.step()?;
assert_eq!((tick_ms * 2) - 1, actual.load(Ordering::SeqCst));

Ok(())
Expand All @@ -902,7 +914,7 @@ mod test {
Err("Host software finished unexpectedly")?
});

assert!(sim.run().is_err());
assert!(sim.step().is_err());
}

#[test]
Expand Down Expand Up @@ -1087,10 +1099,10 @@ mod test {
});
}

sim.run()?;
sim.step()?;
assert_eq!(count.load(Ordering::SeqCst), 3);
sim.bounce(regex::Regex::new("host-[12]")?);
sim.run()?;
sim.step()?;
assert_eq!(count.load(Ordering::SeqCst), 5);

Ok(())
Expand Down

0 comments on commit db51c71

Please sign in to comment.