use super::super::hold::{Ending, hold};
use super::{advertised, aside, echo, ops, refusal, row, set, wired, work};
use crate::channel::Channel;
use crate::channel::material::read_dir;
use crate::test_support::engine::Engine;
use crate::test_support::{Scratch, mint};
#[test]
fn a_refused_read_is_this_box_s_own_predecessor_and_is_dialled_again() {
let refused = "client \"foot-1\" already holds a read on this engine";
let (_scratch, engine, channel) = wired(vec![advertised(), refusal(refused)]);
assert_eq!(
hold(&channel, &set(), echo, &aside()),
Ending::Again {
said: refused.to_owned(),
predecessor: true,
served: false,
}
);
assert_eq!(ops(&engine), ["advertise", "invocations"]);
}
#[test]
fn a_refused_advertisement_is_over_and_not_a_predecessor() {
let refused = "this box's set is held by a serving connection";
let (_scratch, _engine, channel) = wired(vec![refusal(refused)]);
assert_eq!(
hold(&channel, &set(), echo, &aside()),
Ending::Over(refused.to_owned())
);
}
#[test]
fn a_refused_completion_is_over() {
let refused = "no invocation \"i-1\" is in flight";
let (_scratch, _engine, channel) = wired(vec![
advertised(),
work(vec![row("i-1", "Bash")]),
refusal(refused),
]);
assert_eq!(
hold(&channel, &set(), echo, &aside()),
Ending::Over(refused.to_owned())
);
}
#[test]
fn an_unusable_answer_is_over() {
let (_scratch, _engine, channel) = wired(vec![advertised(), advertised()]);
let Ending::Over(said) = hold(&channel, &set(), echo, &aside()) else {
panic!("an unusable answer must end the channel");
};
assert!(said.contains("not this machine's work"), "{said}");
}
#[test]
fn a_wire_that_goes_away_is_dialled_again() {
let scratch = Scratch::new();
mint::material(scratch.path());
let _engine = Engine::vanishes(scratch.path());
let held = read_dir(scratch.path())
.expect("readable")
.expect("provisioned");
let channel = Channel::open(&held).expect("opened");
let Ending::Again {
said,
predecessor,
served,
} = hold(&channel, &set(), echo, &aside())
else {
panic!("a dropped wire must be worth another dial");
};
assert!(!predecessor, "the wire is nobody's refusal");
assert!(!served, "it never got as far as an answered read");
assert!(said.contains("the channel to the engine failed"), "{said}");
}
#[test]
fn an_answered_read_marks_the_channel_as_having_served() {
let scratch = Scratch::new();
mint::material(scratch.path());
let _engine = Engine::flapping(
scratch.path(),
vec![Some(vec![advertised()]), Some(vec![work(vec![])]), None],
);
let held = read_dir(scratch.path())
.expect("readable")
.expect("provisioned");
let channel = Channel::open(&held).expect("opened");
let Ending::Again { served, .. } = hold(&channel, &set(), echo, &aside()) else {
panic!("a dropped wire must be worth another dial");
};
assert!(served, "the engine answered a read before the wire dropped");
}
#[test]
fn a_stream_that_answered_nothing_is_over() {
let scratch = Scratch::new();
mint::material(scratch.path());
let _engine = Engine::start(scratch.path(), crate::corpus::PROTOCOL, vec![vec![]]);
let held = read_dir(scratch.path())
.expect("readable")
.expect("provisioned");
let channel = Channel::open(&held).expect("opened");
assert_eq!(
hold(&channel, &set(), echo, &aside()),
Ending::Over("the engine ended the stream without answering".to_owned())
);
}
#[test]
fn a_completion_the_wire_swallowed_is_dialled_again() {
let scratch = Scratch::new();
mint::material(scratch.path());
let _engine = Engine::flapping(
scratch.path(),
vec![
Some(vec![advertised()]),
Some(vec![work(vec![row("i-1", "Bash")])]),
None,
],
);
let held = read_dir(scratch.path())
.expect("readable")
.expect("provisioned");
let channel = Channel::open(&held).expect("opened");
let Ending::Again { predecessor, .. } = hold(&channel, &set(), echo, &aside()) else {
panic!("a dropped completion must be worth another dial");
};
assert!(!predecessor, "the wire is nobody's refusal");
}