Fix connection_reuse test.

This test was making requests to a server on the Internet. That has the
potential to make the test flaky. Also, the test was relying on a
specific behavior from that server (timing out after 2s), which it no
longer exhibits.

This sets up a local test server that exhibits the specific properties
needed for this test.
This commit is contained in:
Jacob Hoffman-Andrews
2020-06-14 00:23:50 -07:00
committed by Martin Algesten
parent 378ef57636
commit 64ef337c0b

View File

@@ -1,6 +1,7 @@
use crate::test;
use super::super::*;
use std::thread;
#[test]
fn agent_reuse_headers() {
@@ -56,24 +57,61 @@ fn agent_cookies() {
#[test]
#[cfg(feature = "tls")]
fn connection_reuse() {
use std::io::Read;
use std::io::{BufRead, BufReader, Read, Write};
use std::time::Duration;
// Start a test server on an available port, that times out idle connections at 2 seconds.
let listener = std::net::TcpListener::bind("localhost:0").unwrap();
let port = listener.local_addr().unwrap().port();
let url = format!("http://localhost:{}", port);
thread::spawn(move || {
for stream in listener.incoming() {
thread::spawn(move || {
let stream = stream.unwrap();
stream
.set_read_timeout(Some(Duration::from_millis(2000)))
.unwrap();
let mut write_stream = stream.try_clone().unwrap();
for line in BufReader::new(stream).lines() {
let line = match line {
Ok(x) => x,
Err(_) => return,
};
if line == "" {
write_stream
.write_all(b"HTTP/1.1 200 OK\r\nContent-Length: 8\r\n\r\nresponse")
.unwrap();
}
}
});
}
});
let agent = Agent::default().build();
let resp = agent.get("https://fau.xxx/").call();
let resp = agent.get(&url).call();
// use up the connection so it gets returned to the pool
assert_eq!(resp.status(), 200);
resp.into_reader().read_to_end(&mut vec![]).unwrap();
let mut buf = vec![];
resp.into_reader().read_to_end(&mut buf).unwrap();
// wait for the server to close the connection. fau.xxx has a
// 2 second connection keep-alive. then it closes.
{
let mut guard_state = agent.state().lock().unwrap();
let mut state = guard_state.take().unwrap();
assert!(state.pool().len() > 0);
}
// wait for the server to close the connection.
std::thread::sleep(Duration::from_secs(3));
// try and make a new request on the pool. this fails
// when we discover that the TLS connection is dead
// first when attempting to read from it.
let resp = agent.get("https://fau.xxx/").call();
// Note: This test assumes the second .call() actually
// pulls from the pool. If for some reason the timed-out
// connection wasn't in the pool, we won't be testing what
// we thought we were testing.
let resp = agent.get(&url).call();
if let Some(err) = resp.synthetic_error() {
panic!("Pooled connection failed! {:?}", err);
}