diff options
Diffstat (limited to 'src/libstd/old_io/test.rs')
| -rw-r--r-- | src/libstd/old_io/test.rs | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/src/libstd/old_io/test.rs b/src/libstd/old_io/test.rs new file mode 100644 index 00000000000..f49e2397d42 --- /dev/null +++ b/src/libstd/old_io/test.rs @@ -0,0 +1,175 @@ +// 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. + +//! Various utility functions useful for writing I/O tests + +use prelude::v1::*; + +use libc; +use os; +use std::old_io::net::ip::*; +use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; + +/// Get a port number, starting at 9600, for use in tests +pub fn next_test_port() -> u16 { + static NEXT_OFFSET: AtomicUsize = ATOMIC_USIZE_INIT; + base_port() + NEXT_OFFSET.fetch_add(1, Ordering::Relaxed) as u16 +} + +// iOS has a pretty long tmpdir path which causes pipe creation +// to like: invalid argument: path must be smaller than SUN_LEN +fn next_test_unix_socket() -> String { + static COUNT: AtomicUsize = ATOMIC_USIZE_INIT; + // base port and pid are an attempt to be unique between multiple + // test-runners of different configurations running on one + // buildbot, the count is to be unique within this executable. + format!("rust-test-unix-path-{}-{}-{}", + base_port(), + unsafe {libc::getpid()}, + COUNT.fetch_add(1, Ordering::Relaxed)) +} + +/// Get a temporary path which could be the location of a unix socket +#[cfg(not(target_os = "ios"))] +pub fn next_test_unix() -> Path { + let string = next_test_unix_socket(); + if cfg!(unix) { + os::tmpdir().join(string) + } else { + Path::new(format!("{}{}", r"\\.\pipe\", string)) + } +} + +/// Get a temporary path which could be the location of a unix socket +#[cfg(target_os = "ios")] +pub fn next_test_unix() -> Path { + Path::new(format!("/var/tmp/{}", next_test_unix_socket())) +} + +/// 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 { + + let base = 9600u16; + let range = 1000u16; + + let bases = [ + ("32-opt", base + range * 1), + ("32-nopt", base + range * 2), + ("64-opt", base + range * 3), + ("64-nopt", 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().unwrap(); + 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; +} + +/// Raises the file descriptor limit when running tests if necessary +pub fn raise_fd_limit() { + unsafe { darwin_fd_limit::raise_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. +#[cfg(any(target_os = "macos", target_os = "ios"))] +#[allow(non_camel_case_types)] +mod darwin_fd_limit { + use libc; + type rlim_t = libc::uint64_t; + #[repr(C)] + struct rlimit { + rlim_cur: rlim_t, + rlim_max: rlim_t + } + 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: *const 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::null_mut; + 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(&mut mib[0], 2, &mut maxfiles as *mut libc::c_int as *mut libc::c_void, &mut size, + null_mut(), 0) != 0 { + let err = last_os_error(); + panic!("raise_fd_limit: error calling sysctl: {}", err); + } + + // Fetch the current resource limits + let mut rlim = rlimit{rlim_cur: 0, rlim_max: 0}; + if getrlimit(RLIMIT_NOFILE, &mut rlim) != 0 { + let err = last_os_error(); + panic!("raise_fd_limit: error calling getrlimit: {}", err); + } + + // 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, &rlim) != 0 { + let err = last_os_error(); + panic!("raise_fd_limit: error calling setrlimit: {}", err); + } + } +} + +#[cfg(not(any(target_os = "macos", target_os = "ios")))] +mod darwin_fd_limit { + pub unsafe fn raise_fd_limit() {} +} |
