test(server): exercise async client interop
This commit is contained in:
3 files changed
+94
No files matched your search
Generated
+1
@@ -731,6 +731,7 @@ name = "irtt-server"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"getrandom 0.4.3",
|
||||
"irtt-client",
|
||||
"irtt-proto",
|
||||
"thiserror 2.0.20",
|
||||
"tokio",
|
||||
|
||||
@@ -16,3 +16,6 @@ irtt-proto.workspace = true
|
||||
getrandom = "0.4.3"
|
||||
thiserror = "2.0.20"
|
||||
tokio = { version = "1.53.1", default-features = false, features = ["rt", "net", "time", "sync", "macros"] }
|
||||
|
||||
[dev-dependencies]
|
||||
irtt-client = { workspace = true, features = ["tokio"] }
|
||||
@@ -0,0 +1,90 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use irtt_client::{AsyncClient, ClientConfig, ClientEvent, OpenOutcome, SocketConfig};
|
||||
use irtt_proto::{Clock, ReceivedStats, StampAt};
|
||||
use irtt_server::{Server, ServerConfig};
|
||||
use tokio::{sync::oneshot, time::timeout};
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn async_client_opens_echoes_receives_and_closes() {
|
||||
timeout(Duration::from_secs(2), exercise_client_server())
|
||||
.await
|
||||
.expect("client/server integration exceeded its bounded runtime");
|
||||
}
|
||||
|
||||
async fn exercise_client_server() {
|
||||
let mut server = Server::bind("127.0.0.1:0".parse().unwrap(), ServerConfig::default())
|
||||
.await
|
||||
.unwrap();
|
||||
let server_addr = server.local_addr().unwrap();
|
||||
let (shutdown_tx, shutdown_rx) = oneshot::channel();
|
||||
let server_task = tokio::spawn(async move {
|
||||
server
|
||||
.run(async {
|
||||
let _ = shutdown_rx.await;
|
||||
})
|
||||
.await
|
||||
});
|
||||
|
||||
let config = ClientConfig {
|
||||
server_addr: server_addr.to_string(),
|
||||
duration: Some(Duration::from_secs(1)),
|
||||
interval: Duration::from_millis(100),
|
||||
length: 64,
|
||||
received_stats: ReceivedStats::Both,
|
||||
stamp_at: StampAt::Both,
|
||||
clock: Clock::Both,
|
||||
open_timeouts: vec![Duration::from_millis(200)],
|
||||
socket_config: SocketConfig {
|
||||
recv_timeout: Some(Duration::from_millis(200)),
|
||||
..SocketConfig::default()
|
||||
},
|
||||
probe_timeout: Duration::from_millis(200),
|
||||
..ClientConfig::default()
|
||||
};
|
||||
let mut client = AsyncClient::connect(config).await.unwrap();
|
||||
|
||||
let opened = client.open().await.unwrap();
|
||||
match &opened {
|
||||
OpenOutcome::Started {
|
||||
remote,
|
||||
token,
|
||||
negotiated,
|
||||
event,
|
||||
} => {
|
||||
assert_eq!(*remote, server_addr);
|
||||
assert_ne!(*token, 0);
|
||||
assert_eq!(negotiated.params.received_stats, ReceivedStats::Both);
|
||||
assert_eq!(negotiated.params.stamp_at, StampAt::Both);
|
||||
assert_eq!(negotiated.params.clock, Clock::Both);
|
||||
assert!(matches!(event, ClientEvent::SessionStarted { .. }));
|
||||
}
|
||||
OpenOutcome::NoTestCompleted { .. } => panic!("normal client unexpectedly ran no-test"),
|
||||
}
|
||||
|
||||
assert!(matches!(
|
||||
client.send_probe().await.unwrap().as_slice(),
|
||||
[ClientEvent::EchoSent {
|
||||
seq: 0,
|
||||
remote,
|
||||
..
|
||||
}] if *remote == server_addr
|
||||
));
|
||||
assert!(matches!(
|
||||
client.recv().await.unwrap().as_slice(),
|
||||
[ClientEvent::EchoReply {
|
||||
seq: 0,
|
||||
remote,
|
||||
server_timing: Some(_),
|
||||
received_stats: Some(_),
|
||||
..
|
||||
}] if *remote == server_addr
|
||||
));
|
||||
assert!(matches!(
|
||||
client.close().await.unwrap().as_slice(),
|
||||
[ClientEvent::SessionClosed { remote, .. }] if *remote == server_addr
|
||||
));
|
||||
|
||||
shutdown_tx.send(()).unwrap();
|
||||
server_task.await.unwrap().unwrap();
|
||||
}
|
||||
Reference in new issue
Block a user