From e4232dd0d8a39955b467fc8e77ba7738e5a0a9cd Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 16 Jan 2017 11:34:07 -0800 Subject: [PATCH] test(client): sleep disconnect test to reduce flakiness Closes #1003 --- .travis.yml | 2 +- tests/client.rs | 42 +++++++++++++++++++++++++++++++++--------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1aa06190..1274b77c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ cache: script: - ./.travis/readme.py - cargo build --verbose $FEATURES - - cargo test --verbose $FEATURES + - RUST_LOG=hyper cargo test --verbose $FEATURES - 'for f in ./doc/**/*.md; do echo "Running rustdoc on $f"; rustdoc -L ./target/debug -L ./target/debug/deps --test $f; done' - 'if [ $TRAVIS_RUST_VERSION = nightly ]; then for f in ./benches/*.rs; do cargo test --bench $(basename $f .rs) $FEATURES; done; fi' diff --git a/tests/client.rs b/tests/client.rs index 422ed82d..2586a56d 100644 --- a/tests/client.rs +++ b/tests/client.rs @@ -2,6 +2,7 @@ extern crate hyper; extern crate futures; extern crate tokio_core; +extern crate pretty_env_logger; use std::io::{self, Read, Write}; use std::net::TcpListener; @@ -11,10 +12,10 @@ use std::time::Duration; use hyper::client::{Client, Request, HttpConnector}; use hyper::{Method, StatusCode}; -use futures::Future; +use futures::{Future, Stream}; use futures::sync::oneshot; -use tokio_core::reactor::{Core, Handle}; +use tokio_core::reactor::{Core, Handle, Timeout}; fn client(handle: &Handle) -> Client { Client::new(handle) @@ -232,6 +233,7 @@ fn client_keep_alive() { #[test] fn client_pooled_socket_disconnected() { + let _ = pretty_env_logger::init(); let server = TcpListener::bind("127.0.0.1:0").unwrap(); let addr = server.local_addr().unwrap(); let mut core = Core::new().unwrap(); @@ -246,7 +248,9 @@ fn client_pooled_socket_disconnected() { sock.set_write_timeout(Some(Duration::from_secs(5))).unwrap(); let mut buf = [0; 4096]; sock.read(&mut buf).expect("read 1"); - sock.write_all(b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n").expect("write 1"); + let remote_addr = sock.peer_addr().unwrap().to_string(); + let out = format!("HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}", remote_addr.len(), remote_addr); + sock.write_all(out.as_bytes()).expect("write 1"); drop(sock); tx1.complete(()); @@ -254,17 +258,37 @@ fn client_pooled_socket_disconnected() { sock.read(&mut buf).expect("read 2"); let second_get = b"GET /b HTTP/1.1\r\n"; assert_eq!(&buf[..second_get.len()], second_get); - sock.write_all(b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n").expect("write 2"); + let remote_addr = sock.peer_addr().unwrap().to_string(); + let out = format!("HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}", remote_addr.len(), remote_addr); + sock.write_all(out.as_bytes()).expect("write 2"); tx2.complete(()); }); - + // spin shortly so we receive the hangup on the client socket + let sleep = Timeout::new(Duration::from_millis(500), &core.handle()).unwrap(); + core.run(sleep).unwrap(); let rx = rx1.map_err(|_| hyper::Error::Io(io::Error::new(io::ErrorKind::Other, "thread panicked"))); - let res = client.get(format!("http://{}/a", addr).parse().unwrap()); - core.run(res.join(rx).map(|r| r.0)).unwrap(); + let res = client.get(format!("http://{}/a", addr).parse().unwrap()) + .and_then(|res| { + res.body() + .map(|chunk| chunk.to_vec()) + .collect() + .map(|vec| vec.concat()) + .map(|vec| String::from_utf8(vec).unwrap()) + }); + let addr1 = core.run(res.join(rx).map(|r| r.0)).unwrap(); let rx = rx2.map_err(|_| hyper::Error::Io(io::Error::new(io::ErrorKind::Other, "thread panicked"))); - let res = client.get(format!("http://{}/b", addr).parse().unwrap()); - core.run(res.join(rx).map(|r| r.0)).unwrap(); + let res = client.get(format!("http://{}/b", addr).parse().unwrap()) + .and_then(|res| { + res.body() + .map(|chunk| chunk.to_vec()) + .collect() + .map(|vec| vec.concat()) + .map(|vec| String::from_utf8(vec).unwrap()) + }); + let addr2 = core.run(res.join(rx).map(|r| r.0)).unwrap(); + + assert_ne!(addr1, addr2); }