#![cfg(feature = "tcp")]
use bytes::Bytes;
use qmux::{transport::Stream, Config, Error, Session, Version};
use tokio::net::{TcpListener, TcpStream};
use web_transport_trait::Session as _;
async fn pair(client_cfg: Config, server_cfg: Config) -> (Session, Session) {
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
let addr = listener.local_addr().unwrap();
let server = tokio::spawn(async move {
let (sock, _) = listener.accept().await.unwrap();
let transport = Stream::new(sock, server_cfg.version, server_cfg.max_record_size);
Session::accept(transport, server_cfg).await.unwrap()
});
let sock = TcpStream::connect(addr).await.unwrap();
let transport = Stream::new(sock, client_cfg.version, client_cfg.max_record_size);
let client = Session::connect(transport, client_cfg).await.unwrap();
(client, server.await.unwrap())
}
#[tokio::test]
async fn round_trip() {
let (client, server) = pair(Config::new(Version::QMux01), Config::new(Version::QMux01)).await;
assert!(client.max_datagram_size() > 0);
assert!(server.max_datagram_size() > 0);
client.send_datagram(Bytes::from_static(b"ping")).unwrap();
assert_eq!(server.recv_datagram().await.unwrap().as_ref(), b"ping");
server.send_datagram(Bytes::from_static(b"pong")).unwrap();
assert_eq!(client.recv_datagram().await.unwrap().as_ref(), b"pong");
}
#[tokio::test]
async fn disabled_on_qmux00() {
let (client, server) = pair(Config::new(Version::QMux00), Config::new(Version::QMux00)).await;
assert_eq!(client.max_datagram_size(), 0);
assert_eq!(server.max_datagram_size(), 0);
assert!(matches!(
client.send_datagram(Bytes::from_static(b"hello")),
Err(Error::DatagramsUnsupported)
));
}
#[tokio::test]
async fn disabled_by_peer_is_one_directional() {
let mut client_cfg = Config::new(Version::QMux01);
client_cfg.max_datagram_frame_size = 0;
let (client, server) = pair(client_cfg, Config::new(Version::QMux01)).await;
assert_eq!(server.max_datagram_size(), 0);
assert!(matches!(
server.send_datagram(Bytes::from_static(b"x")),
Err(Error::DatagramsUnsupported)
));
assert!(client.max_datagram_size() > 0);
client.send_datagram(Bytes::from_static(b"hey")).unwrap();
assert_eq!(server.recv_datagram().await.unwrap().as_ref(), b"hey");
}
#[tokio::test]
async fn oversized_payload_rejected() {
let (client, _server) = pair(Config::new(Version::QMux01), Config::new(Version::QMux01)).await;
let too_big = vec![0u8; client.max_datagram_size() + 1];
assert!(matches!(
client.send_datagram(Bytes::from(too_big)),
Err(Error::FrameTooLarge)
));
}