Skip to main content

Harness

Struct Harness 

Source
pub struct Harness<C: BrokerCore> { /* private fields */ }
Expand description

Drives a BrokerCore with virtual time and records what comes out.

The harness owns the core and a clock that only moves when you move it. Feed frames, move time, then read the events the core emitted (events) and the messages it wanted to send (transmitted). There is no socket and no real waiting, so a test of a minute of silence takes no time.

After every call into the core the harness drains BrokerCore::poll_transmit into the transmitted log, and it fires the core’s timers whenever time passes their deadline.

§Examples

use brokapi_sansio::Harness;

let mut harness = Harness::new(core, t0);

// A frame arrives: the core answers with a pong.
harness.feed_frame("ping".to_string());
assert_eq!(harness.transmitted(), [Outbound::WsText("pong ping".to_string())]);

// 9 seconds of silence: the watchdog has not fired yet. 2 more: it has.
harness.advance_by(Duration::from_secs(9));
assert!(harness.events().is_empty());
harness.advance_by(Duration::from_secs(2));
let events = harness.take_events();
assert_eq!(events.len(), 1);
assert!(matches!(events[0].payload, Event::Resync { .. }));
assert!(harness.events().is_empty());

Implementations§

Source§

impl<C: BrokerCore> Harness<C>

Source

pub fn new(core: C, start: Instant) -> Self

Wraps core. The virtual clock starts at start.

Source

pub fn now(&self) -> Instant

The current virtual time.

Source

pub fn core(&self) -> &C

The core, for reading its state.

Source

pub fn core_mut(&mut self) -> &mut C

The core, for changing it directly. Messages it queues this way are collected on the next call that drains transmits, or by drain_transmit.

Source

pub fn events(&self) -> &[CoreEvent]

All events the core emitted since the last take_events, oldest first.

Source

pub fn transmitted(&self) -> &[Outbound]

The log of every message the core wanted sent, oldest first. It is never cleared.

Source

pub fn apply(&mut self, desired: &SubscriptionSet)

Tells the core the wanted subscriptions (BrokerCore::apply) and collects what it queues to send.

Source

pub fn feed_frame(&mut self, frame: C::Frame)

Delivers a frame to the core at the current virtual time, and collects its events and messages. Time does not move.

Source

pub fn feed_frame_at(&mut self, at: Instant, frame: C::Frame)

Moves time to at (firing due timers on the way, see advance_to), then delivers the frame.

Source

pub fn advance_by(&mut self, delta: Duration)

Moves time forward by delta, firing every timer that falls due.

Source

pub fn advance_to(&mut self, at: Instant)

Moves time to at, firing every timer that falls due on the way.

While the core’s poll_timeout is at or before at, the harness calls on_timeout with that deadline as the time, then asks again. So one call can fire several timers, each at its own time.

A core whose on_timeout leaves the same deadline in place makes this loop for ever. Move or clear the deadline in on_timeout.

at should not be earlier than now: the clock is set to at without a check.

Source

pub fn run_frames(&mut self, frames: &[FrameRecord<C::Frame>])
where C::Frame: Clone,

Replays a recorded session: each frame is delivered at its recorded time with feed_frame_at. Records must be in time order.

§Examples
use brokapi_sansio::{FrameRecord, Harness};

let mut harness = Harness::new(core, t0);
let session = [
    FrameRecord::new(t0 + Duration::from_secs(1), "a".to_string()),
    FrameRecord::new(t0 + Duration::from_secs(2), "b".to_string()),
];
harness.run_frames(&session);

assert_eq!(harness.transmitted().len(), 2);
assert_eq!(harness.now(), t0 + Duration::from_secs(2));
Source

pub fn drain_transmit(&mut self) -> Vec<Outbound>

Polls the core for messages it wants sent and returns the ones found by this call.

Every other harness method already does this and logs the result in transmitted, so the return value is usually empty. Call it after changing the core through core_mut. What it returns is also appended to the log.

Source

pub fn take_events(&mut self) -> Vec<CoreEvent>

Returns all collected events, oldest first, and empties the list.

Auto Trait Implementations§

§

impl<C> Freeze for Harness<C>
where C: Freeze,

§

impl<C> RefUnwindSafe for Harness<C>
where C: RefUnwindSafe,

§

impl<C> Send for Harness<C>
where C: Send,

§

impl<C> Sync for Harness<C>
where C: Sync,

§

impl<C> Unpin for Harness<C>
where C: Unpin,

§

impl<C> UnsafeUnpin for Harness<C>
where C: UnsafeUnpin,

§

impl<C> UnwindSafe for Harness<C>
where C: UnwindSafe,

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, 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, 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.