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>
impl<C: BrokerCore> Harness<C>
Sourcepub fn core_mut(&mut self) -> &mut C
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.
Sourcepub fn events(&self) -> &[CoreEvent]
pub fn events(&self) -> &[CoreEvent]
All events the core emitted since the last take_events, oldest first.
Sourcepub fn transmitted(&self) -> &[Outbound]
pub fn transmitted(&self) -> &[Outbound]
The log of every message the core wanted sent, oldest first. It is never cleared.
Sourcepub fn apply(&mut self, desired: &SubscriptionSet)
pub fn apply(&mut self, desired: &SubscriptionSet)
Tells the core the wanted subscriptions (BrokerCore::apply) and collects what it queues
to send.
Sourcepub fn feed_frame(&mut self, frame: C::Frame)
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.
Sourcepub fn feed_frame_at(&mut self, at: Instant, frame: C::Frame)
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.
Sourcepub fn advance_by(&mut self, delta: Duration)
pub fn advance_by(&mut self, delta: Duration)
Moves time forward by delta, firing every timer that falls due.
Sourcepub fn advance_to(&mut self, at: Instant)
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.
Sourcepub fn run_frames(&mut self, frames: &[FrameRecord<C::Frame>])
pub fn run_frames(&mut self, frames: &[FrameRecord<C::Frame>])
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));Sourcepub fn drain_transmit(&mut self) -> Vec<Outbound>
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.
Sourcepub fn take_events(&mut self) -> Vec<CoreEvent>
pub fn take_events(&mut self) -> Vec<CoreEvent>
Returns all collected events, oldest first, and empties the list.