mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-02 19:53:46 +00:00
std: Delete rt::test
This module contains many M:N specific concepts. This will no longer be available with libgreen, and most functions aren't really that necessary today anyway. New testing primitives will be introduced as they become available for 1:1 and M:N. A new io::test module is introduced with the new ip4/ip6 address helpers to continue usage in io tests.
This commit is contained in:
parent
1815aea368
commit
dafb310ba1
@ -147,468 +147,439 @@ impl Acceptor<TcpStream> for TcpAcceptor {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use rt::test::*;
|
||||
use io::net::ip::{Ipv4Addr, SocketAddr};
|
||||
use io::*;
|
||||
use io::test::{next_test_ip4, next_test_ip6};
|
||||
use prelude::*;
|
||||
|
||||
#[test] #[ignore]
|
||||
fn bind_error() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
assert!(e.kind == PermissionDenied);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
let listener = TcpListener::bind(addr);
|
||||
assert!(listener.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
assert!(e.kind == PermissionDenied);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
let listener = TcpListener::bind(addr);
|
||||
assert!(listener.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connect_error() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
let expected_error = if cfg!(unix) {
|
||||
ConnectionRefused
|
||||
} else {
|
||||
// On Win32, opening port 1 gives WSAEADDRNOTAVAIL error.
|
||||
OtherIoError
|
||||
};
|
||||
assert_eq!(e.kind, expected_error);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
let stream = TcpStream::connect(addr);
|
||||
assert!(stream.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
let expected_error = if cfg!(unix) {
|
||||
ConnectionRefused
|
||||
} else {
|
||||
// On Win32, opening port 1 gives WSAEADDRNOTAVAIL error.
|
||||
OtherIoError
|
||||
};
|
||||
assert_eq!(e.kind, expected_error);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
let stream = TcpStream::connect(addr);
|
||||
assert!(stream.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_test_ip4() {
|
||||
do run_in_mt_newsched_task {
|
||||
let addr = next_test_ip4();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert!(buf[0] == 99);
|
||||
}
|
||||
let addr = next_test_ip4();
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawn {
|
||||
port.recv();
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
stream.write([99]);
|
||||
}
|
||||
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert!(buf[0] == 99);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_test_ip6() {
|
||||
do run_in_mt_newsched_task {
|
||||
let addr = next_test_ip6();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert!(buf[0] == 99);
|
||||
}
|
||||
let addr = next_test_ip6();
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawn {
|
||||
port.recv();
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
stream.write([99]);
|
||||
}
|
||||
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert!(buf[0] == 99);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_eof_ip4() {
|
||||
do run_in_mt_newsched_task {
|
||||
let addr = next_test_ip4();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
}
|
||||
let addr = next_test_ip4();
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawn {
|
||||
port.recv();
|
||||
let _stream = TcpStream::connect(addr);
|
||||
// Close
|
||||
}
|
||||
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_eof_ip6() {
|
||||
do run_in_mt_newsched_task {
|
||||
let addr = next_test_ip6();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
}
|
||||
let addr = next_test_ip6();
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawn {
|
||||
port.recv();
|
||||
let _stream = TcpStream::connect(addr);
|
||||
// Close
|
||||
}
|
||||
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_eof_twice_ip4() {
|
||||
do run_in_mt_newsched_task {
|
||||
let addr = next_test_ip4();
|
||||
let (port, chan) = Chan::new();
|
||||
let addr = next_test_ip4();
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
io_error::cond.trap(|e| {
|
||||
if cfg!(windows) {
|
||||
assert_eq!(e.kind, NotConnected);
|
||||
} else {
|
||||
fail!();
|
||||
}
|
||||
}).inside(|| {
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
})
|
||||
}
|
||||
|
||||
port.recv();
|
||||
do spawn {
|
||||
port.take().recv();
|
||||
let _stream = TcpStream::connect(addr);
|
||||
// Close
|
||||
}
|
||||
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
io_error::cond.trap(|e| {
|
||||
if cfg!(windows) {
|
||||
assert_eq!(e.kind, NotConnected);
|
||||
} else {
|
||||
fail!();
|
||||
}
|
||||
}).inside(|| {
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_eof_twice_ip6() {
|
||||
do run_in_mt_newsched_task {
|
||||
let addr = next_test_ip6();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
io_error::cond.trap(|e| {
|
||||
if cfg!(windows) {
|
||||
assert_eq!(e.kind, NotConnected);
|
||||
} else {
|
||||
fail!();
|
||||
}
|
||||
}).inside(|| {
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
})
|
||||
}
|
||||
let addr = next_test_ip6();
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawn {
|
||||
port.recv();
|
||||
let _stream = TcpStream::connect(addr);
|
||||
// Close
|
||||
}
|
||||
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
io_error::cond.trap(|e| {
|
||||
if cfg!(windows) {
|
||||
assert_eq!(e.kind, NotConnected);
|
||||
} else {
|
||||
fail!();
|
||||
}
|
||||
}).inside(|| {
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_close_ip4() {
|
||||
do run_in_mt_newsched_task {
|
||||
let addr = next_test_ip4();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let buf = [0];
|
||||
loop {
|
||||
let mut stop = false;
|
||||
io_error::cond.trap(|e| {
|
||||
// NB: ECONNRESET on linux, EPIPE on mac, ECONNABORTED
|
||||
// on windows
|
||||
assert!(e.kind == ConnectionReset ||
|
||||
e.kind == BrokenPipe ||
|
||||
e.kind == ConnectionAborted,
|
||||
"unknown error: {:?}", e);
|
||||
stop = true;
|
||||
}).inside(|| {
|
||||
stream.write(buf);
|
||||
});
|
||||
if stop { break }
|
||||
}
|
||||
}
|
||||
let addr = next_test_ip4();
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawn {
|
||||
port.recv();
|
||||
let _stream = TcpStream::connect(addr);
|
||||
// Close
|
||||
}
|
||||
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let buf = [0];
|
||||
loop {
|
||||
let mut stop = false;
|
||||
io_error::cond.trap(|e| {
|
||||
// NB: ECONNRESET on linux, EPIPE on mac, ECONNABORTED
|
||||
// on windows
|
||||
assert!(e.kind == ConnectionReset ||
|
||||
e.kind == BrokenPipe ||
|
||||
e.kind == ConnectionAborted,
|
||||
"unknown error: {:?}", e);
|
||||
stop = true;
|
||||
}).inside(|| {
|
||||
stream.write(buf);
|
||||
});
|
||||
if stop { break }
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_close_ip6() {
|
||||
do run_in_mt_newsched_task {
|
||||
let addr = next_test_ip6();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let buf = [0];
|
||||
loop {
|
||||
let mut stop = false;
|
||||
io_error::cond.trap(|e| {
|
||||
// NB: ECONNRESET on linux, EPIPE on mac, ECONNABORTED
|
||||
// on windows
|
||||
assert!(e.kind == ConnectionReset ||
|
||||
e.kind == BrokenPipe ||
|
||||
e.kind == ConnectionAborted,
|
||||
"unknown error: {:?}", e);
|
||||
stop = true;
|
||||
}).inside(|| {
|
||||
stream.write(buf);
|
||||
});
|
||||
if stop { break }
|
||||
}
|
||||
}
|
||||
let addr = next_test_ip6();
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawn {
|
||||
port.recv();
|
||||
let _stream = TcpStream::connect(addr);
|
||||
// Close
|
||||
}
|
||||
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let buf = [0];
|
||||
loop {
|
||||
let mut stop = false;
|
||||
io_error::cond.trap(|e| {
|
||||
// NB: ECONNRESET on linux, EPIPE on mac, ECONNABORTED
|
||||
// on windows
|
||||
assert!(e.kind == ConnectionReset ||
|
||||
e.kind == BrokenPipe ||
|
||||
e.kind == ConnectionAborted,
|
||||
"unknown error: {:?}", e);
|
||||
stop = true;
|
||||
}).inside(|| {
|
||||
stream.write(buf);
|
||||
});
|
||||
if stop { break }
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_connect_serial_ip4() {
|
||||
do run_in_mt_newsched_task {
|
||||
let addr = next_test_ip4();
|
||||
let max = 10;
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
for ref mut stream in acceptor.incoming().take(max) {
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert_eq!(buf[0], 99);
|
||||
}
|
||||
}
|
||||
let addr = next_test_ip4();
|
||||
let max = 10;
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawn {
|
||||
port.recv();
|
||||
max.times(|| {
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
stream.write([99]);
|
||||
});
|
||||
}
|
||||
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
for ref mut stream in acceptor.incoming().take(max) {
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert_eq!(buf[0], 99);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_connect_serial_ip6() {
|
||||
do run_in_mt_newsched_task {
|
||||
let addr = next_test_ip6();
|
||||
let max = 10;
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
for ref mut stream in acceptor.incoming().take(max) {
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert_eq!(buf[0], 99);
|
||||
}
|
||||
}
|
||||
let addr = next_test_ip6();
|
||||
let max = 10;
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawn {
|
||||
port.recv();
|
||||
max.times(|| {
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
stream.write([99]);
|
||||
});
|
||||
}
|
||||
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
for ref mut stream in acceptor.incoming().take(max) {
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert_eq!(buf[0], 99);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_connect_interleaved_greedy_schedule_ip4() {
|
||||
do run_in_mt_newsched_task {
|
||||
let addr = next_test_ip4();
|
||||
static MAX: int = 10;
|
||||
let (port, chan) = Chan::new();
|
||||
let addr = next_test_ip4();
|
||||
static MAX: int = 10;
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
|
||||
// Start another task to handle the connection
|
||||
do spawntask {
|
||||
let mut stream = stream;
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert!(buf[0] == i as u8);
|
||||
debug!("read");
|
||||
}
|
||||
do spawn {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
|
||||
let stream = Cell::new(stream);
|
||||
// Start another task to handle the connection
|
||||
do spawn {
|
||||
let mut stream = stream.take();
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert!(buf[0] == i as u8);
|
||||
debug!("read");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
port.recv();
|
||||
connect(0, addr);
|
||||
port.recv();
|
||||
connect(0, addr);
|
||||
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
if i == MAX { return }
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
if i == MAX { return }
|
||||
|
||||
do spawntask {
|
||||
debug!("connecting");
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
stream.write([i as u8]);
|
||||
}
|
||||
do spawn {
|
||||
debug!("connecting");
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
stream.write([i as u8]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_connect_interleaved_greedy_schedule_ip6() {
|
||||
do run_in_mt_newsched_task {
|
||||
let addr = next_test_ip6();
|
||||
static MAX: int = 10;
|
||||
let (port, chan) = Chan::new();
|
||||
let addr = next_test_ip6();
|
||||
static MAX: int = 10;
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
|
||||
// Start another task to handle the connection
|
||||
do spawntask {
|
||||
let mut stream = stream;
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert!(buf[0] == i as u8);
|
||||
debug!("read");
|
||||
}
|
||||
do spawn {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
|
||||
let stream = Cell::new(stream);
|
||||
// Start another task to handle the connection
|
||||
do spawn {
|
||||
let mut stream = stream.take();
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert!(buf[0] == i as u8);
|
||||
debug!("read");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
port.recv();
|
||||
connect(0, addr);
|
||||
port.recv();
|
||||
connect(0, addr);
|
||||
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
if i == MAX { return }
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
if i == MAX { return }
|
||||
|
||||
do spawntask {
|
||||
debug!("connecting");
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
stream.write([i as u8]);
|
||||
}
|
||||
do spawn {
|
||||
debug!("connecting");
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
stream.write([i as u8]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_connect_interleaved_lazy_schedule_ip4() {
|
||||
do run_in_mt_newsched_task {
|
||||
let addr = next_test_ip4();
|
||||
static MAX: int = 10;
|
||||
let (port, chan) = Chan::new();
|
||||
let addr = next_test_ip4();
|
||||
static MAX: int = 10;
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
for stream in acceptor.incoming().take(MAX as uint) {
|
||||
// Start another task to handle the connection
|
||||
do spawntask_later {
|
||||
let mut stream = stream;
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert!(buf[0] == 99);
|
||||
debug!("read");
|
||||
}
|
||||
do spawn {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
for stream in acceptor.incoming().take(MAX as uint) {
|
||||
let stream = Cell::new(stream);
|
||||
// Start another task to handle the connection
|
||||
do spawn {
|
||||
let mut stream = stream.take();
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert!(buf[0] == 99);
|
||||
debug!("read");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
port.recv();
|
||||
connect(0, addr);
|
||||
port.recv();
|
||||
connect(0, addr);
|
||||
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
if i == MAX { return }
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
if i == MAX { return }
|
||||
|
||||
do spawntask_later {
|
||||
debug!("connecting");
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
stream.write([99]);
|
||||
}
|
||||
do spawn {
|
||||
debug!("connecting");
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
stream.write([99]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn multiple_connect_interleaved_lazy_schedule_ip6() {
|
||||
do run_in_mt_newsched_task {
|
||||
let addr = next_test_ip6();
|
||||
static MAX: int = 10;
|
||||
let (port, chan) = Chan::new();
|
||||
let addr = next_test_ip6();
|
||||
static MAX: int = 10;
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
for stream in acceptor.incoming().take(MAX as uint) {
|
||||
// Start another task to handle the connection
|
||||
do spawntask_later {
|
||||
let mut stream = stream;
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert!(buf[0] == 99);
|
||||
debug!("read");
|
||||
}
|
||||
do spawn {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
for stream in acceptor.incoming().take(MAX as uint) {
|
||||
let stream = Cell::new(stream);
|
||||
// Start another task to handle the connection
|
||||
do spawn {
|
||||
let mut stream = stream.take();
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert!(buf[0] == 99);
|
||||
debug!("read");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
port.recv();
|
||||
connect(0, addr);
|
||||
port.recv();
|
||||
connect(0, addr);
|
||||
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
if i == MAX { return }
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
if i == MAX { return }
|
||||
|
||||
do spawntask_later {
|
||||
debug!("connecting");
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
stream.write([99]);
|
||||
}
|
||||
do spawn {
|
||||
debug!("connecting");
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
stream.write([99]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -631,29 +602,26 @@ mod test {
|
||||
|
||||
#[cfg(test)]
|
||||
fn peer_name(addr: SocketAddr) {
|
||||
do run_in_mt_newsched_task {
|
||||
let (port, chan) = Chan::new();
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
|
||||
acceptor.accept();
|
||||
}
|
||||
|
||||
port.recv();
|
||||
let stream = TcpStream::connect(addr);
|
||||
|
||||
assert!(stream.is_some());
|
||||
let mut stream = stream.unwrap();
|
||||
|
||||
// Make sure peer_name gives us the
|
||||
// address/port of the peer we've
|
||||
// connected to.
|
||||
let peer_name = stream.peer_name();
|
||||
assert!(peer_name.is_some());
|
||||
assert_eq!(addr, peer_name.unwrap());
|
||||
do spawn {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
acceptor.accept();
|
||||
}
|
||||
|
||||
port.recv();
|
||||
let stream = TcpStream::connect(addr);
|
||||
|
||||
assert!(stream.is_some());
|
||||
let mut stream = stream.unwrap();
|
||||
|
||||
// Make sure peer_name gives us the
|
||||
// address/port of the peer we've
|
||||
// connected to.
|
||||
let peer_name = stream.peer_name();
|
||||
assert!(peer_name.is_some());
|
||||
assert_eq!(addr, peer_name.unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -668,5 +636,4 @@ mod test {
|
||||
//peer_name(next_test_ip6());
|
||||
socket_name(next_test_ip6());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -104,52 +104,31 @@ impl Writer for UdpStream {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use rt::test::*;
|
||||
use io::net::ip::{Ipv4Addr, SocketAddr};
|
||||
use io::*;
|
||||
use prelude::*;
|
||||
|
||||
#[test] #[ignore]
|
||||
fn bind_error() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
assert!(e.kind == PermissionDenied);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
let socket = UdpSocket::bind(addr);
|
||||
assert!(socket.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
assert!(e.kind == PermissionDenied);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
let socket = UdpSocket::bind(addr);
|
||||
assert!(socket.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn socket_smoke_test_ip4() {
|
||||
do run_in_mt_newsched_task {
|
||||
let server_ip = next_test_ip4();
|
||||
let client_ip = next_test_ip4();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawntask {
|
||||
match UdpSocket::bind(server_ip) {
|
||||
Some(ref mut server) => {
|
||||
chan.send(());
|
||||
let mut buf = [0];
|
||||
match server.recvfrom(buf) {
|
||||
Some((nread, src)) => {
|
||||
assert_eq!(nread, 1);
|
||||
assert_eq!(buf[0], 99);
|
||||
assert_eq!(src, client_ip);
|
||||
}
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
let server_ip = next_test_ip4();
|
||||
let client_ip = next_test_ip4();
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawn {
|
||||
match UdpSocket::bind(client_ip) {
|
||||
Some(ref mut client) => {
|
||||
port.recv();
|
||||
@ -158,33 +137,31 @@ mod test {
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
|
||||
match UdpSocket::bind(server_ip) {
|
||||
Some(ref mut server) => {
|
||||
chan.send(());
|
||||
let mut buf = [0];
|
||||
match server.recvfrom(buf) {
|
||||
Some((nread, src)) => {
|
||||
assert_eq!(nread, 1);
|
||||
assert_eq!(buf[0], 99);
|
||||
assert_eq!(src, client_ip);
|
||||
}
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn socket_smoke_test_ip6() {
|
||||
do run_in_mt_newsched_task {
|
||||
let server_ip = next_test_ip6();
|
||||
let client_ip = next_test_ip6();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawntask {
|
||||
match UdpSocket::bind(server_ip) {
|
||||
Some(ref mut server) => {
|
||||
chan.send(());
|
||||
let mut buf = [0];
|
||||
match server.recvfrom(buf) {
|
||||
Some((nread, src)) => {
|
||||
assert_eq!(nread, 1);
|
||||
assert_eq!(buf[0], 99);
|
||||
assert_eq!(src, client_ip);
|
||||
}
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
let server_ip = next_test_ip6();
|
||||
let client_ip = next_test_ip6();
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawn {
|
||||
match UdpSocket::bind(client_ip) {
|
||||
Some(ref mut client) => {
|
||||
port.recv();
|
||||
@ -193,34 +170,31 @@ mod test {
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stream_smoke_test_ip4() {
|
||||
do run_in_mt_newsched_task {
|
||||
let server_ip = next_test_ip4();
|
||||
let client_ip = next_test_ip4();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawntask {
|
||||
match UdpSocket::bind(server_ip) {
|
||||
Some(server) => {
|
||||
let server = ~server;
|
||||
let mut stream = server.connect(client_ip);
|
||||
chan.send(());
|
||||
let mut buf = [0];
|
||||
match stream.read(buf) {
|
||||
Some(nread) => {
|
||||
assert_eq!(nread, 1);
|
||||
assert_eq!(buf[0], 99);
|
||||
}
|
||||
None => fail!()
|
||||
}
|
||||
match UdpSocket::bind(server_ip) {
|
||||
Some(ref mut server) => {
|
||||
chan.take().send(());
|
||||
let mut buf = [0];
|
||||
match server.recvfrom(buf) {
|
||||
Some((nread, src)) => {
|
||||
assert_eq!(nread, 1);
|
||||
assert_eq!(buf[0], 99);
|
||||
assert_eq!(src, client_ip);
|
||||
}
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stream_smoke_test_ip4() {
|
||||
let server_ip = next_test_ip4();
|
||||
let client_ip = next_test_ip4();
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawn {
|
||||
match UdpSocket::bind(client_ip) {
|
||||
Some(client) => {
|
||||
let client = ~client;
|
||||
@ -231,34 +205,32 @@ mod test {
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
|
||||
match UdpSocket::bind(server_ip) {
|
||||
Some(server) => {
|
||||
let server = ~server;
|
||||
let mut stream = server.connect(client_ip);
|
||||
chan.send(());
|
||||
let mut buf = [0];
|
||||
match stream.read(buf) {
|
||||
Some(nread) => {
|
||||
assert_eq!(nread, 1);
|
||||
assert_eq!(buf[0], 99);
|
||||
}
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stream_smoke_test_ip6() {
|
||||
do run_in_mt_newsched_task {
|
||||
let server_ip = next_test_ip6();
|
||||
let client_ip = next_test_ip6();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawntask {
|
||||
match UdpSocket::bind(server_ip) {
|
||||
Some(server) => {
|
||||
let server = ~server;
|
||||
let mut stream = server.connect(client_ip);
|
||||
chan.send(());
|
||||
let mut buf = [0];
|
||||
match stream.read(buf) {
|
||||
Some(nread) => {
|
||||
assert_eq!(nread, 1);
|
||||
assert_eq!(buf[0], 99);
|
||||
}
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
let server_ip = next_test_ip6();
|
||||
let client_ip = next_test_ip6();
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawn {
|
||||
match UdpSocket::bind(client_ip) {
|
||||
Some(client) => {
|
||||
let client = ~client;
|
||||
@ -269,25 +241,36 @@ mod test {
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
|
||||
match UdpSocket::bind(server_ip) {
|
||||
Some(server) => {
|
||||
let server = ~server;
|
||||
let mut stream = server.connect(client_ip);
|
||||
chan.send(());
|
||||
let mut buf = [0];
|
||||
match stream.read(buf) {
|
||||
Some(nread) => {
|
||||
assert_eq!(nread, 1);
|
||||
assert_eq!(buf[0], 99);
|
||||
}
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn socket_name(addr: SocketAddr) {
|
||||
do run_in_mt_newsched_task {
|
||||
do spawntask {
|
||||
let server = UdpSocket::bind(addr);
|
||||
let server = UdpSocket::bind(addr);
|
||||
|
||||
assert!(server.is_some());
|
||||
let mut server = server.unwrap();
|
||||
assert!(server.is_some());
|
||||
let mut server = server.unwrap();
|
||||
|
||||
// Make sure socket_name gives
|
||||
// us the socket we binded to.
|
||||
let so_name = server.socket_name();
|
||||
assert!(so_name.is_some());
|
||||
assert_eq!(addr, so_name.unwrap());
|
||||
|
||||
}
|
||||
}
|
||||
// Make sure socket_name gives
|
||||
// us the socket we binded to.
|
||||
let so_name = server.socket_name();
|
||||
assert!(so_name.is_some());
|
||||
assert_eq!(addr, so_name.unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -150,55 +150,47 @@ impl Acceptor<UnixStream> for UnixAcceptor {
|
||||
mod tests {
|
||||
use prelude::*;
|
||||
use super::*;
|
||||
use rt::test::*;
|
||||
use io::*;
|
||||
|
||||
fn smalltest(server: proc(UnixStream), client: proc(UnixStream)) {
|
||||
do run_in_mt_newsched_task {
|
||||
let path1 = next_test_unix();
|
||||
let path2 = path1.clone();
|
||||
let (client, server) = (client, server);
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = UnixListener::bind(&path1).listen();
|
||||
chan.send(());
|
||||
server(acceptor.accept().unwrap());
|
||||
}
|
||||
let path1 = next_test_unix();
|
||||
let path2 = path1.clone();
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawn {
|
||||
port.recv();
|
||||
client(UnixStream::connect(&path2).unwrap());
|
||||
}
|
||||
|
||||
let mut acceptor = UnixListener::bind(&path1).listen();
|
||||
chan.send(());
|
||||
server(acceptor.accept().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bind_error() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
assert!(e.kind == PermissionDenied);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let listener = UnixListener::bind(&("path/to/nowhere"));
|
||||
assert!(listener.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
assert!(e.kind == PermissionDenied);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let listener = UnixListener::bind(&("path/to/nowhere"));
|
||||
assert!(listener.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connect_error() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
assert_eq!(e.kind, FileNotFound);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let stream = UnixStream::connect(&("path/to/nowhere"));
|
||||
assert!(stream.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
assert_eq!(e.kind, OtherIoError);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let stream = UnixStream::connect(&("path/to/nowhere"));
|
||||
assert!(stream.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -244,37 +236,33 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn accept_lots() {
|
||||
do run_in_mt_newsched_task {
|
||||
let times = 10;
|
||||
let path1 = next_test_unix();
|
||||
let path2 = path1.clone();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawntask {
|
||||
let mut acceptor = UnixListener::bind(&path1).listen();
|
||||
chan.send(());
|
||||
times.times(|| {
|
||||
let mut client = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
client.read(buf);
|
||||
assert_eq!(buf[0], 100);
|
||||
})
|
||||
}
|
||||
let times = 10;
|
||||
let path1 = next_test_unix();
|
||||
let path2 = path1.clone();
|
||||
let (port, chan) = oneshot();
|
||||
|
||||
do spawn {
|
||||
port.recv();
|
||||
times.times(|| {
|
||||
let mut stream = UnixStream::connect(&path2);
|
||||
stream.write([100]);
|
||||
})
|
||||
}
|
||||
|
||||
let mut acceptor = UnixListener::bind(&path1).listen();
|
||||
chan.send(());
|
||||
times.times(|| {
|
||||
let mut client = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
client.read(buf);
|
||||
assert_eq!(buf[0], 100);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_exists() {
|
||||
do run_in_mt_newsched_task {
|
||||
let path = next_test_unix();
|
||||
let _acceptor = UnixListener::bind(&path).listen();
|
||||
assert!(path.exists());
|
||||
}
|
||||
let path = next_test_unix();
|
||||
let _acceptor = UnixListener::bind(&path).listen();
|
||||
assert!(path.exists());
|
||||
}
|
||||
}
|
||||
|
@ -106,53 +106,46 @@ impl<T, A: Acceptor<T>> Acceptor<T> for Option<A> {
|
||||
mod test {
|
||||
use option::*;
|
||||
use super::super::mem::*;
|
||||
use rt::test::*;
|
||||
use super::super::{PreviousIoError, io_error};
|
||||
|
||||
#[test]
|
||||
fn test_option_writer() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut writer: Option<MemWriter> = Some(MemWriter::new());
|
||||
writer.write([0, 1, 2]);
|
||||
writer.flush();
|
||||
assert_eq!(writer.unwrap().inner(), ~[0, 1, 2]);
|
||||
}
|
||||
let mut writer: Option<MemWriter> = Some(MemWriter::new());
|
||||
writer.write([0, 1, 2]);
|
||||
writer.flush();
|
||||
assert_eq!(writer.unwrap().inner(), ~[0, 1, 2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_writer_error() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut writer: Option<MemWriter> = None;
|
||||
let mut writer: Option<MemWriter> = None;
|
||||
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|err| {
|
||||
assert_eq!(err.kind, PreviousIoError);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
writer.write([0, 0, 0]);
|
||||
});
|
||||
assert!(called);
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|err| {
|
||||
assert_eq!(err.kind, PreviousIoError);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
writer.write([0, 0, 0]);
|
||||
});
|
||||
assert!(called);
|
||||
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|err| {
|
||||
assert_eq!(err.kind, PreviousIoError);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
writer.flush();
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|err| {
|
||||
assert_eq!(err.kind, PreviousIoError);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
writer.flush();
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_reader() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut reader: Option<MemReader> = Some(MemReader::new(~[0, 1, 2, 3]));
|
||||
let mut buf = [0, 0];
|
||||
reader.read(buf);
|
||||
assert_eq!(buf, [0, 1]);
|
||||
assert!(!reader.eof());
|
||||
}
|
||||
let mut reader: Option<MemReader> = Some(MemReader::new(~[0, 1, 2, 3]));
|
||||
let mut buf = [0, 0];
|
||||
reader.read(buf);
|
||||
assert_eq!(buf, [0, 1]);
|
||||
assert!(!reader.eof());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
79
src/libstd/io/test.rs
Normal file
79
src/libstd/io/test.rs
Normal file
@ -0,0 +1,79 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/// Get a port number, starting at 9600, for use in tests
|
||||
pub fn next_test_port() -> u16 {
|
||||
use unstable::atomics::{AtomicUint, INIT_ATOMIC_UINT, Relaxed};
|
||||
static mut next_offset: AtomicUint = INIT_ATOMIC_UINT;
|
||||
unsafe {
|
||||
base_port() + next_offset.fetch_add(1, Relaxed) as u16
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a temporary path which could be the location of a unix socket
|
||||
pub fn next_test_unix() -> Path {
|
||||
if cfg!(unix) {
|
||||
os::tmpdir().join(rand::task_rng().gen_ascii_str(20))
|
||||
} else {
|
||||
Path::new(r"\\.\pipe\" + rand::task_rng().gen_ascii_str(20))
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a unique IPv4 localhost:port pair starting at 9600
|
||||
pub fn next_test_ip4() -> SocketAddr {
|
||||
SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: next_test_port() }
|
||||
}
|
||||
|
||||
/// Get a unique IPv6 localhost:port pair starting at 9600
|
||||
pub fn next_test_ip6() -> SocketAddr {
|
||||
SocketAddr { ip: Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1), port: next_test_port() }
|
||||
}
|
||||
|
||||
/*
|
||||
XXX: Welcome to MegaHack City.
|
||||
|
||||
The bots run multiple builds at the same time, and these builds
|
||||
all want to use ports. This function figures out which workspace
|
||||
it is running in and assigns a port range based on it.
|
||||
*/
|
||||
fn base_port() -> u16 {
|
||||
use os;
|
||||
use str::StrSlice;
|
||||
use vec::ImmutableVector;
|
||||
|
||||
let base = 9600u16;
|
||||
let range = 1000u16;
|
||||
|
||||
let bases = [
|
||||
("32-opt", base + range * 1),
|
||||
("32-noopt", base + range * 2),
|
||||
("64-opt", base + range * 3),
|
||||
("64-noopt", base + range * 4),
|
||||
("64-opt-vg", base + range * 5),
|
||||
("all-opt", base + range * 6),
|
||||
("snap3", base + range * 7),
|
||||
("dist", base + range * 8)
|
||||
];
|
||||
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
let path = os::getcwd();
|
||||
let path_s = path.as_str().unwrap();
|
||||
|
||||
let mut final_base = base;
|
||||
|
||||
for &(dir, base) in bases.iter() {
|
||||
if path_s.contains(dir) {
|
||||
final_base = base;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return final_base;
|
||||
}
|
@ -108,77 +108,60 @@ impl Timer {
|
||||
mod test {
|
||||
use prelude::*;
|
||||
use super::*;
|
||||
use rt::test::*;
|
||||
|
||||
#[test]
|
||||
fn test_io_timer_sleep_simple() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut timer = Timer::new().unwrap();
|
||||
timer.sleep(1);
|
||||
}
|
||||
let mut timer = Timer::new().unwrap();
|
||||
timer.sleep(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_io_timer_sleep_oneshot() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut timer = Timer::new().unwrap();
|
||||
timer.oneshot(1).recv();
|
||||
}
|
||||
let mut timer = Timer::new().unwrap();
|
||||
timer.oneshot(1).recv();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_io_timer_sleep_oneshot_forget() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut timer = Timer::new().unwrap();
|
||||
timer.oneshot(100000000000);
|
||||
}
|
||||
let mut timer = Timer::new().unwrap();
|
||||
timer.oneshot(100000000000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oneshot_twice() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut timer = Timer::new().unwrap();
|
||||
let port1 = timer.oneshot(10000);
|
||||
let port = timer.oneshot(1);
|
||||
port.recv();
|
||||
assert_eq!(port1.try_recv(), None);
|
||||
}
|
||||
let mut timer = Timer::new().unwrap();
|
||||
let port1 = timer.oneshot(10000);
|
||||
let port = timer.oneshot(1);
|
||||
port.recv();
|
||||
assert_eq!(port1.try_recv(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_io_timer_oneshot_then_sleep() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut timer = Timer::new().unwrap();
|
||||
let port = timer.oneshot(100000000000);
|
||||
timer.sleep(1); // this should invalidate the port
|
||||
let mut timer = Timer::new().unwrap();
|
||||
let port = timer.oneshot(100000000000);
|
||||
timer.sleep(1); // this should invalidate the port
|
||||
|
||||
assert_eq!(port.try_recv(), None);
|
||||
}
|
||||
assert_eq!(port.try_recv(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_io_timer_sleep_periodic() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut timer = Timer::new().unwrap();
|
||||
let port = timer.periodic(1);
|
||||
port.recv();
|
||||
port.recv();
|
||||
port.recv();
|
||||
}
|
||||
let mut timer = Timer::new().unwrap();
|
||||
let port = timer.periodic(1);
|
||||
port.recv();
|
||||
port.recv();
|
||||
port.recv();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_io_timer_sleep_periodic_forget() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut timer = Timer::new().unwrap();
|
||||
timer.periodic(100000000000);
|
||||
}
|
||||
let mut timer = Timer::new().unwrap();
|
||||
timer.periodic(100000000000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_io_timer_sleep_standalone() {
|
||||
do run_in_mt_newsched_task {
|
||||
sleep(1)
|
||||
}
|
||||
sleep(1)
|
||||
}
|
||||
}
|
||||
|
@ -1,440 +0,0 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr};
|
||||
|
||||
use clone::Clone;
|
||||
use container::Container;
|
||||
use iter::{Iterator, range};
|
||||
use option::{Some, None};
|
||||
use os;
|
||||
use path::GenericPath;
|
||||
use path::Path;
|
||||
use rand::Rng;
|
||||
use rand;
|
||||
use result::{Result, Ok, Err};
|
||||
use rt::basic;
|
||||
use rt::deque::BufferPool;
|
||||
use comm::Chan;
|
||||
use rt::new_event_loop;
|
||||
use rt::sched::Scheduler;
|
||||
use rt::sleeper_list::SleeperList;
|
||||
use rt::task::Task;
|
||||
use rt::thread::Thread;
|
||||
use task::TaskResult;
|
||||
use unstable::{run_in_bare_thread};
|
||||
use vec;
|
||||
use vec::{OwnedVector, MutableVector, ImmutableVector};
|
||||
|
||||
pub fn new_test_uv_sched() -> Scheduler {
|
||||
|
||||
let mut pool = BufferPool::new();
|
||||
let (worker, stealer) = pool.deque();
|
||||
|
||||
let mut sched = Scheduler::new(new_event_loop(),
|
||||
worker,
|
||||
~[stealer],
|
||||
SleeperList::new());
|
||||
|
||||
// Don't wait for the Shutdown message
|
||||
sched.no_sleep = true;
|
||||
return sched;
|
||||
|
||||
}
|
||||
|
||||
pub fn new_test_sched() -> Scheduler {
|
||||
let mut pool = BufferPool::new();
|
||||
let (worker, stealer) = pool.deque();
|
||||
|
||||
let mut sched = Scheduler::new(basic::event_loop(),
|
||||
worker,
|
||||
~[stealer],
|
||||
SleeperList::new());
|
||||
|
||||
// Don't wait for the Shutdown message
|
||||
sched.no_sleep = true;
|
||||
return sched;
|
||||
}
|
||||
|
||||
pub fn run_in_uv_task(f: proc()) {
|
||||
do run_in_bare_thread {
|
||||
run_in_uv_task_core(f);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_in_newsched_task(f: proc()) {
|
||||
do run_in_bare_thread {
|
||||
run_in_newsched_task_core(f);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_in_uv_task_core(f: proc()) {
|
||||
|
||||
use rt::sched::Shutdown;
|
||||
|
||||
let mut sched = ~new_test_uv_sched();
|
||||
let exit_handle = sched.make_handle();
|
||||
|
||||
let on_exit: proc(TaskResult) = proc(exit_status: TaskResult) {
|
||||
let mut exit_handle = exit_handle;
|
||||
exit_handle.send(Shutdown);
|
||||
rtassert!(exit_status.is_ok());
|
||||
};
|
||||
let mut task = ~Task::new_root(&mut sched.stack_pool, None, f);
|
||||
task.death.on_exit = Some(on_exit);
|
||||
|
||||
sched.bootstrap(task);
|
||||
}
|
||||
|
||||
pub fn run_in_newsched_task_core(f: proc()) {
|
||||
use rt::sched::Shutdown;
|
||||
|
||||
let mut sched = ~new_test_sched();
|
||||
let exit_handle = sched.make_handle();
|
||||
|
||||
let on_exit: proc(TaskResult) = proc(exit_status: TaskResult) {
|
||||
let mut exit_handle = exit_handle;
|
||||
exit_handle.send(Shutdown);
|
||||
rtassert!(exit_status.is_ok());
|
||||
};
|
||||
let mut task = ~Task::new_root(&mut sched.stack_pool, None, f);
|
||||
task.death.on_exit = Some(on_exit);
|
||||
|
||||
sched.bootstrap(task);
|
||||
}
|
||||
|
||||
#[cfg(target_os="macos")]
|
||||
#[allow(non_camel_case_types)]
|
||||
mod darwin_fd_limit {
|
||||
/*!
|
||||
* darwin_fd_limit exists to work around an issue where launchctl on Mac OS X defaults the
|
||||
* rlimit maxfiles to 256/unlimited. The default soft limit of 256 ends up being far too low
|
||||
* for our multithreaded scheduler testing, depending on the number of cores available.
|
||||
*
|
||||
* This fixes issue #7772.
|
||||
*/
|
||||
|
||||
use libc;
|
||||
type rlim_t = libc::uint64_t;
|
||||
struct rlimit {
|
||||
rlim_cur: rlim_t,
|
||||
rlim_max: rlim_t
|
||||
}
|
||||
#[nolink]
|
||||
extern {
|
||||
// name probably doesn't need to be mut, but the C function doesn't specify const
|
||||
fn sysctl(name: *mut libc::c_int, namelen: libc::c_uint,
|
||||
oldp: *mut libc::c_void, oldlenp: *mut libc::size_t,
|
||||
newp: *mut libc::c_void, newlen: libc::size_t) -> libc::c_int;
|
||||
fn getrlimit(resource: libc::c_int, rlp: *mut rlimit) -> libc::c_int;
|
||||
fn setrlimit(resource: libc::c_int, rlp: *rlimit) -> libc::c_int;
|
||||
}
|
||||
static CTL_KERN: libc::c_int = 1;
|
||||
static KERN_MAXFILESPERPROC: libc::c_int = 29;
|
||||
static RLIMIT_NOFILE: libc::c_int = 8;
|
||||
|
||||
pub unsafe fn raise_fd_limit() {
|
||||
// The strategy here is to fetch the current resource limits, read the kern.maxfilesperproc
|
||||
// sysctl value, and bump the soft resource limit for maxfiles up to the sysctl value.
|
||||
use ptr::{to_unsafe_ptr, to_mut_unsafe_ptr, mut_null};
|
||||
use mem::size_of_val;
|
||||
use os::last_os_error;
|
||||
|
||||
// Fetch the kern.maxfilesperproc value
|
||||
let mut mib: [libc::c_int, ..2] = [CTL_KERN, KERN_MAXFILESPERPROC];
|
||||
let mut maxfiles: libc::c_int = 0;
|
||||
let mut size: libc::size_t = size_of_val(&maxfiles) as libc::size_t;
|
||||
if sysctl(to_mut_unsafe_ptr(&mut mib[0]), 2,
|
||||
to_mut_unsafe_ptr(&mut maxfiles) as *mut libc::c_void,
|
||||
to_mut_unsafe_ptr(&mut size),
|
||||
mut_null(), 0) != 0 {
|
||||
let err = last_os_error();
|
||||
error!("raise_fd_limit: error calling sysctl: {}", err);
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch the current resource limits
|
||||
let mut rlim = rlimit{rlim_cur: 0, rlim_max: 0};
|
||||
if getrlimit(RLIMIT_NOFILE, to_mut_unsafe_ptr(&mut rlim)) != 0 {
|
||||
let err = last_os_error();
|
||||
error!("raise_fd_limit: error calling getrlimit: {}", err);
|
||||
return;
|
||||
}
|
||||
|
||||
// Bump the soft limit to the smaller of kern.maxfilesperproc and the hard limit
|
||||
rlim.rlim_cur = ::cmp::min(maxfiles as rlim_t, rlim.rlim_max);
|
||||
|
||||
// Set our newly-increased resource limit
|
||||
if setrlimit(RLIMIT_NOFILE, to_unsafe_ptr(&rlim)) != 0 {
|
||||
let err = last_os_error();
|
||||
error!("raise_fd_limit: error calling setrlimit: {}", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os="macos"))]
|
||||
mod darwin_fd_limit {
|
||||
pub unsafe fn raise_fd_limit() {}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn prepare_for_lots_of_tests() {
|
||||
// Bump the fd limit on OS X. See darwin_fd_limit for an explanation.
|
||||
unsafe { darwin_fd_limit::raise_fd_limit() }
|
||||
}
|
||||
|
||||
/// Create more than one scheduler and run a function in a task
|
||||
/// in one of the schedulers. The schedulers will stay alive
|
||||
/// until the function `f` returns.
|
||||
pub fn run_in_mt_newsched_task(f: proc()) {
|
||||
use os;
|
||||
use from_str::FromStr;
|
||||
use rt::sched::Shutdown;
|
||||
use rt::util;
|
||||
|
||||
// see comment in other function (raising fd limits)
|
||||
prepare_for_lots_of_tests();
|
||||
|
||||
do run_in_bare_thread {
|
||||
let nthreads = match os::getenv("RUST_RT_TEST_THREADS") {
|
||||
Some(nstr) => FromStr::from_str(nstr).unwrap(),
|
||||
None => {
|
||||
if util::limit_thread_creation_due_to_osx_and_valgrind() {
|
||||
1
|
||||
} else {
|
||||
// Using more threads than cores in test code
|
||||
// to force the OS to preempt them frequently.
|
||||
// Assuming that this help stress test concurrent types.
|
||||
util::num_cpus() * 2
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let sleepers = SleeperList::new();
|
||||
|
||||
let mut handles = ~[];
|
||||
let mut scheds = ~[];
|
||||
|
||||
let mut pool = BufferPool::<~Task>::new();
|
||||
let workers = range(0, nthreads).map(|_| pool.deque());
|
||||
let (workers, stealers) = vec::unzip(workers);
|
||||
|
||||
for worker in workers.move_iter() {
|
||||
let loop_ = new_event_loop();
|
||||
let mut sched = ~Scheduler::new(loop_,
|
||||
worker,
|
||||
stealers.clone(),
|
||||
sleepers.clone());
|
||||
let handle = sched.make_handle();
|
||||
|
||||
handles.push(handle);
|
||||
scheds.push(sched);
|
||||
}
|
||||
|
||||
let handles = handles; // Work around not being able to capture mut
|
||||
let on_exit: proc(TaskResult) = proc(exit_status: TaskResult) {
|
||||
// Tell schedulers to exit
|
||||
let mut handles = handles;
|
||||
for handle in handles.mut_iter() {
|
||||
handle.send(Shutdown);
|
||||
}
|
||||
|
||||
rtassert!(exit_status.is_ok());
|
||||
};
|
||||
let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool,
|
||||
None,
|
||||
f);
|
||||
main_task.death.on_exit = Some(on_exit);
|
||||
|
||||
let mut threads = ~[];
|
||||
|
||||
let main_thread = {
|
||||
let sched = scheds.pop();
|
||||
let main_task = main_task;
|
||||
do Thread::start {
|
||||
sched.bootstrap(main_task);
|
||||
}
|
||||
};
|
||||
threads.push(main_thread);
|
||||
|
||||
while !scheds.is_empty() {
|
||||
let mut sched = scheds.pop();
|
||||
let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool, None) || {
|
||||
rtdebug!("bootstrapping non-primary scheduler");
|
||||
};
|
||||
let sched = sched;
|
||||
let thread = do Thread::start {
|
||||
sched.bootstrap(bootstrap_task);
|
||||
};
|
||||
|
||||
threads.push(thread);
|
||||
}
|
||||
|
||||
// Wait for schedulers
|
||||
for thread in threads.move_iter() {
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Test tasks will abort on failure instead of unwinding
|
||||
pub fn spawntask(f: proc()) {
|
||||
Scheduler::run_task(Task::build_child(None, f));
|
||||
}
|
||||
|
||||
/// Create a new task and run it right now. Aborts on failure
|
||||
pub fn spawntask_later(f: proc()) {
|
||||
Scheduler::run_task_later(Task::build_child(None, f));
|
||||
}
|
||||
|
||||
pub fn spawntask_random(f: proc()) {
|
||||
use rand::{Rand, rng};
|
||||
|
||||
let mut rng = rng();
|
||||
let run_now: bool = Rand::rand(&mut rng);
|
||||
|
||||
if run_now {
|
||||
spawntask(f)
|
||||
} else {
|
||||
spawntask_later(f)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawntask_try(f: proc()) -> Result<(),()> {
|
||||
|
||||
let (port, chan) = Chan::new();
|
||||
let on_exit: proc(TaskResult) = proc(exit_status) {
|
||||
chan.send(exit_status)
|
||||
};
|
||||
|
||||
let mut new_task = Task::build_root(None, f);
|
||||
new_task.death.on_exit = Some(on_exit);
|
||||
|
||||
Scheduler::run_task(new_task);
|
||||
|
||||
let exit_status = port.recv();
|
||||
if exit_status.is_ok() { Ok(()) } else { Err(()) }
|
||||
|
||||
}
|
||||
|
||||
/// Spawn a new task in a new scheduler and return a thread handle.
|
||||
pub fn spawntask_thread(f: proc()) -> Thread<()> {
|
||||
let thread = do Thread::start {
|
||||
run_in_newsched_task_core(f);
|
||||
};
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
/// Get a ~Task for testing purposes other than actually scheduling it.
|
||||
pub fn with_test_task(blk: proc(~Task) -> ~Task) {
|
||||
do run_in_bare_thread {
|
||||
let mut sched = ~new_test_sched();
|
||||
let task = blk(~Task::new_root(&mut sched.stack_pool,
|
||||
None,
|
||||
proc() {}));
|
||||
cleanup_task(task);
|
||||
}
|
||||
}
|
||||
|
||||
/// Use to cleanup tasks created for testing but not "run".
|
||||
pub fn cleanup_task(mut task: ~Task) {
|
||||
task.destroyed = true;
|
||||
}
|
||||
|
||||
/// Get a port number, starting at 9600, for use in tests
|
||||
pub fn next_test_port() -> u16 {
|
||||
use unstable::mutex::{Mutex, MUTEX_INIT};
|
||||
static mut lock: Mutex = MUTEX_INIT;
|
||||
static mut next_offset: u16 = 0;
|
||||
unsafe {
|
||||
let base = base_port();
|
||||
lock.lock();
|
||||
let ret = base + next_offset;
|
||||
next_offset += 1;
|
||||
lock.unlock();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a temporary path which could be the location of a unix socket
|
||||
pub fn next_test_unix() -> Path {
|
||||
if cfg!(unix) {
|
||||
os::tmpdir().join(rand::task_rng().gen_ascii_str(20))
|
||||
} else {
|
||||
Path::new(r"\\.\pipe\" + rand::task_rng().gen_ascii_str(20))
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a unique IPv4 localhost:port pair starting at 9600
|
||||
pub fn next_test_ip4() -> SocketAddr {
|
||||
SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: next_test_port() }
|
||||
}
|
||||
|
||||
/// Get a unique IPv6 localhost:port pair starting at 9600
|
||||
pub fn next_test_ip6() -> SocketAddr {
|
||||
SocketAddr { ip: Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1), port: next_test_port() }
|
||||
}
|
||||
|
||||
/*
|
||||
XXX: Welcome to MegaHack City.
|
||||
|
||||
The bots run multiple builds at the same time, and these builds
|
||||
all want to use ports. This function figures out which workspace
|
||||
it is running in and assigns a port range based on it.
|
||||
*/
|
||||
fn base_port() -> u16 {
|
||||
use os;
|
||||
use str::StrSlice;
|
||||
use vec::ImmutableVector;
|
||||
|
||||
let base = 9600u16;
|
||||
let range = 1000u16;
|
||||
|
||||
let bases = [
|
||||
("32-opt", base + range * 1),
|
||||
("32-noopt", base + range * 2),
|
||||
("64-opt", base + range * 3),
|
||||
("64-noopt", base + range * 4),
|
||||
("64-opt-vg", base + range * 5),
|
||||
("all-opt", base + range * 6),
|
||||
("snap3", base + range * 7),
|
||||
("dist", base + range * 8)
|
||||
];
|
||||
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
let path = os::getcwd();
|
||||
let path_s = path.as_str().unwrap();
|
||||
|
||||
let mut final_base = base;
|
||||
|
||||
for &(dir, base) in bases.iter() {
|
||||
if path_s.contains(dir) {
|
||||
final_base = base;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return final_base;
|
||||
}
|
||||
|
||||
/// Get a constant that represents the number of times to repeat
|
||||
/// stress tests. Default 1.
|
||||
pub fn stress_factor() -> uint {
|
||||
use os::getenv;
|
||||
use from_str::from_str;
|
||||
|
||||
match getenv("RUST_RT_STRESS") {
|
||||
Some(val) => from_str::<uint>(val).unwrap(),
|
||||
None => 1
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user