use std::collections::VecDeque;
use super::*;
struct Scripted {
now: PipeStatus,
later: VecDeque<PipeStatus>,
}
impl Scripted {
fn new(now: PipeStatus, later: &[PipeStatus]) -> Self {
Self {
now,
later: later.iter().copied().collect(),
}
}
}
impl AsyncStatus for Scripted {
fn current(&self) -> PipeStatus {
self.now
}
async fn changed(&mut self) -> PipeStatus {
match self.later.pop_front() {
Some(next) => {
self.now = next;
next
}
None => std::future::pending().await,
}
}
}
const BRIEFLY: Duration = Duration::from_millis(50);
#[tokio::test]
async fn a_pipe_that_is_already_carrying_is_not_waited_for() {
let status = Scripted::new(PipeStatus::Direct, &[]);
first_contact(status, BRIEFLY)
.await
.expect("a connected pipe must not be reported as unreachable");
}
#[tokio::test]
async fn a_pairing_that_forms_a_moment_later_is_waited_for() {
let status = Scripted::new(PipeStatus::Idle, &[PipeStatus::Relayed]);
first_contact(status, BRIEFLY)
.await
.expect("a pipe that connects while waiting has reached its peer");
}
#[tokio::test]
async fn a_serve_side_that_never_answers_is_reported_rather_than_waited_on_for_ever() {
let status = Scripted::new(PipeStatus::Idle, &[]);
let e = first_contact(status, BRIEFLY)
.await
.expect_err("an absent peer must not be reported as reachable");
assert_eq!(
e.to_string(),
"could not reach the serve side, directly or via a relay"
);
}
#[tokio::test]
async fn a_pipe_that_closes_before_it_connects_is_reported_at_once() {
let status = Scripted::new(PipeStatus::Idle, &[PipeStatus::Closed]);
let started = std::time::Instant::now();
let e = first_contact(status, BRIEFLY)
.await
.expect_err("a closed pipe never reached anyone");
assert!(
started.elapsed() < BRIEFLY,
"a terminal state must end the wait rather than run it out"
);
assert_eq!(
e.to_string(),
"could not reach the serve side, directly or via a relay"
);
}