use std::time::Duration;
use eyre::Result;
use speed_cli::TestType;
use speed_cli::performance::http::HttpVersion;
use speed_cli::performance::http::client::run_http_test;
use speed_cli::performance::http::h3_server::{Http3ServerConfig, bind_h3, run_h3_server};
use speed_cli::report::{HttpTestConfig, TestResult};
use speed_cli::utils::tls::TlsMaterial;
use tokio_util::sync::CancellationToken;
#[tokio::test]
async fn http3_download_and_upload_roundtrip() -> Result<()> {
let cfg = Http3ServerConfig {
max_upload_size: 8 * 1024 * 1024,
tls: TlsMaterial::self_signed()?,
};
let (endpoint, port) = bind_h3("127.0.0.1:0".parse().unwrap(), &cfg)?;
let cancel = CancellationToken::new();
let server_cancel = cancel.clone();
let server_handle =
tokio::spawn(async move { run_h3_server(endpoint, cfg, server_cancel).await });
tokio::time::sleep(Duration::from_millis(200)).await;
let config = HttpTestConfig::new(
"127.0.0.1".to_string(),
Some(port),
2,
1,
TestType::Bidirectional,
vec![64 * 1024usize],
Some(16 * 1024),
HttpVersion::HTTP3,
)
.with_warmup(Duration::from_millis(0));
let report = run_http_test(config).await?;
let result = match &report.result {
TestResult::Network(net) => net,
_ => panic!("expected NetworkTestResult"),
};
assert!(
result.download.values().next().unwrap().bytes_transferred() > 0,
"HTTP/3 download bytes must be > 0"
);
assert!(
result.upload.values().next().unwrap().bytes_transferred() > 0,
"HTTP/3 upload bytes must be > 0"
);
cancel.cancel();
let join = tokio::time::timeout(Duration::from_secs(5), server_handle).await;
assert!(join.is_ok(), "HTTP/3 server did not shut down within 5s");
Ok(())
}