Skip to main content

LabRuntime

Struct LabRuntime 

Source
pub struct LabRuntime {
    pub state: RuntimeState,
    pub scheduler: Arc<Mutex<LabScheduler>>,
    pub oracles: OracleSuite,
    /* private fields */
}
Expand description

The deterministic lab runtime.

This runtime is designed for testing and provides:

  • Virtual time instead of wall-clock time
  • Deterministic scheduling based on a seed
  • Trace capture for debugging and replay
  • Chaos injection for stress testing

Fields§

§state: RuntimeState

Runtime state (public for tests and oracle access).

§scheduler: Arc<Mutex<LabScheduler>>

Scheduler.

§oracles: OracleSuite

Oracle suite for invariant verification.

Implementations§

Source§

impl LabRuntime

Source

pub fn new(config: LabConfig) -> LabRuntime

Creates a new lab runtime with the given configuration.

Source

pub fn with_seed(seed: u64) -> LabRuntime

Creates a lab runtime with the default configuration.

Source

pub const fn now(&self) -> Time

Returns the current virtual time.

Source

pub const fn steps(&self) -> u64

Returns the number of steps executed.

Source

pub const fn config(&self) -> &LabConfig

Returns a reference to the configuration.

Source

pub fn lab_reactor(&self) -> &Arc<LabReactor>

Returns a handle to the lab reactor for deterministic I/O injection.

Source

pub fn trace(&self) -> &TraceBufferHandle

Returns a reference to the trace buffer handle.

Source

pub fn detected_races(&self) -> RaceReport

Returns a race report derived from the current trace buffer.

Source

pub fn chaos_stats(&self) -> &ChaosStats

Returns a reference to the chaos statistics.

Source

pub fn certificate(&self) -> &ScheduleCertificate

Returns the schedule certificate for determinism verification.

Source

pub fn has_replay_recording(&self) -> bool

Returns true if replay recording is enabled.

Source

pub fn replay_recorder(&self) -> &TraceRecorder

Returns a reference to the replay recorder.

Source

pub fn take_replay_trace(&mut self) -> Option<ReplayTrace>

Takes the replay trace, leaving an empty trace in place.

Returns None if recording is disabled.

Source

pub fn finish_replay_trace(&mut self) -> Option<ReplayTrace>

Finishes recording and returns the replay trace.

This consumes the replay recorder. Returns None if recording is disabled.

Source

pub fn has_chaos(&self) -> bool

Returns true if chaos injection is enabled.

Source

pub fn is_quiescent(&self) -> bool

Returns true if the runtime is quiescent.

Source

pub fn advance_time(&mut self, nanos: u64)

Advances virtual time by the given number of nanoseconds.

Source

pub fn advance_time_to(&mut self, time: Time)

Advances time to the given absolute time.

If the target time is before the current time, logs an error and does nothing (time cannot go backward).

Source

pub fn advance_to_next_timer(&mut self) -> usize

Advances virtual time to the next timer deadline.

If a timer is pending, advances time to its deadline, processes the expired timer(s), and returns the number of wakeups triggered. Returns 0 if no timers are pending.

Source

pub fn next_timer_deadline(&self) -> Option<Time>

Returns the next timer deadline, if any timers are pending.

Source

pub fn pending_timer_count(&self) -> usize

Returns the number of pending timers.

Source

pub fn run_with_auto_advance(&mut self) -> VirtualTimeReport

Runs until quiescent, automatically advancing virtual time to pending timer deadlines whenever all tasks are idle.

This enables “instant timeout testing”: a scenario that would take 24 hours of wall-clock time completes in <1 second because every sleep/timeout deadline is jumped to instantly.

The loop is:

  1. Run until idle (no runnable tasks in scheduler).
  2. If timers are pending, advance time to next deadline → go to 1.
  3. If no timers and quiescent → done.

Returns a VirtualTimeReport with execution statistics.

Source

pub fn pause_clock(&self)

Pauses the virtual clock, freezing time at the current value.

While paused, advance_time() and timer processing still work at the LabRuntime level (they update the runtime’s own virtual_time field), but the underlying VirtualClock visible to tasks via Cx::now() is frozen. This is useful for testing timeout detection: tasks that call Cx::now() will see time standing still while the runtime can still orchestrate scheduling.

Source

pub fn resume_clock(&self)

Resumes a paused virtual clock.

Source

pub fn is_clock_paused(&self) -> bool

Returns true if the virtual clock is currently paused.

Source

pub fn inject_clock_skew(&mut self, skew_nanos: u64)

Injects a clock skew by jumping time forward by skew_nanos.

This simulates clock drift or NTP corrections. A warning is logged because large jumps may affect lease/timeout correctness.

Source

pub fn run_until_quiescent(&mut self) -> u64

Runs until quiescent or max steps reached.

Returns the number of steps executed.

Source

pub fn run_until_idle(&mut self) -> u64

Runs until there are no runnable tasks in the scheduler.

This is intentionally weaker than Self::run_until_quiescent:

  • It does not require all tasks to complete.
  • It does not require all obligations to be resolved.

Use this when a test wants to “poll once” until the system is idle (e.g. a task is blocked on a channel receive) without forcing full completion and drain.

Source

pub fn run_until_quiescent_with_report(&mut self) -> LabRunReport

Runs until quiescent (or max_steps is reached) and returns a structured report.

Source

pub fn report(&mut self) -> LabRunReport

Build a structured report for the current runtime state.

This does not advance execution.

Source

pub fn run_until_quiescent_spork_report( &mut self, app: impl Into<String>, attachments: Vec<HarnessAttachmentRef>, ) -> SporkHarnessReport

Runs until quiescent (or max_steps is reached) and returns a Spork harness report.

Source

pub fn spork_report( &mut self, app: impl Into<String>, attachments: Vec<HarnessAttachmentRef>, ) -> SporkHarnessReport

Build a Spork harness report for the current runtime state.

This does not advance execution.

Source

pub fn build_crashpack_for_report( &self, run: &LabRunReport, ) -> Option<CrashPack>

Build an in-memory crashpack for a failing report.

Returns None for passing reports.

Source

pub fn enable_deadline_monitoring(&mut self, config: MonitorConfig)

Enable deadline monitoring with the default warning handler.

Source

pub fn enable_deadline_monitoring_with_handler<F>( &mut self, config: MonitorConfig, f: F, )
where F: Fn(DeadlineWarning) + Send + Sync + 'static,

Enable deadline monitoring with a custom warning handler.

Source

pub fn deadline_monitor_mut(&mut self) -> Option<&mut DeadlineMonitor>

Returns a mutable reference to the deadline monitor, if enabled.

Source

pub fn step_for_test(&mut self)

Public wrapper for step() for use in tests.

This is useful for testing determinism across multiple step executions.

Source

pub fn check_invariants(&mut self) -> Vec<InvariantViolation>

Checks invariants and returns any violations.

Trait Implementations§

Source§

impl Debug for LabRuntime

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, _span: NoopSpan) -> Self

Instruments this future with a span (no-op when disabled).
Source§

fn in_current_span(self) -> Self

Instruments this future with the current span (no-op when disabled).
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more