use selecting::Selector; use std::thread; use std::io::{self, Read, Write}; use std::net::{TcpStream, TcpListener, Shutdown, SocketAddr, SocketAddrV4, Ipv4Addr}; #[test] pub fn should_work_tcp_stream() { let mut selector = Selector::new(); let mut stream = TcpStream::connect("www.google.com:80").expect("Couldn't connect to the server..."); stream.set_nonblocking(true).expect("set_nonblocking call failed"); let mut buffer: [u8; 1024] = [0; 1024]; let error = stream.read(&mut buffer).unwrap_err(); assert_eq!(error.kind(), io::ErrorKind::WouldBlock); selector.add_read(&stream); selector.add_except(&stream); let result = selector.try_select().expect("To try select"); assert_eq!(result.len(), 0); assert!(!result.is_read(&stream)); selector.clear_read(); selector.add_write(&stream); let result = selector.try_select().expect("To try select"); assert_eq!(result.len(), 1); assert!(!result.is_read(&stream)); assert!(result.is_write(&stream)); } #[test] pub fn should_work_with_multiple_fds() { const LOCALHOST: SocketAddr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 65000)); let mut selector = Selector::new(); let (client_notifier, client_notification) = std::sync::mpsc::channel(); let (server_notifier, server_notification) = std::sync::mpsc::channel(); let server = thread::spawn(move || { let listener = TcpListener::bind(LOCALHOST).expect("Couldn't bind to the address..."); let s1 = listener.accept().expect("Couldn't accept the connection...").0; let mut s2 = listener.accept().expect("Couldn't accept the connection...").0; let mut s3 = listener.accept().expect("Couldn't accept the connection...").0; s1.set_nonblocking(true).expect("set_nonblocking call failed"); s2.set_nonblocking(true).expect("set_nonblocking call failed"); s3.set_nonblocking(true).expect("set_nonblocking call failed"); s2.write(b"Hello from s2").expect("Couldn't write to the socket..."); s3.write(b"Hello from s3").expect("Couldn't write to the socket..."); client_notifier.send(()).expect("send client notification"); server_notification.recv().expect("receive server notification"); s1.shutdown(Shutdown::Both).expect("Couldn't shutdown the socket..."); s2.shutdown(Shutdown::Both).expect("Couldn't shutdown the socket..."); s3.shutdown(Shutdown::Both).expect("Couldn't shutdown the socket..."); }); let s1 = TcpStream::connect(LOCALHOST).expect("Couldn't connect to the server..."); let s2 = TcpStream::connect(LOCALHOST).expect("Couldn't connect to the server..."); let s3 = TcpStream::connect(LOCALHOST).expect("Couldn't connect to the server..."); s1.set_nonblocking(true).expect("set_nonblocking call failed"); s2.set_nonblocking(true).expect("set_nonblocking call failed"); s3.set_nonblocking(true).expect("set_nonblocking call failed"); client_notification.recv().expect("receive server notifcation"); selector.add_read(&s1); selector.add_read(&s2); selector.add_read(&s3); let result = selector.select().expect("To try select"); assert_eq!(result.len(), 2); assert!(!result.is_read(&s1)); assert!(result.is_read(&s2)); assert!(result.is_read(&s3)); server_notifier.send(()).expect("send server notifcation"); server.join().expect("Couldn't join the server thread..."); let result = selector.select().expect("To try select"); //Shutdown should trigger read assert_eq!(result.len(), 3); assert!(result.is_read(&s1)); assert!(result.is_read(&s2)); assert!(result.is_read(&s3)); }