Rewrite tests with a hyper server instead of raw TCP
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.
This commit is contained in:
269
tests/gzip.rs
269
tests/gzip.rs
@@ -1,13 +1,101 @@
|
||||
#[macro_use]
|
||||
mod support;
|
||||
use support::*;
|
||||
|
||||
use std::io::Write;
|
||||
use std::time::Duration;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_gzip_response() {
|
||||
let content: String = (0..50).into_iter().map(|i| format!("test {}", i)).collect();
|
||||
let chunk_size = content.len() / 3;
|
||||
async fn gzip_response() {
|
||||
gzip_case(10_000, 4096).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn gzip_single_byte_chunks() {
|
||||
gzip_case(10, 1).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_gzip_empty_body() {
|
||||
let server = server::http(move |req| {
|
||||
async move {
|
||||
assert_eq!(req.method(), "HEAD");
|
||||
|
||||
http::Response::builder()
|
||||
.header("content-encoding", "gzip")
|
||||
.header("content-length", 100)
|
||||
.body(Default::default())
|
||||
.unwrap()
|
||||
}
|
||||
});
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
let res = client
|
||||
.head(&format!("http://{}/gzip", server.addr()))
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let body = res.text().await.unwrap();
|
||||
|
||||
assert_eq!(body, "");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_accept_header_is_not_changed_if_set() {
|
||||
let server = server::http(move |req| {
|
||||
async move {
|
||||
assert_eq!(req.headers()["accept"], "application/json");
|
||||
assert_eq!(req.headers()["accept-encoding"], "gzip");
|
||||
http::Response::default()
|
||||
}
|
||||
});
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
let res = client
|
||||
.get(&format!("http://{}/accept", server.addr()))
|
||||
.header(
|
||||
reqwest::header::ACCEPT,
|
||||
reqwest::header::HeaderValue::from_static("application/json"),
|
||||
)
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(res.status(), reqwest::StatusCode::OK);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_accept_encoding_header_is_not_changed_if_set() {
|
||||
let server = server::http(move |req| {
|
||||
async move {
|
||||
assert_eq!(req.headers()["accept"], "*/*");
|
||||
assert_eq!(req.headers()["accept-encoding"], "identity");
|
||||
http::Response::default()
|
||||
}
|
||||
});
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
let res = client
|
||||
.get(&format!("http://{}/accept-encoding", server.addr()))
|
||||
.header(
|
||||
reqwest::header::ACCEPT_ENCODING,
|
||||
reqwest::header::HeaderValue::from_static("identity"),
|
||||
)
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(res.status(), reqwest::StatusCode::OK);
|
||||
}
|
||||
|
||||
async fn gzip_case(response_size: usize, chunk_size: usize) {
|
||||
use futures_util::stream::StreamExt;
|
||||
|
||||
let content: String = (0..response_size)
|
||||
.into_iter()
|
||||
.map(|i| format!("test {}", i))
|
||||
.collect();
|
||||
let mut encoder = libflate::gzip::Encoder::new(Vec::new()).unwrap();
|
||||
match encoder.write(content.as_bytes()) {
|
||||
Ok(n) => assert!(n > 0, "Failed to write to encoder."),
|
||||
@@ -28,147 +116,38 @@ async fn test_gzip_response() {
|
||||
.into_bytes();
|
||||
response.extend(&gzipped_content);
|
||||
|
||||
let server = server! {
|
||||
request: b"\
|
||||
GET /gzip HTTP/1.1\r\n\
|
||||
user-agent: $USERAGENT\r\n\
|
||||
accept: */*\r\n\
|
||||
accept-encoding: gzip\r\n\
|
||||
host: $HOST\r\n\
|
||||
\r\n\
|
||||
",
|
||||
chunk_size: chunk_size,
|
||||
write_timeout: Duration::from_millis(10),
|
||||
response: response
|
||||
};
|
||||
let url = format!("http://{}/gzip", server.addr());
|
||||
let res = reqwest::get(&url).await.unwrap();
|
||||
let server = server::http(move |req| {
|
||||
assert_eq!(req.headers()["accept-encoding"], "gzip");
|
||||
|
||||
let body = res.text().await.unwrap();
|
||||
let gzipped = gzipped_content.clone();
|
||||
async move {
|
||||
let len = gzipped.len();
|
||||
let stream = futures_util::stream::unfold((gzipped, 0), move |(gzipped, pos)| {
|
||||
async move {
|
||||
let chunk = gzipped.chunks(chunk_size).nth(pos)?.to_vec();
|
||||
|
||||
Some((chunk, (gzipped, pos + 1)))
|
||||
}
|
||||
});
|
||||
|
||||
let body = hyper::Body::wrap_stream(stream.map(Ok::<_, std::convert::Infallible>));
|
||||
|
||||
http::Response::builder()
|
||||
.header("content-encoding", "gzip")
|
||||
.header("content-length", len)
|
||||
.body(body)
|
||||
.unwrap()
|
||||
}
|
||||
});
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
let res = client
|
||||
.get(&format!("http://{}/gzip", server.addr()))
|
||||
.send()
|
||||
.await
|
||||
.expect("response");
|
||||
|
||||
let body = res.text().await.expect("text");
|
||||
assert_eq!(body, content);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_gzip_empty_body() {
|
||||
let server = server! {
|
||||
request: b"\
|
||||
HEAD /gzip HTTP/1.1\r\n\
|
||||
user-agent: $USERAGENT\r\n\
|
||||
accept: */*\r\n\
|
||||
accept-encoding: gzip\r\n\
|
||||
host: $HOST\r\n\
|
||||
\r\n\
|
||||
",
|
||||
response: b"\
|
||||
HTTP/1.1 200 OK\r\n\
|
||||
Server: test-accept\r\n\
|
||||
Content-Encoding: gzip\r\n\
|
||||
Content-Length: 100\r\n\
|
||||
\r\n"
|
||||
};
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
let res = client
|
||||
.head(&format!("http://{}/gzip", server.addr()))
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let body = res.text().await.unwrap();
|
||||
|
||||
assert_eq!(body, "");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_gzip_invalid_body() {
|
||||
let server = server! {
|
||||
request: b"\
|
||||
GET /gzip HTTP/1.1\r\n\
|
||||
user-agent: $USERAGENT\r\n\
|
||||
accept: */*\r\n\
|
||||
accept-encoding: gzip\r\n\
|
||||
host: $HOST\r\n\
|
||||
\r\n\
|
||||
",
|
||||
response: b"\
|
||||
HTTP/1.1 200 OK\r\n\
|
||||
Server: test-accept\r\n\
|
||||
Content-Encoding: gzip\r\n\
|
||||
Content-Length: 100\r\n\
|
||||
\r\n\
|
||||
0"
|
||||
};
|
||||
let url = format!("http://{}/gzip", server.addr());
|
||||
let res = reqwest::get(&url).await.unwrap();
|
||||
// this tests that the request.send() didn't error, but that the error
|
||||
// is in reading the body
|
||||
|
||||
res.text().await.unwrap_err();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_accept_header_is_not_changed_if_set() {
|
||||
let server = server! {
|
||||
request: b"\
|
||||
GET /accept HTTP/1.1\r\n\
|
||||
accept: application/json\r\n\
|
||||
user-agent: $USERAGENT\r\n\
|
||||
accept-encoding: gzip\r\n\
|
||||
host: $HOST\r\n\
|
||||
\r\n\
|
||||
",
|
||||
response: b"\
|
||||
HTTP/1.1 200 OK\r\n\
|
||||
Server: test-accept\r\n\
|
||||
Content-Length: 0\r\n\
|
||||
\r\n\
|
||||
"
|
||||
};
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
let res = client
|
||||
.get(&format!("http://{}/accept", server.addr()))
|
||||
.header(
|
||||
reqwest::header::ACCEPT,
|
||||
reqwest::header::HeaderValue::from_static("application/json"),
|
||||
)
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(res.status(), reqwest::StatusCode::OK);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_accept_encoding_header_is_not_changed_if_set() {
|
||||
let server = server! {
|
||||
request: b"\
|
||||
GET /accept-encoding HTTP/1.1\r\n\
|
||||
accept-encoding: identity\r\n\
|
||||
user-agent: $USERAGENT\r\n\
|
||||
accept: */*\r\n\
|
||||
host: $HOST\r\n\
|
||||
\r\n\
|
||||
",
|
||||
response: b"\
|
||||
HTTP/1.1 200 OK\r\n\
|
||||
Server: test-accept-encoding\r\n\
|
||||
Content-Length: 0\r\n\
|
||||
\r\n\
|
||||
"
|
||||
};
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
let res = client
|
||||
.get(&format!("http://{}/accept-encoding", server.addr()))
|
||||
.header(
|
||||
reqwest::header::ACCEPT_ENCODING,
|
||||
reqwest::header::HeaderValue::from_static("identity"),
|
||||
)
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(res.status(), reqwest::StatusCode::OK);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user