Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: add teest for graceful shutdown #106

Merged
merged 1 commit into from
Mar 9, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions src/server/conn/auto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -816,8 +816,11 @@ mod tests {
use http_body::Body;
use http_body_util::{BodyExt, Empty, Full};
use hyper::{body, body::Bytes, client, service::service_fn};
use std::{convert::Infallible, error::Error as StdError, net::SocketAddr};
use tokio::net::{TcpListener, TcpStream};
use std::{convert::Infallible, error::Error as StdError, net::SocketAddr, time::Duration};
use tokio::{
net::{TcpListener, TcpStream},
pin,
};

const BODY: &[u8] = b"Hello, world!";

Expand Down Expand Up @@ -871,6 +874,40 @@ mod tests {
assert_eq!(body, BODY);
}

#[cfg(not(miri))]
#[tokio::test]
async fn graceful_shutdown() {
let listener = TcpListener::bind(SocketAddr::from(([127, 0, 0, 1], 0)))
.await
.unwrap();

let listener_addr = listener.local_addr().unwrap();

// Spawn the task in background so that we can connect there
let listen_task = tokio::spawn(async move { listener.accept().await.unwrap() });
// Only connect a stream, do not send headers or anything
let _stream = TcpStream::connect(listener_addr).await.unwrap();

let (stream, _) = listen_task.await.unwrap();
let stream = TokioIo::new(stream);
let builder = auto::Builder::new(TokioExecutor::new());
let connection = builder.serve_connection(stream, service_fn(hello));

pin!(connection);

connection.as_mut().graceful_shutdown();

let connection_error = tokio::time::timeout(Duration::from_millis(200), connection)
.await
.expect("Connection should have finished in a timely manner after graceful shutdown.")
.expect_err("Connection should have been interrupted.");

let connection_error = connection_error
.downcast_ref::<std::io::Error>()
.expect("The error should have been `std::io::Error`.");
assert_eq!(connection_error.kind(), std::io::ErrorKind::Interrupted);
}

async fn connect_h1<B>(addr: SocketAddr) -> client::conn::http1::SendRequest<B>
where
B: Body + Send + 'static,
Expand Down