use std::time::Duration;
use iroh::endpoint::presets;
use super::*;
const PATIENCE: Duration = Duration::from_secs(20);
async fn accepting() -> (Endpoint, tokio::sync::mpsc::UnboundedReceiver<Connection>) {
let (tx, rx) = tokio::sync::mpsc::unbounded_channel();
let endpoint = Endpoint::builder(presets::N0)
.alpns(vec![transport::ALPN.to_vec()])
.bind()
.await
.expect("an endpoint binds");
let accepting = endpoint.clone();
tokio::spawn(async move {
while let Some(incoming) = accepting.accept().await {
if let Ok(connection) = incoming.await {
let _ = tx.send(connection);
}
}
});
(endpoint, rx)
}
fn ticket_for(endpoint: &Endpoint) -> Ticket {
transport::ticket_from(&endpoint.addr())
}
#[tokio::test]
async fn a_ticket_for_a_live_peer_dials_it_and_holds_the_connection() {
let (endpoint, _accepted) = accepting().await;
let peer = tokio::time::timeout(PATIENCE, Peer::dial(&ticket_for(&endpoint)))
.await
.expect("the dial must not hang")
.expect("a live peer is reachable");
assert!(peer.current().is_some(), "and the connection is held");
}
#[tokio::test]
async fn a_peer_can_be_dialled_again_at_the_same_identity() {
let (endpoint, _accepted) = accepting().await;
let peer = tokio::time::timeout(PATIENCE, Peer::dial(&ticket_for(&endpoint)))
.await
.expect("the dial must not hang")
.expect("a live peer is reachable");
let first = peer.current().expect("a connection").stable_id();
let path = tokio::time::timeout(PATIENCE, peer.redial())
.await
.expect("the re-dial must not hang")
.expect("the same peer is still there");
let second = peer.current().expect("a connection").stable_id();
assert_ne!(first, second, "a genuinely new connection, not the old one");
assert!(
matches!(path, PeerPath::Direct | PeerPath::Relayed),
"and it reports a path it is actually using"
);
}
#[tokio::test]
async fn forgetting_a_replaced_connection_leaves_its_successor_alone() {
let (endpoint, _accepted) = accepting().await;
let peer = tokio::time::timeout(PATIENCE, Peer::dial(&ticket_for(&endpoint)))
.await
.expect("the dial must not hang")
.expect("a live peer is reachable");
let stale = peer.current().expect("a connection");
tokio::time::timeout(PATIENCE, peer.redial())
.await
.expect("the re-dial must not hang")
.expect("the same peer is still there");
let live = peer.current().expect("a replacement").stable_id();
peer.forget(&stale);
assert_eq!(
peer.current().map(|c| c.stable_id()),
Some(live),
"forgetting the connection that died must not drop the one that replaced it"
);
}
#[tokio::test]
async fn forgetting_the_live_connection_clears_it() {
let (endpoint, _accepted) = accepting().await;
let peer = tokio::time::timeout(PATIENCE, Peer::dial(&ticket_for(&endpoint)))
.await
.expect("the dial must not hang")
.expect("a live peer is reachable");
let live = peer.current().expect("a connection");
peer.forget(&live);
assert!(
peer.current().is_none(),
"and the pipe now knows it has no connection"
);
}