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:
Alex Crichton 2013-12-12 17:20:58 -08:00
parent 1815aea368
commit dafb310ba1
7 changed files with 573 additions and 1020 deletions

View File

@ -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());
}
}

View File

@ -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]

View File

@ -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());
}
}

View File

@ -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
View 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;
}

View File

@ -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)
}
}

View File

@ -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
}
}