#![allow(
clippy::unwrap_used,
reason = "test helpers; a panic is a test failure"
)]
use std::time::Duration;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpListener;
use yapi_ai::http::{self, Failure};
use yapi_ai::stream::StreamOptions;
async fn silent_server(head: &'static str) -> String {
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
let address = listener.local_addr().unwrap();
tokio::spawn(async move {
let (mut socket, _) = listener.accept().await.unwrap();
let mut buffer = [0u8; 4096];
let _ = socket.read(&mut buffer).await;
socket.write_all(head.as_bytes()).await.unwrap();
tokio::time::sleep(Duration::from_secs(30)).await;
});
format!("http://{address}/")
}
#[tokio::test]
async fn idle_requests_fail() {
http::set_idle_timeout_ms(200);
let options = StreamOptions::default();
let url = silent_server("").await;
let started = std::time::Instant::now();
let result = http::send(|| http::client().get(&url), &options).await;
assert!(
matches!(&result, Err(Failure::Connection(message)) if message == "Connection error."),
"{result:?}"
);
assert!(started.elapsed() < Duration::from_secs(5));
let url = silent_server("").await;
let sdk = StreamOptions {
timeout_ms: Some(50.0),
..StreamOptions::default()
};
let result = http::send(|| http::client().get(&url), &sdk).await;
assert!(
matches!(&result, Err(Failure::Connection(message)) if message == "Request timed out."),
"{result:?}"
);
let url = silent_server(
"HTTP/1.1 200 OK\r\ncontent-type: text/event-stream\r\ntransfer-encoding: chunked\r\n\r\n5\r\nhello\r\n",
)
.await;
let mut response = http::send(|| http::client().get(&url), &options)
.await
.unwrap();
let cancel = options.cancel.clone();
assert_eq!(
http::read_chunk(&mut response, &cancel, "aborted").await,
Ok(Some(b"hello".to_vec()))
);
assert_eq!(
http::read_chunk(&mut response, &cancel, "aborted").await,
Err("terminated".to_owned())
);
}