Skip to content

Commit 67f019b

Browse files
committed
add test
1 parent 450bfa7 commit 67f019b

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

tests/client.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,6 +2041,89 @@ mod conn {
20412041
assert_eq!(vec, b"bar=foo");
20422042
}
20432043

2044+
#[tokio::test]
2045+
async fn test_try_send_request() {
2046+
use std::future::Future;
2047+
let (listener, addr) = setup_tk_test_server().await;
2048+
let (done_tx, done_rx) = tokio::sync::oneshot::channel::<()>();
2049+
2050+
tokio::spawn(async move {
2051+
let mut sock = listener.accept().await.unwrap().0;
2052+
let mut buf = [0u8; 8192];
2053+
sock.read(&mut buf).await.expect("read 1");
2054+
sock.write_all(b"HTTP/1.1 200 OK\r\ncontent-length: 0\r\n\r\n")
2055+
.await
2056+
.expect("write 1");
2057+
let _ = done_rx.await;
2058+
});
2059+
2060+
// make polling fair by putting both in spawns
2061+
tokio::spawn(async move {
2062+
let io = tcp_connect(&addr).await.expect("tcp connect");
2063+
let (mut client, mut conn) = conn::http1::Builder::new()
2064+
.handshake::<_, Empty<Bytes>>(io)
2065+
.await
2066+
.expect("http handshake");
2067+
2068+
// get the conn ready
2069+
assert!(future::poll_fn(|cx| Poll::Ready(Pin::new(&mut conn).poll(cx)))
2070+
.await
2071+
.is_pending());
2072+
assert!(client.is_ready());
2073+
2074+
// use the connection once
2075+
let mut fut1 = std::pin::pin!(client.send_request(http::Request::new(Empty::new())));
2076+
let _res1 = future::poll_fn(|cx| loop {
2077+
if let Poll::Ready(res) = fut1.as_mut().poll(cx) {
2078+
return Poll::Ready(res);
2079+
}
2080+
return match Pin::new(&mut conn).poll(cx) {
2081+
Poll::Ready(_) => panic!("ruh roh"),
2082+
Poll::Pending => Poll::Pending,
2083+
};
2084+
})
2085+
.await
2086+
.expect("resp 1");
2087+
2088+
assert!(client.is_ready());
2089+
2090+
// simulate the server dropping the conn
2091+
let _ = done_tx.send(());
2092+
// let the server task die
2093+
tokio::task::yield_now().await;
2094+
2095+
let mut fut2 =
2096+
std::pin::pin!(client.try_send_request(http::Request::new(Empty::new())));
2097+
let poll1 = future::poll_fn(|cx| Poll::Ready(fut2.as_mut().poll(cx))).await;
2098+
assert!(poll1.is_pending(), "not already known to error");
2099+
2100+
let mut conn_opt = Some(conn);
2101+
// wasn't a known error, req is in queue, and now the next poll, the
2102+
// conn will be noticed as errored
2103+
let mut err = future::poll_fn(|cx| {
2104+
loop {
2105+
if let Poll::Ready(res) = fut2.as_mut().poll(cx) {
2106+
return Poll::Ready(res);
2107+
}
2108+
if let Some(ref mut conn) = conn_opt {
2109+
match Pin::new(conn).poll(cx) {
2110+
Poll::Ready(_) => {
2111+
conn_opt = None;
2112+
}, // ok
2113+
Poll::Pending => return Poll::Pending,
2114+
};
2115+
}
2116+
}
2117+
})
2118+
.await
2119+
.expect_err("resp 2");
2120+
2121+
assert!(err.take_message().is_some(), "request was returned");
2122+
})
2123+
.await
2124+
.unwrap();
2125+
}
2126+
20442127
#[tokio::test]
20452128
async fn http2_detect_conn_eof() {
20462129
use futures_util::future;

0 commit comments

Comments
 (0)