blob: 53cbdf20c45e08935a7feb99e380be7651b7e83e [file] [log] [blame]
#![cfg(all(feature = "os-poll", feature = "net"))]
use mio::net::{TcpKeepalive, TcpSocket};
use std::io;
use std::time::Duration;
#[test]
fn is_send_and_sync() {
fn is_send<T: Send>() {}
fn is_sync<T: Sync>() {}
is_send::<TcpSocket>();
is_sync::<TcpSocket>();
}
#[test]
fn set_reuseaddr() {
let addr = "127.0.0.1:0".parse().unwrap();
let socket = TcpSocket::new_v4().unwrap();
socket.set_reuseaddr(true).unwrap();
assert!(socket.get_reuseaddr().unwrap());
socket.bind(addr).unwrap();
let _ = socket.listen(128).unwrap();
}
#[cfg(all(unix, not(any(target_os = "solaris", target_os = "illumos"))))]
#[test]
fn set_reuseport() {
let addr = "127.0.0.1:0".parse().unwrap();
let socket = TcpSocket::new_v4().unwrap();
socket.set_reuseport(true).unwrap();
assert!(socket.get_reuseport().unwrap());
socket.bind(addr).unwrap();
let _ = socket.listen(128).unwrap();
}
#[test]
fn set_keepalive() {
let addr = "127.0.0.1:0".parse().unwrap();
let socket = TcpSocket::new_v4().unwrap();
socket.set_keepalive(false).unwrap();
assert_eq!(false, socket.get_keepalive().unwrap());
socket.set_keepalive(true).unwrap();
assert_eq!(true, socket.get_keepalive().unwrap());
socket.bind(addr).unwrap();
let _ = socket.listen(128).unwrap();
}
#[test]
fn set_keepalive_time() {
let dur = Duration::from_secs(4); // Chosen by fair dice roll, guaranteed to be random
let addr = "127.0.0.1:0".parse().unwrap();
let socket = TcpSocket::new_v4().unwrap();
socket
.set_keepalive_params(TcpKeepalive::default().with_time(dur))
.unwrap();
// It's not possible to access keepalive parameters on Windows...
#[cfg(not(target_os = "windows"))]
assert_eq!(Some(dur), socket.get_keepalive_time().unwrap());
socket.bind(addr).unwrap();
let _ = socket.listen(128).unwrap();
}
#[cfg(any(
target_os = "linux",
target_os = "macos",
target_os = "ios",
target_os = "freebsd",
target_os = "netbsd",
target_os = "windows"
))]
#[test]
fn set_keepalive_interval() {
let dur = Duration::from_secs(4); // Chosen by fair dice roll, guaranteed to be random
let addr = "127.0.0.1:0".parse().unwrap();
let socket = TcpSocket::new_v4().unwrap();
socket
.set_keepalive_params(TcpKeepalive::default().with_interval(dur))
.unwrap();
// It's not possible to access keepalive parameters on Windows...
#[cfg(not(target_os = "windows"))]
assert_eq!(Some(dur), socket.get_keepalive_interval().unwrap());
socket.bind(addr).unwrap();
let _ = socket.listen(128).unwrap();
}
#[cfg(any(
target_os = "linux",
target_os = "macos",
target_os = "ios",
target_os = "freebsd",
target_os = "netbsd",
))]
#[test]
fn set_keepalive_retries() {
let addr = "127.0.0.1:0".parse().unwrap();
let socket = TcpSocket::new_v4().unwrap();
socket
.set_keepalive_params(TcpKeepalive::default().with_retries(16))
.unwrap();
assert_eq!(Some(16), socket.get_keepalive_retries().unwrap());
socket.bind(addr).unwrap();
let _ = socket.listen(128).unwrap();
}
#[test]
fn get_localaddr() {
let expected_addr = "127.0.0.1:0".parse().unwrap();
let socket = TcpSocket::new_v4().unwrap();
//Windows doesn't support calling getsockname before calling `bind`
#[cfg(not(windows))]
assert_eq!("0.0.0.0:0", socket.get_localaddr().unwrap().to_string());
socket.bind(expected_addr).unwrap();
let actual_addr = socket.get_localaddr().unwrap();
assert_eq!(expected_addr.ip(), actual_addr.ip());
assert!(actual_addr.port() > 0);
let _ = socket.listen(128).unwrap();
}
#[test]
fn set_linger() {
let addr = "127.0.0.1:0".parse().unwrap();
let socket = TcpSocket::new_v4().unwrap();
socket.set_linger(Some(Duration::from_secs(1))).unwrap();
assert_eq!(socket.get_linger().unwrap().unwrap().as_secs(), 1);
let _ = socket.set_linger(None);
assert_eq!(socket.get_linger().unwrap(), None);
socket.bind(addr).unwrap();
let _ = socket.listen(128).unwrap();
}
#[test]
fn send_buffer_size_roundtrips() {
test_buffer_sizes(
TcpSocket::set_send_buffer_size,
TcpSocket::get_send_buffer_size,
)
}
#[test]
fn recv_buffer_size_roundtrips() {
test_buffer_sizes(
TcpSocket::set_recv_buffer_size,
TcpSocket::get_recv_buffer_size,
)
}
// Helper for testing send/recv buffer size.
fn test_buffer_sizes(
set: impl Fn(&TcpSocket, u32) -> io::Result<()>,
get: impl Fn(&TcpSocket) -> io::Result<u32>,
) {
let test = |size: u32| {
println!("testing buffer size: {}", size);
let socket = TcpSocket::new_v4().unwrap();
set(&socket, size).unwrap();
// Note that this doesn't assert that the values are equal: on Linux,
// the kernel doubles the requested buffer size, and returns the doubled
// value from `getsockopt`. As per `man socket(7)`:
// > Sets or gets the maximum socket send buffer in bytes. The
// > kernel doubles this value (to allow space for bookkeeping
// > overhead) when it is set using setsockopt(2), and this doubled
// > value is returned by getsockopt(2).
//
// Additionally, the buffer size may be clamped above a minimum value,
// and this minimum value is OS-dependent.
let actual = get(&socket).unwrap();
assert!(actual >= size, "\tactual: {}\n\texpected: {}", actual, size);
};
test(256);
test(4096);
test(65512);
}