use core::ops::Range; use core::time::Duration; use safina_async_test::async_test; use safina_net::TcpListener; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::time::Instant; fn any_port() -> std::net::SocketAddr { SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 0) } fn expect_elapsed(before: Instant, range_ms: Range) { assert!(!range_ms.is_empty(), "invalid range {:?}", range_ms); let elapsed = before.elapsed(); let duration_range = Duration::from_millis(range_ms.start)..Duration::from_millis(range_ms.end); assert!( duration_range.contains(&elapsed), "{:?} elapsed, out of range {:?}", elapsed, duration_range ); } #[test] fn bind_error() { let before = Instant::now(); let addr = SocketAddr::from(([127, 0, 0, 1], 1694)); let _listener = std::net::TcpListener::bind(&addr).unwrap(); assert_eq!( std::io::ErrorKind::AddrInUse, TcpListener::bind(addr).unwrap_err().kind() ); expect_elapsed(before, 0..10); } #[test] fn inner() { let listener = TcpListener::bind(&any_port()).unwrap(); let before = Instant::now(); let local_addr = listener.inner().local_addr().unwrap(); std::net::TcpStream::connect(local_addr).unwrap(); expect_elapsed(before, 0..100); } #[test] fn into_inner() { let listener = TcpListener::bind(&any_port()).unwrap(); let inner = listener.into_inner(); std::net::TcpStream::connect(inner.local_addr().unwrap()).unwrap(); } #[async_test] async fn try_clone() { let listener = TcpListener::bind(&any_port()).unwrap(); let clone = listener.try_clone().unwrap(); drop(listener); let addr = clone.inner().local_addr().unwrap(); std::thread::spawn(move || { std::net::TcpStream::connect(addr).unwrap(); }); clone.accept().await.unwrap(); drop(clone); assert_eq!( std::io::ErrorKind::ConnectionRefused, std::net::TcpStream::connect(addr).unwrap_err().kind() ); } #[async_test] async fn accepted_tcp_stream_remote_addr() { let listener = TcpListener::bind(&any_port()).unwrap(); let addr = listener.inner().local_addr().unwrap(); let before = Instant::now(); let (sender, receiver) = std::sync::mpsc::channel::(); std::thread::spawn(move || { //std::thread::sleep(Duration::from_millis(100)); let tcp_stream = std::net::TcpStream::connect(addr).unwrap(); sender.send(tcp_stream.local_addr().unwrap()).unwrap(); }); let (_tcp_stream, remote_addr) = listener.accept().await.unwrap(); expect_elapsed(before, 0..100); let remote_addr2 = receiver.recv_timeout(Duration::from_millis(500)).unwrap(); assert_eq!(remote_addr2, remote_addr); } #[async_test] async fn accept_many() { const NUM_THREADS: usize = 100; let listener = TcpListener::bind(&any_port()).unwrap(); let addr = listener.inner().local_addr().unwrap(); let before = Instant::now(); std::thread::spawn(move || { for _ in 0..NUM_THREADS { std::thread::spawn(move || { //std::thread::sleep(Duration::from_millis(100)); std::net::TcpStream::connect(addr).unwrap(); }); } }); for _ in 0..NUM_THREADS { listener.accept().await.unwrap(); //println!("."); } expect_elapsed(before, 0..5000); }