Skip to main content

LabReactor

Struct LabReactor 

Source
pub struct LabReactor { /* private fields */ }
Expand description

A deterministic reactor for testing.

This reactor operates in virtual time and allows test code to inject events at specific points. It’s used by the lab runtime for deterministic testing of async I/O code.

Implementations§

Source§

impl LabReactor

Source

pub fn new() -> Self

Creates a new lab reactor.

Source

pub fn with_chaos(config: ChaosConfig) -> Self

Creates a new lab reactor with chaos injection enabled.

Source

pub fn inject_event(&self, token: Token, event: Event, delay: Duration)

Injects an event into the reactor at a specific delay from now.

The event will be delivered when virtual time advances past the delay. This is the primary mechanism for testing I/O-dependent code. Events scheduled at the same time are delivered in insertion order.

§Arguments
  • token - The token to associate with the event
  • event - The event to inject
  • delay - How far in the future to deliver the event
§Aliases

This method is also known as schedule_event() in the spec.

Source

pub fn schedule_event(&self, token: Token, event: Event, delay: Duration)

Alias for inject_event to match the spec terminology.

Schedules an event for future delivery at a specific delay from now.

Source

pub fn set_ready(&self, token: Token, event: Event)

Makes a source immediately ready for the specified event type.

The event will be delivered on the next call to poll(). Multiple calls to set_ready() for the same token append events.

§Arguments
  • token - The token to make ready
  • event - The event type (readable, writable, etc.)
Source

pub fn now(&self) -> Time

Returns the current virtual time.

Source

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

Returns the next scheduled event time, if any.

This is useful for driving the lab runtime forward to the next I/O event without relying on wall-clock time.

Source

pub fn advance_time(&self, duration: Duration)

Advances virtual time by the specified duration.

This is useful for testing timeout behavior without going through poll().

Source

pub fn advance_time_to(&self, target: Time)

Advances virtual time to a specific target time.

If the target time is before the current time, this is a no-op. Events scheduled between the current time and target time will be delivered on the next poll() call.

§Arguments
  • target - The target virtual time to advance to
Source

pub fn chaos_stats(&self) -> ChaosStats

Returns a snapshot of global chaos statistics accumulated by this reactor.

Source

pub fn last_io_error_kind(&self) -> Option<ErrorKind>

Returns the last global chaos I/O error kind injected by this reactor.

Source

pub fn check_and_clear_wake(&self) -> bool

Checks if the reactor has been woken.

Clears the wake flag and returns its previous value.

Source

pub fn set_fault_config(&self, token: Token, config: FaultConfig) -> Result<()>

Sets the fault configuration for a specific token.

This enables per-connection fault injection, allowing tests to simulate failures on specific connections while others remain healthy.

§Arguments
  • token - The token to configure faults for
  • config - The fault configuration to apply
§Returns

Returns Err if the token is not registered.

§Example
use asupersync::runtime::reactor::{LabReactor, FaultConfig, Token};
use std::io;

let reactor = LabReactor::new();
let token = Token::new(1);
// ... register token ...

let config = FaultConfig::new()
    .with_error_probability(0.5)
    .with_error_kinds(vec![io::ErrorKind::ConnectionReset]);
reactor.set_fault_config(token, config)?;
Source

pub fn clear_fault_config(&self, token: Token) -> Result<()>

Clears fault configuration for a token.

Removes any per-token fault injection, returning to normal behavior.

§Returns

Returns Err if the token is not registered.

Source

pub fn inject_error(&self, token: Token, kind: ErrorKind) -> Result<()>

Injects an immediate error for the next event on a token.

The next event delivered for this token will be converted to an error event with the specified ErrorKind. This is a one-shot operation; subsequent events are not affected unless inject_error is called again.

§Arguments
  • token - The token to inject an error for
  • kind - The error kind to inject
§Returns

Returns Err if the token is not registered.

§Example
use asupersync::runtime::reactor::{LabReactor, Token};
use std::io;

let reactor = LabReactor::new();
let token = Token::new(1);
// ... register token ...

// The next event for this token will be an error
reactor.inject_error(token, io::ErrorKind::BrokenPipe)?;
Source

pub fn inject_close(&self, token: Token) -> Result<()>

Injects a connection close (HUP) for a token.

Marks the token as closed, simulating the remote end closing the connection. The next poll will deliver HUP even if no readiness is queued for the token.

§Arguments
  • token - The token to close
§Returns

Returns Err if the token is not registered.

§Example
use asupersync::runtime::reactor::{LabReactor, Token};

let reactor = LabReactor::new();
let token = Token::new(1);
// ... register token ...

// Simulate remote close
reactor.inject_close(token)?;
// Next poll will deliver HUP
Source

pub fn partition(&self, token: Token, partitioned: bool) -> Result<()>

Sets the partition state for a token.

When partitioned, events for this token are dropped rather than delivered, simulating a network partition. This is useful for testing timeout handling and partition recovery.

§Arguments
  • token - The token to partition
  • partitioned - true to enable partition, false to disable
§Returns

Returns Err if the token is not registered.

§Example
use asupersync::runtime::reactor::{LabReactor, Token, Interest, Event};
use std::time::Duration;

let reactor = LabReactor::new();
let token = Token::new(1);
// ... register token ...

// Simulate network partition
reactor.partition(token, true)?;
reactor.inject_event(token, Event::readable(token), Duration::ZERO);

// Event will be dropped, not delivered
let mut events = Events::with_capacity(10);
reactor.poll(&mut events, Some(Duration::ZERO))?;
assert!(events.is_empty());

// Restore connectivity
reactor.partition(token, false)?;
Source

pub fn last_injected_error(&self, token: Token) -> Option<ErrorKind>

Returns the last error kind injected for a token (for diagnostics).

Source

pub fn fault_stats(&self, token: Token) -> Option<(u64, u64, u64)>

Returns fault injection statistics for a token.

Returns (injected_errors, injected_closes, dropped_events).

Trait Implementations§

Source§

impl Debug for LabReactor

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Default for LabReactor

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Reactor for LabReactor

Source§

fn register( &self, _source: &dyn Source, token: Token, interest: Interest, ) -> Result<()>

Registers interest in I/O events for a source. Read more
Source§

fn modify(&self, token: Token, interest: Interest) -> Result<()>

Modifies the interest set for an existing registration. Read more
Source§

fn deregister(&self, token: Token) -> Result<()>

Deregisters a previously registered source by token. Read more
Source§

fn poll(&self, events: &mut Events, timeout: Option<Duration>) -> Result<usize>

Polls for I/O events, blocking up to timeout. Read more
Source§

fn wake(&self) -> Result<()>

Wakes the reactor from a blocking poll() call. Read more
Source§

fn registration_count(&self) -> usize

Returns the number of active registrations. Read more
Source§

fn is_empty(&self) -> bool

Returns true if no sources are currently registered. 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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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, 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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V