blob: 1b82b93e68a0d676a6f081014b5ced1313f613f6 [file] [log] [blame]
use mio::*;
use mio::tcp::*;
use super::localhost;
use self::TestState::{Initial, AfterRead, AfterHup};
const SERVER: Token = Token(0);
const CLIENT: Token = Token(1);
#[derive(Debug, PartialEq)]
enum TestState {
Initial,
AfterRead,
AfterHup
}
struct TestHandler {
srv: TcpListener,
cli: TcpStream,
state: TestState
}
impl TestHandler {
fn new(srv: TcpListener, cli: TcpStream) -> TestHandler {
TestHandler {
srv: srv,
cli: cli,
state: Initial
}
}
fn handle_read(&mut self, event_loop: &mut EventLoop<TestHandler>, tok: Token, events: EventSet) {
match tok {
SERVER => {
debug!("server connection ready for accept");
let conn = self.srv.accept().unwrap().unwrap();
event_loop.timeout_ms(conn, 200).unwrap();
event_loop.reregister(&self.srv, SERVER, EventSet::readable(), PollOpt::edge()).unwrap();
}
CLIENT => {
debug!("client readable");
match self.state {
Initial => {
// Whether or not Hup is included with actual data is platform specific
if events.is_hup() {
self.state = AfterHup;
} else {
self.state = AfterRead;
}
}
AfterRead => {
assert_eq!(events, EventSet::readable() | EventSet::hup());
self.state = AfterHup;
}
AfterHup => panic!("Shouldn't get here"),
}
if self.state == AfterHup {
event_loop.shutdown();
return;
}
let mut buf = buf::ByteBuf::mut_with_capacity(2048);
match self.cli.try_read_buf(&mut buf) {
Ok(n) => {
debug!("read {:?} bytes", n);
assert!(b"zomg" == buf.flip().bytes());
}
Err(e) => {
debug!("client sock failed to read; err={:?}", e.kind());
}
}
event_loop.reregister(&self.cli, CLIENT, EventSet::readable() | EventSet::hup(), PollOpt::edge()).unwrap();
}
_ => panic!("received unknown token {:?}", tok),
}
}
fn handle_write(&mut self, event_loop: &mut EventLoop<TestHandler>, tok: Token, events: EventSet) {
match tok {
SERVER => panic!("received writable for token 0"),
CLIENT => debug!("client connected"),
_ => panic!("received unknown token {:?}", tok),
}
event_loop.reregister(&self.cli, CLIENT, EventSet::readable(), PollOpt::edge()).unwrap();
}
}
impl Handler for TestHandler {
type Timeout = TcpStream;
type Message = ();
fn ready(&mut self, event_loop: &mut EventLoop<TestHandler>, tok: Token, events: EventSet) {
if events.is_readable() {
self.handle_read(event_loop, tok, events);
}
if events.is_writable() {
self.handle_write(event_loop, tok, events);
}
}
fn timeout(&mut self, _event_loop: &mut EventLoop<TestHandler>, mut sock: TcpStream) {
debug!("timeout handler : writing to socket");
sock.try_write_buf(&mut buf::SliceBuf::wrap(b"zomg")).unwrap().unwrap();
}
}
#[test]
pub fn test_timer() {
debug!("Starting TEST_TIMER");
let mut event_loop = EventLoop::new().unwrap();
let addr = localhost();
let srv = TcpSocket::v4().unwrap();
info!("setting re-use addr");
srv.set_reuseaddr(true).unwrap();
srv.bind(&addr).unwrap();
let srv = srv.listen(256).unwrap();
info!("listening for connections");
event_loop.register_opt(&srv, SERVER, EventSet::all(), PollOpt::edge()).unwrap();
let (sock, _) = TcpSocket::v4().unwrap()
.connect(&addr).unwrap();
// Connect to the server
event_loop.register_opt(&sock, CLIENT, EventSet::all(), PollOpt::edge()).unwrap();
// Init the handler
let mut handler = TestHandler::new(srv, sock);
// Start the event loop
event_loop.run(&mut handler).unwrap();
assert!(handler.state == AfterHup, "actual={:?}", handler.state);
}