#![cfg(feature = "tokio")]
use core::time::Duration;
use srt_runtime::handshake_sm::HandshakeConfig;
use srt_runtime::io::{SrtListener, SrtSocket};
const CALLER_ISN: u32 = 500;
const LISTENER_ISN: u32 = 1000;
const NUM_PAYLOADS: usize = 20;
const TEST_TIMEOUT: Duration = Duration::from_secs(60);
#[tokio::test]
async fn loopback_call_to_recv() {
tokio::time::timeout(TEST_TIMEOUT, async {
let listener_addr = "127.0.0.1:0".parse::<std::net::SocketAddr>().unwrap();
let listener_config = HandshakeConfig {
initial_seq_number: LISTENER_ISN,
..HandshakeConfig::default()
};
let mut listener = SrtListener::bind(listener_addr, listener_config)
.await
.expect("listener bind");
let bound_addr = listener.local_addr().expect("listener local addr");
let caller_config = HandshakeConfig {
initial_seq_number: CALLER_ISN,
..HandshakeConfig::default()
};
let jh = tokio::spawn(async move { listener.accept().await.expect("listener accept") });
let mut caller = SrtSocket::connect(bound_addr, caller_config)
.await
.expect("caller connect");
let mut receiver = jh.await.expect("join listener");
let payloads: Vec<Vec<u8>> = (0..NUM_PAYLOADS)
.map(|i| {
let mut p = vec![0u8; 100 + i * 10];
for (j, byte) in p.iter_mut().enumerate() {
*byte = (i as u8).wrapping_add(j as u8);
}
p
})
.collect();
for payload in &payloads {
caller.send(payload).await.expect("caller send");
tokio::time::sleep(Duration::from_millis(5)).await;
}
let mut received: Vec<Vec<u8>> = Vec::with_capacity(NUM_PAYLOADS);
while received.len() < NUM_PAYLOADS {
match receiver.recv().await.expect("receiver recv") {
Some(payload) => {
received.push(payload);
}
None => break,
}
}
assert_eq!(
received.len(),
NUM_PAYLOADS,
"expected {NUM_PAYLOADS} payloads, got {}",
received.len()
);
for (i, (sent, recvd)) in payloads.iter().zip(received.iter()).enumerate() {
assert_eq!(
sent,
recvd,
"payload {i} mismatch: sent {} bytes, recv {} bytes",
sent.len(),
recvd.len()
);
}
drop(caller);
drop(receiver);
})
.await
.expect("test timed out — deadlock or stalled handshake");
}