use dig_nat::method::upnp::{RealIgd, RealUpnpMethod};
use dig_nat::method::{TraversalKind, TraversalMethod};
use dig_nat::mux::{PeerSession, RangeRequest};
use dig_nat::peer::PeerConnection;
use dig_nat::PeerId;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
fn loopback_conn() -> (PeerConnection, tokio::task::JoinHandle<()>) {
let (a, b) = tokio::io::duplex(256 * 1024);
let client = PeerSession::client(a);
let mut server = PeerSession::server(b);
let handle = tokio::spawn(async move {
while let Some(mut s) = server.accept_stream().await {
tokio::spawn(async move {
let mut buf = Vec::new();
let _ = s.read_to_end(&mut buf).await;
let _ = s.write_all(&buf).await;
let _ = s.shutdown().await;
});
}
});
let conn = PeerConnection {
peer_id: PeerId::from_bytes([3u8; 32]),
method: TraversalKind::Direct,
remote_addr: "127.0.0.1:1".parse().unwrap(),
session: client,
};
(conn, handle)
}
#[tokio::test]
async fn peer_connection_open_stream_passthrough() {
let (mut conn, _srv) = loopback_conn();
let mut s = conn.open_stream().await.unwrap();
s.write_all(b"ping").await.unwrap();
s.shutdown().await.unwrap();
let mut back = Vec::new();
s.read_to_end(&mut back).await.unwrap();
assert_eq!(back, b"ping");
}
#[tokio::test]
async fn peer_connection_open_range_stream_passthrough() {
let (mut conn, _srv) = loopback_conn();
let req = RangeRequest::resource("00".repeat(32), "11".repeat(32), 0, 8);
let mut s = conn.open_range_stream(&req).await.unwrap();
s.shutdown().await.unwrap();
let decoded = RangeRequest::decode(&mut s).await.unwrap();
assert_eq!(decoded, req);
}
#[test]
fn real_upnp_method_constructs() {
let m: RealUpnpMethod = RealUpnpMethod::real(9444);
assert_eq!(m.kind(), TraversalKind::Upnp);
assert_eq!(m.local_port, 9444);
let _default = RealIgd::default();
}
#[tokio::test]
async fn peer_connection_debug_is_safe() {
let (conn, _srv) = loopback_conn();
let s = format!("{conn:?}");
assert!(s.contains("PeerConnection"));
assert!(s.contains("Direct"));
}