chore(windows): add test for keep-alive dropped in failing test
This commit is contained in:
@@ -4,6 +4,7 @@ extern crate futures;
|
|||||||
extern crate spmc;
|
extern crate spmc;
|
||||||
extern crate pretty_env_logger;
|
extern crate pretty_env_logger;
|
||||||
extern crate tokio_core;
|
extern crate tokio_core;
|
||||||
|
extern crate tokio_io;
|
||||||
|
|
||||||
use futures::{Future, Stream};
|
use futures::{Future, Stream};
|
||||||
use futures::future::{self, FutureResult, Either};
|
use futures::future::{self, FutureResult, Either};
|
||||||
@@ -11,9 +12,11 @@ use futures::sync::oneshot;
|
|||||||
|
|
||||||
use tokio_core::net::TcpListener;
|
use tokio_core::net::TcpListener;
|
||||||
use tokio_core::reactor::Core;
|
use tokio_core::reactor::Core;
|
||||||
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
|
|
||||||
use std::net::{TcpStream, SocketAddr};
|
use std::net::{TcpStream, SocketAddr};
|
||||||
use std::io::{Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
@@ -623,18 +626,22 @@ fn disable_keep_alive_post_request() {
|
|||||||
|
|
||||||
tx1.send(()).unwrap();
|
tx1.send(()).unwrap();
|
||||||
|
|
||||||
// allow a little more time for TCP to notice the FIN
|
let nread = req.read(&mut buf).expect("keep-alive reading")
|
||||||
req.set_read_timeout(Some(Duration::from_secs(5))).expect("set_read_timeout 2");
|
|
||||||
let nread = req.read(&mut buf).expect("keep-alive reading");
|
|
||||||
assert_eq!(nread, 0);
|
assert_eq!(nread, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let dropped = Dropped::new();
|
||||||
|
let dropped2 = dropped.clone();
|
||||||
let fut = listener.incoming()
|
let fut = listener.incoming()
|
||||||
.into_future()
|
.into_future()
|
||||||
.map_err(|_| unreachable!())
|
.map_err(|_| unreachable!())
|
||||||
.and_then(|(item, _incoming)| {
|
.and_then(|(item, _incoming)| {
|
||||||
let (socket, _) = item.expect("accepted socket");
|
let (socket, _) = item.expect("accepted socket");
|
||||||
Http::<hyper::Chunk>::new().serve_connection(socket, HelloWorld)
|
let transport = DebugStream {
|
||||||
|
stream: socket,
|
||||||
|
_debug: dropped2,
|
||||||
|
};
|
||||||
|
Http::<hyper::Chunk>::new().serve_connection(transport, HelloWorld)
|
||||||
.select2(rx1)
|
.select2(rx1)
|
||||||
.then(|r| {
|
.then(|r| {
|
||||||
match r {
|
match r {
|
||||||
@@ -649,7 +656,9 @@ fn disable_keep_alive_post_request() {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
assert!(!dropped.load());
|
||||||
core.run(fut).unwrap();
|
core.run(fut).unwrap();
|
||||||
|
assert!(dropped.load());
|
||||||
child.join().unwrap();
|
child.join().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -918,3 +927,53 @@ fn serve_with_options(options: ServeOptions) -> Serve {
|
|||||||
thread: Some(thread),
|
thread: Some(thread),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DebugStream<T, D> {
|
||||||
|
stream: T,
|
||||||
|
_debug: D,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Read, D> Read for DebugStream<T, D> {
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
|
self.stream.read(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Write, D> Write for DebugStream<T, D> {
|
||||||
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
|
self.stream.write(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> io::Result<()> {
|
||||||
|
self.stream.flush()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<T: AsyncWrite, D> AsyncWrite for DebugStream<T, D> {
|
||||||
|
fn shutdown(&mut self) -> futures::Poll<(), io::Error> {
|
||||||
|
self.stream.shutdown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<T: AsyncRead, D> AsyncRead for DebugStream<T, D> {}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Dropped(Arc<AtomicBool>);
|
||||||
|
|
||||||
|
impl Dropped {
|
||||||
|
pub fn new() -> Dropped {
|
||||||
|
Dropped(Arc::new(AtomicBool::new(false)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load(&self) -> bool {
|
||||||
|
self.0.load(Ordering::SeqCst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Dropped {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.0.store(true, Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user