]> git.lizzy.rs Git - rust.git/blob - src/libstd/io/test.rs
Test fixes and rebase problems
[rust.git] / src / libstd / io / test.rs
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #[macro_escape];
12
13 use os;
14 use prelude::*;
15 use rand;
16 use rand::Rng;
17 use std::io::net::ip::*;
18 use sync::atomics::{AtomicUint, INIT_ATOMIC_UINT, Relaxed};
19
20 macro_rules! iotest (
21     { fn $name:ident() $b:block } => (
22         mod $name {
23             #[allow(unused_imports)];
24
25             use super::super::*;
26             use super::*;
27             use io;
28             use prelude::*;
29             use io::*;
30             use io::fs::*;
31             use io::net::tcp::*;
32             use io::net::ip::*;
33             use io::net::udp::*;
34             use io::net::unix::*;
35             use str;
36             use util;
37
38             fn f() $b
39
40             #[test] fn green() { f() }
41             #[test] fn native() {
42                 use native;
43                 let (p, c) = Chan::new();
44                 do native::task::spawn { c.send(f()) }
45                 p.recv();
46             }
47         }
48     )
49 )
50
51 /// Get a port number, starting at 9600, for use in tests
52 pub fn next_test_port() -> u16 {
53     static mut next_offset: AtomicUint = INIT_ATOMIC_UINT;
54     unsafe {
55         base_port() + next_offset.fetch_add(1, Relaxed) as u16
56     }
57 }
58
59 /// Get a temporary path which could be the location of a unix socket
60 pub fn next_test_unix() -> Path {
61     if cfg!(unix) {
62         os::tmpdir().join(rand::task_rng().gen_ascii_str(20))
63     } else {
64         Path::new(r"\\.\pipe\" + rand::task_rng().gen_ascii_str(20))
65     }
66 }
67
68 /// Get a unique IPv4 localhost:port pair starting at 9600
69 pub fn next_test_ip4() -> SocketAddr {
70     SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: next_test_port() }
71 }
72
73 /// Get a unique IPv6 localhost:port pair starting at 9600
74 pub fn next_test_ip6() -> SocketAddr {
75     SocketAddr { ip: Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1), port: next_test_port() }
76 }
77
78 /*
79 XXX: Welcome to MegaHack City.
80
81 The bots run multiple builds at the same time, and these builds
82 all want to use ports. This function figures out which workspace
83 it is running in and assigns a port range based on it.
84 */
85 fn base_port() -> u16 {
86
87     let base = 9600u16;
88     let range = 1000u16;
89
90     let bases = [
91         ("32-opt", base + range * 1),
92         ("32-noopt", base + range * 2),
93         ("64-opt", base + range * 3),
94         ("64-noopt", base + range * 4),
95         ("64-opt-vg", base + range * 5),
96         ("all-opt", base + range * 6),
97         ("snap3", base + range * 7),
98         ("dist", base + range * 8)
99     ];
100
101     // FIXME (#9639): This needs to handle non-utf8 paths
102     let path = os::getcwd();
103     let path_s = path.as_str().unwrap();
104
105     let mut final_base = base;
106
107     for &(dir, base) in bases.iter() {
108         if path_s.contains(dir) {
109             final_base = base;
110             break;
111         }
112     }
113
114     return final_base;
115 }
116
117 pub fn raise_fd_limit() {
118     unsafe { darwin_fd_limit::raise_fd_limit() }
119 }
120
121 #[cfg(target_os="macos")]
122 #[allow(non_camel_case_types)]
123 mod darwin_fd_limit {
124     /*!
125      * darwin_fd_limit exists to work around an issue where launchctl on Mac OS X defaults the
126      * rlimit maxfiles to 256/unlimited. The default soft limit of 256 ends up being far too low
127      * for our multithreaded scheduler testing, depending on the number of cores available.
128      *
129      * This fixes issue #7772.
130      */
131
132     use libc;
133     type rlim_t = libc::uint64_t;
134     struct rlimit {
135         rlim_cur: rlim_t,
136         rlim_max: rlim_t
137     }
138     #[nolink]
139     extern {
140         // name probably doesn't need to be mut, but the C function doesn't specify const
141         fn sysctl(name: *mut libc::c_int, namelen: libc::c_uint,
142                   oldp: *mut libc::c_void, oldlenp: *mut libc::size_t,
143                   newp: *mut libc::c_void, newlen: libc::size_t) -> libc::c_int;
144         fn getrlimit(resource: libc::c_int, rlp: *mut rlimit) -> libc::c_int;
145         fn setrlimit(resource: libc::c_int, rlp: *rlimit) -> libc::c_int;
146     }
147     static CTL_KERN: libc::c_int = 1;
148     static KERN_MAXFILESPERPROC: libc::c_int = 29;
149     static RLIMIT_NOFILE: libc::c_int = 8;
150
151     pub unsafe fn raise_fd_limit() {
152         // The strategy here is to fetch the current resource limits, read the kern.maxfilesperproc
153         // sysctl value, and bump the soft resource limit for maxfiles up to the sysctl value.
154         use ptr::{to_unsafe_ptr, to_mut_unsafe_ptr, mut_null};
155         use mem::size_of_val;
156         use os::last_os_error;
157
158         // Fetch the kern.maxfilesperproc value
159         let mut mib: [libc::c_int, ..2] = [CTL_KERN, KERN_MAXFILESPERPROC];
160         let mut maxfiles: libc::c_int = 0;
161         let mut size: libc::size_t = size_of_val(&maxfiles) as libc::size_t;
162         if sysctl(to_mut_unsafe_ptr(&mut mib[0]), 2,
163                   to_mut_unsafe_ptr(&mut maxfiles) as *mut libc::c_void,
164                   to_mut_unsafe_ptr(&mut size),
165                   mut_null(), 0) != 0 {
166             let err = last_os_error();
167             error!("raise_fd_limit: error calling sysctl: {}", err);
168             return;
169         }
170
171         // Fetch the current resource limits
172         let mut rlim = rlimit{rlim_cur: 0, rlim_max: 0};
173         if getrlimit(RLIMIT_NOFILE, to_mut_unsafe_ptr(&mut rlim)) != 0 {
174             let err = last_os_error();
175             error!("raise_fd_limit: error calling getrlimit: {}", err);
176             return;
177         }
178
179         // Bump the soft limit to the smaller of kern.maxfilesperproc and the hard limit
180         rlim.rlim_cur = ::cmp::min(maxfiles as rlim_t, rlim.rlim_max);
181
182         // Set our newly-increased resource limit
183         if setrlimit(RLIMIT_NOFILE, to_unsafe_ptr(&rlim)) != 0 {
184             let err = last_os_error();
185             error!("raise_fd_limit: error calling setrlimit: {}", err);
186             return;
187         }
188     }
189 }
190
191 #[cfg(not(target_os="macos"))]
192 mod darwin_fd_limit {
193     pub unsafe fn raise_fd_limit() {}
194 }