This makes the tests much less brittle, by not depending on the exact order of the HTTP headers, nor always requiring to check for every single header.
81 lines
2.1 KiB
Rust
81 lines
2.1 KiB
Rust
use std::convert::Infallible;
|
|
use std::future::Future;
|
|
use std::net;
|
|
use std::sync::mpsc as std_mpsc;
|
|
use std::thread;
|
|
use std::time::Duration;
|
|
|
|
use tokio::sync::oneshot;
|
|
|
|
pub use http::Response;
|
|
|
|
pub struct Server {
|
|
addr: net::SocketAddr,
|
|
panic_rx: std_mpsc::Receiver<()>,
|
|
shutdown_tx: Option<oneshot::Sender<()>>,
|
|
}
|
|
|
|
impl Server {
|
|
pub fn addr(&self) -> net::SocketAddr {
|
|
self.addr
|
|
}
|
|
}
|
|
|
|
impl Drop for Server {
|
|
fn drop(&mut self) {
|
|
if let Some(tx) = self.shutdown_tx.take() {
|
|
let _ = tx.send(());
|
|
}
|
|
|
|
if !::std::thread::panicking() {
|
|
self.panic_rx
|
|
.recv_timeout(Duration::from_secs(3))
|
|
.expect("test server should not panic");
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn http<F, Fut>(func: F) -> Server
|
|
where
|
|
F: Fn(http::Request<hyper::Body>) -> Fut + Clone + Send + 'static,
|
|
Fut: Future<Output = http::Response<hyper::Body>> + Send + 'static,
|
|
{
|
|
let srv = hyper::Server::bind(&([127, 0, 0, 1], 0).into()).serve(
|
|
hyper::service::make_service_fn(move |_| {
|
|
let func = func.clone();
|
|
async move {
|
|
Ok::<_, Infallible>(hyper::service::service_fn(move |req| {
|
|
let fut = func(req);
|
|
async move { Ok::<_, Infallible>(fut.await) }
|
|
}))
|
|
}
|
|
}),
|
|
);
|
|
|
|
let addr = srv.local_addr();
|
|
let (shutdown_tx, shutdown_rx) = oneshot::channel();
|
|
let srv = srv.with_graceful_shutdown(async move {
|
|
let _ = shutdown_rx.await;
|
|
});
|
|
|
|
let (panic_tx, panic_rx) = std_mpsc::channel();
|
|
let tname = format!(
|
|
"test({})-support-server",
|
|
thread::current().name().unwrap_or("<unknown>")
|
|
);
|
|
thread::Builder::new()
|
|
.name(tname)
|
|
.spawn(move || {
|
|
let mut rt = tokio::runtime::current_thread::Runtime::new().expect("rt new");
|
|
rt.block_on(srv).unwrap();
|
|
let _ = panic_tx.send(());
|
|
})
|
|
.expect("thread spawn");
|
|
|
|
Server {
|
|
addr,
|
|
panic_rx,
|
|
shutdown_tx: Some(shutdown_tx),
|
|
}
|
|
}
|