use anyhow::Result; use futures_util::FutureExt; use std::net::SocketAddr; use tokio::task::JoinHandle; use tracing::info; use zero_to_axum::ZeroToAxum; pub struct TestServer { server_task_handle: JoinHandle<()>, addr: SocketAddr, } impl TestServer { pub async fn spawn() -> TestServer { info!("start server"); let server = ZeroToAxum::serve("[::]:0".parse().unwrap()).await; let addr = server.local_addr(); let server_task_handle = tokio::spawn(server.map(|res| res.unwrap())); info!("server spawned"); TestServer { server_task_handle, addr, } } /// format a URL for the given path pub fn url(&self, path: &str) -> String { format!("http://{}{path}", self.addr) } /// Request a graceful shutdown and then wait for shutdown to complete pub async fn shutdown(self) -> Result<()> { self.server_task_handle.abort(); let _ = self.server_task_handle.await; Ok(()) } }