use super::{FIRST_RETRY, MAX_RETRY, OutboundLinkConfig, Slot, Wake};
use std::time::{Duration, Instant};
#[test]
fn peer_refused_open_is_counted_and_scheduled_like_a_failed_dial() -> Result<(), crate::ServerError>
{
let services = std::sync::Arc::new(
crate::server::connection::services::LiminalConnectionServices::empty()?,
);
let result = (|| {
let registry = crate::link_bridge::BridgeRegistry::default();
let wake = std::sync::Arc::new(Wake::default());
let mut slot = Slot {
entry: OutboundLinkConfig {
link_id: "orders".to_owned(),
peer_holder: "importer".to_owned(),
peer_address: None,
exports: vec!["orders".to_owned()],
},
bridge: None,
retry_at: None,
backoff: FIRST_RETRY,
stopped: false,
};
let now = Instant::now();
let reason = "link_refused:link_import needed".to_owned();
super::answered(
&mut slot,
super::ChoiceOutcome::Refused {
reason: reason.clone(),
},
&services,
®istry,
&wake,
true,
now,
)?;
let counters = registry.snapshot().remove("orders").unwrap_or_default();
assert_eq!(counters.refused, 1, "peer refusal absent from health");
assert_eq!(counters.dial_refused, 0);
assert!(counters.refused_subjects.is_empty());
assert_eq!(counters.last_refusal, Some(reason));
assert!(!slot.stopped, "peer refusal stopped retries");
assert_eq!(slot.retry_at, now.checked_add(FIRST_RETRY));
assert_eq!(slot.backoff, FIRST_RETRY * 2);
Ok(())
})();
let supervisor = crate::server::connection::ConnectionSupervisor::with_services(services)?;
let stopped = crate::server::runtime::runtime_links::shutdown(
&supervisor,
Duration::ZERO,
|| Ok(()),
(
&mut crate::server::runtime::runtime_links::ConfiguredLinks::default(),
|| Ok(()),
),
);
crate::server::runtime::raise_in_precedence(result, stopped)
}
#[test]
fn retry_backoff_starts_at_one_second_and_caps_at_thirty() -> Result<(), crate::ServerError> {
let mut slot = Slot {
entry: OutboundLinkConfig {
link_id: "orders".to_owned(),
peer_holder: "importer".to_owned(),
peer_address: None,
exports: vec!["orders".to_owned()],
},
bridge: None,
retry_at: None,
backoff: FIRST_RETRY,
stopped: false,
};
let now = Instant::now();
for seconds in [1, 2, 4, 8, 16, 30, 30] {
slot.schedule_at(now)?;
assert_eq!(slot.retry_at, now.checked_add(Duration::from_secs(seconds)));
}
assert_eq!(slot.backoff, MAX_RETRY);
Ok(())
}
#[test]
fn shutdown_releases_retry_wait_without_reaching_its_deadline() -> Result<(), crate::ServerError> {
let wake = Wake::default();
wake.stop()?;
wake.wait(Instant::now().checked_add(MAX_RETRY))?;
assert!(wake.stopping()?);
Ok(())
}