From 8c78311e813c69550da04bd4626cb53f294972ed Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Wed, 31 Jul 2013 18:31:05 -0700 Subject: [PATCH 1/5] test: un-xfail now working run-pass/foreign-struct.rs, close #2334. --- src/test/run-pass/foreign-struct.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/run-pass/foreign-struct.rs b/src/test/run-pass/foreign-struct.rs index 57686b200f23d..a70fec9265942 100644 --- a/src/test/run-pass/foreign-struct.rs +++ b/src/test/run-pass/foreign-struct.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-win32 // Passing enums by value pub enum void { } From eaa378033c63595ee22cc6ccaf6e737f2193c78b Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 1 Aug 2013 12:00:24 -0700 Subject: [PATCH 2/5] test: add testcase, close #4929 which was already fixed. --- src/test/run-pass/issue-4929.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/test/run-pass/issue-4929.rs diff --git a/src/test/run-pass/issue-4929.rs b/src/test/run-pass/issue-4929.rs new file mode 100644 index 0000000000000..5803c3da6cc9c --- /dev/null +++ b/src/test/run-pass/issue-4929.rs @@ -0,0 +1,12 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn make_adder(x: int) -> @fn(int) -> int { |y| x + y } +pub fn main() { } From 29a449aae38d7b291a0038ba23d1e0a607244dae Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 1 Aug 2013 18:09:20 -0700 Subject: [PATCH 3/5] Add tests for cross-crate condition handling. Close #5446. --- src/test/auxiliary/xc_conditions.rs | 19 ++++++++++ src/test/auxiliary/xc_conditions_2.rs | 15 ++++++++ src/test/auxiliary/xc_conditions_3.rs | 21 +++++++++++ src/test/auxiliary/xc_conditions_4.rs | 29 +++++++++++++++ src/test/run-pass/xc_conditions_client.rs | 40 +++++++++++++++++++++ src/test/run-pass/xc_conditions_client_2.rs | 21 +++++++++++ src/test/run-pass/xc_conditions_client_3.rs | 38 ++++++++++++++++++++ src/test/run-pass/xc_conditions_client_4.rs | 32 +++++++++++++++++ 8 files changed, 215 insertions(+) create mode 100644 src/test/auxiliary/xc_conditions.rs create mode 100644 src/test/auxiliary/xc_conditions_2.rs create mode 100644 src/test/auxiliary/xc_conditions_3.rs create mode 100644 src/test/auxiliary/xc_conditions_4.rs create mode 100644 src/test/run-pass/xc_conditions_client.rs create mode 100644 src/test/run-pass/xc_conditions_client_2.rs create mode 100644 src/test/run-pass/xc_conditions_client_3.rs create mode 100644 src/test/run-pass/xc_conditions_client_4.rs diff --git a/src/test/auxiliary/xc_conditions.rs b/src/test/auxiliary/xc_conditions.rs new file mode 100644 index 0000000000000..927602de16989 --- /dev/null +++ b/src/test/auxiliary/xc_conditions.rs @@ -0,0 +1,19 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[crate_type="lib"]; + +condition! { + pub oops: int -> int; +} + +pub fn trouble() -> int { + oops::cond.raise(1) +} diff --git a/src/test/auxiliary/xc_conditions_2.rs b/src/test/auxiliary/xc_conditions_2.rs new file mode 100644 index 0000000000000..16a5bb5634341 --- /dev/null +++ b/src/test/auxiliary/xc_conditions_2.rs @@ -0,0 +1,15 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[crate_type="lib"]; + +condition! { + pub oops: int -> int; +} diff --git a/src/test/auxiliary/xc_conditions_3.rs b/src/test/auxiliary/xc_conditions_3.rs new file mode 100644 index 0000000000000..d5ce63e7e9bc0 --- /dev/null +++ b/src/test/auxiliary/xc_conditions_3.rs @@ -0,0 +1,21 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[crate_type="lib"]; + +condition! { + pub oops: int -> int; +} + +pub fn guard(k: extern fn() -> int, x: int) -> int { + do oops::cond.trap(|i| i*x).inside { + k() + } +} diff --git a/src/test/auxiliary/xc_conditions_4.rs b/src/test/auxiliary/xc_conditions_4.rs new file mode 100644 index 0000000000000..c9b5a1dc2b820 --- /dev/null +++ b/src/test/auxiliary/xc_conditions_4.rs @@ -0,0 +1,29 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[crate_type="lib"]; + +#[deriving(Eq)] +pub enum Color { + Red, Green, Blue +} + +condition! { + pub oops: (int,float,~str) -> ::Color; +} + +pub trait Thunk { + fn call(self) -> T; +} + +pub fn callback>(t:TH) -> T { + t.call() +} + diff --git a/src/test/run-pass/xc_conditions_client.rs b/src/test/run-pass/xc_conditions_client.rs new file mode 100644 index 0000000000000..ffef5369f237e --- /dev/null +++ b/src/test/run-pass/xc_conditions_client.rs @@ -0,0 +1,40 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-fast +// aux-build:xc_conditions.rs + +extern mod xc_conditions; +use xc_conditions::oops; +use xc_conditions::trouble; + +// Tests of cross-crate conditions; the condition is +// defined in lib, and we test various combinations +// of `trap` and `raise` in the client or the lib where +// the condition was defined. Also in test #4 we use +// more complex features (generics, traits) in +// combination with the condition. +// +// trap raise +// ------------ +// xc_conditions : client lib +// xc_conditions_2: client client +// xc_conditions_3: lib client +// xc_conditions_4: client client (with traits) +// +// the trap=lib, raise=lib case isn't tested since +// there's no cross-crate-ness to test in that case. + +pub fn main() { + do oops::cond.trap(|_i| 12345).inside { + let x = trouble(); + assert_eq!(x,12345); + } +} \ No newline at end of file diff --git a/src/test/run-pass/xc_conditions_client_2.rs b/src/test/run-pass/xc_conditions_client_2.rs new file mode 100644 index 0000000000000..9666c037449f1 --- /dev/null +++ b/src/test/run-pass/xc_conditions_client_2.rs @@ -0,0 +1,21 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-fast +// aux-build:xc_conditions_2.rs + +extern mod xc_conditions_2; +use xcc = xc_conditions_2; + +pub fn main() { + do xcc::oops::cond.trap(|_| 1).inside { + xcc::oops::cond.raise(1); + } +} diff --git a/src/test/run-pass/xc_conditions_client_3.rs b/src/test/run-pass/xc_conditions_client_3.rs new file mode 100644 index 0000000000000..7d16572c139ce --- /dev/null +++ b/src/test/run-pass/xc_conditions_client_3.rs @@ -0,0 +1,38 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-fast +// aux-build:xc_conditions_3.rs + +extern mod xc_conditions_3; +use xcc = xc_conditions_3; + +pub fn main() { + assert_eq!(xcc::guard(a, 1), 40); +} + +pub fn a() -> int { + assert_eq!(xcc::oops::cond.raise(7), 7); + xcc::guard(b, 2) +} + +pub fn b() -> int { + assert_eq!(xcc::oops::cond.raise(8), 16); + xcc::guard(c, 3) +} + +pub fn c() -> int { + assert_eq!(xcc::oops::cond.raise(9), 27); + xcc::guard(d, 4) +} + +pub fn d() -> int { + xcc::oops::cond.raise(10) +} diff --git a/src/test/run-pass/xc_conditions_client_4.rs b/src/test/run-pass/xc_conditions_client_4.rs new file mode 100644 index 0000000000000..9a4a868374235 --- /dev/null +++ b/src/test/run-pass/xc_conditions_client_4.rs @@ -0,0 +1,32 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-fast +// aux-build:xc_conditions_4.rs + +extern mod xc_conditions_4; +use xcc = xc_conditions_4; + +struct SThunk { + x: int +} + +impl xcc::Thunk for SThunk { + fn call(self) -> xcc::Color { + xcc::oops::cond.raise((self.x, 1.23, ~"oh no")) + } +} + +pub fn main() { + do xcc::oops::cond.trap(|_| xcc::Red).inside { + let t = SThunk { x : 10 }; + assert_eq!(xcc::callback(t), xcc::Red) + } +} \ No newline at end of file From 19f4ae1415e2baa4b9d756b7af8a0d5779cfca9b Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Fri, 9 Aug 2013 16:30:44 -0700 Subject: [PATCH 4/5] Try to fix mac valgrind bot by disabling thread-heavy activities. --- src/libstd/rt/comm.rs | 10 ++++++++++ src/libstd/rt/sched.rs | 2 ++ src/libstd/rt/test.rs | 14 +++++++++----- src/libstd/rt/util.rs | 28 +++++++++++++++++++++++++++- src/libstd/run.rs | 10 +--------- src/libstd/unstable/mod.rs | 15 +++++++++++++++ 6 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs index 42d59ccdf958e..49cf8c239b7e6 100644 --- a/src/libstd/rt/comm.rs +++ b/src/libstd/rt/comm.rs @@ -727,6 +727,7 @@ mod test { use rt::test::*; use cell::Cell; use iter::Times; + use rt::util; #[test] fn oneshot_single_thread_close_port_first() { @@ -875,6 +876,7 @@ mod test { #[test] fn oneshot_multi_thread_close_stress() { + if util::limit_thread_creation_due_to_osx_and_valgrind() { return; } do stress_factor().times { do run_in_newsched_task { let (port, chan) = oneshot::(); @@ -890,6 +892,7 @@ mod test { #[test] fn oneshot_multi_thread_send_close_stress() { + if util::limit_thread_creation_due_to_osx_and_valgrind() { return; } do stress_factor().times { do run_in_newsched_task { let (port, chan) = oneshot::(); @@ -910,6 +913,7 @@ mod test { #[test] fn oneshot_multi_thread_recv_close_stress() { + if util::limit_thread_creation_due_to_osx_and_valgrind() { return; } do stress_factor().times { do run_in_newsched_task { let (port, chan) = oneshot::(); @@ -936,6 +940,7 @@ mod test { #[test] fn oneshot_multi_thread_send_recv_stress() { + if util::limit_thread_creation_due_to_osx_and_valgrind() { return; } do stress_factor().times { do run_in_newsched_task { let (port, chan) = oneshot::<~int>(); @@ -955,6 +960,7 @@ mod test { #[test] fn stream_send_recv_stress() { + if util::limit_thread_creation_due_to_osx_and_valgrind() { return; } do stress_factor().times { do run_in_mt_newsched_task { let (port, chan) = stream::<~int>(); @@ -999,6 +1005,7 @@ mod test { #[test] fn shared_chan_stress() { + if util::limit_thread_creation_due_to_osx_and_valgrind() { return; } do run_in_mt_newsched_task { let (port, chan) = stream(); let chan = SharedChan::new(chan); @@ -1018,6 +1025,7 @@ mod test { #[test] fn shared_port_stress() { + if util::limit_thread_creation_due_to_osx_and_valgrind() { return; } do run_in_mt_newsched_task { // XXX: Removing these type annotations causes an ICE let (end_port, end_chan) = stream::<()>(); @@ -1098,6 +1106,8 @@ mod test { use rand; use rand::RngUtil; + if util::limit_thread_creation_due_to_osx_and_valgrind() { return; } + do run_in_mt_newsched_task { let (end_port, end_chan) = stream::<()>(); let end_chan = SharedChan::new(end_chan); diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index ce4e64c47d2ef..e65a45f0e0749 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -819,6 +819,7 @@ mod test { use cell::Cell; use rt::thread::Thread; use rt::task::{Task, Sched}; + use rt::util; use option::{Some}; #[test] @@ -1040,6 +1041,7 @@ mod test { #[test] fn test_stress_schedule_task_states() { + if util::limit_thread_creation_due_to_osx_and_valgrind() { return; } let n = stress_factor() * 120; for _ in range(0, n as int) { test_schedule_home_states(); diff --git a/src/libstd/rt/test.rs b/src/libstd/rt/test.rs index a933115774933..4e2f9fbe13075 100644 --- a/src/libstd/rt/test.rs +++ b/src/libstd/rt/test.rs @@ -18,7 +18,7 @@ use iterator::{Iterator, range}; use super::io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr}; use vec::{OwnedVector, MutableVector, ImmutableVector}; use rt::sched::Scheduler; -use unstable::run_in_bare_thread; +use unstable::{run_in_bare_thread}; use rt::thread::Thread; use rt::task::Task; use rt::uv::uvio::UvEventLoop; @@ -162,10 +162,14 @@ pub fn run_in_mt_newsched_task(f: ~fn()) { let nthreads = match os::getenv("RUST_RT_TEST_THREADS") { Some(nstr) => FromStr::from_str(nstr).unwrap(), None => { - // 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 + 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 + } } }; diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs index b8c7c8761e85d..c81f3ec9a7993 100644 --- a/src/libstd/rt/util.rs +++ b/src/libstd/rt/util.rs @@ -15,6 +15,9 @@ use option::{Some, None}; use os; use str::StrSlice; +#[cfg(target_os="macos")] +use unstable::running_on_valgrind; + /// Get the number of cores available pub fn num_cpus() -> uint { #[fixed_stack_segment]; #[inline(never)]; @@ -28,12 +31,35 @@ pub fn num_cpus() -> uint { } } +/// Valgrind has a fixed-sized array (size around 2000) of segment descriptors wired into it; this +/// is a hard limit and requires rebuilding valgrind if you want to go beyond it. Normally this is +/// not a problem, but in some tests, we produce a lot of threads casually. Making lots of threads +/// alone might not be a problem _either_, except on OSX, the segments produced for new threads +/// _take a while_ to get reclaimed by the OS. Combined with the fact that libuv schedulers fork off +/// a separate thread for polling fsevents on OSX, we get a perfect storm of creating "too many +/// mappings" for valgrind to handle when running certain stress tests in the runtime. +#[cfg(target_os="macos")] +pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool { + running_on_valgrind() +} + +#[cfg(not(target_os="macos"))] +pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool { + false +} + /// Get's the number of scheduler threads requested by the environment /// either `RUST_THREADS` or `num_cpus`. pub fn default_sched_threads() -> uint { match os::getenv("RUST_THREADS") { Some(nstr) => FromStr::from_str(nstr).unwrap(), - None => num_cpus() + None => { + if limit_thread_creation_due_to_osx_and_valgrind() { + 1 + } else { + num_cpus() + } + } } } diff --git a/src/libstd/run.rs b/src/libstd/run.rs index a43d448dae51f..eeaee4c14a512 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -955,6 +955,7 @@ mod tests { use path::Path; use run; use str; + use unstable::running_on_valgrind; #[test] #[cfg(windows)] @@ -1365,13 +1366,4 @@ mod tests { assert!(output.contains("RUN_TEST_NEW_ENV=123")); } - - fn running_on_valgrind() -> bool { - #[fixed_stack_segment]; #[inline(never)]; - unsafe { rust_running_on_valgrind() != 0 } - } - - extern { - fn rust_running_on_valgrind() -> uintptr_t; - } } diff --git a/src/libstd/unstable/mod.rs b/src/libstd/unstable/mod.rs index 6ad15bfc7c039..51de3caf2aebb 100644 --- a/src/libstd/unstable/mod.rs +++ b/src/libstd/unstable/mod.rs @@ -14,6 +14,7 @@ use comm::{GenericChan, GenericPort}; use comm; use prelude::*; use task; +use libc::uintptr_t; pub mod dynamic_lib; @@ -118,3 +119,17 @@ pub fn change_dir_locked(p: &Path, action: &fn()) -> bool { fn rust_drop_change_dir_lock(); } } + + +/// Dynamically inquire about whether we're running under V. +/// You should usually not use this unless your test definitely +/// can't run correctly un-altered. Valgrind is there to help +/// you notice weirdness in normal, un-doctored code paths! +pub fn running_on_valgrind() -> bool { + #[fixed_stack_segment]; #[inline(never)]; + unsafe { rust_running_on_valgrind() != 0 } +} + +extern { + fn rust_running_on_valgrind() -> uintptr_t; +} From 610b2b58ecfcce10dd448c11941de956206d1bd1 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Mon, 19 Aug 2013 15:08:47 -0700 Subject: [PATCH 5/5] compiletest: do not run tests in sub-threads if on valgrind. --- src/compiletest/runtest.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 2346aba3bcbb6..a31efe26c1a5f 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -26,6 +26,7 @@ use std::os; use std::str; use std::task::{spawn_sched, SingleThreaded}; use std::vec; +use std::unstable::running_on_valgrind; use extra::test::MetricMap; @@ -38,11 +39,21 @@ pub fn run(config: config, testfile: ~str) { // that destroys parallelism if we let normal schedulers block. // It should be possible to remove this spawn once std::run is // rewritten to be non-blocking. - do spawn_sched(SingleThreaded) { + // + // We do _not_ create another thread if we're running on V because + // it serializes all threads anyways. + if running_on_valgrind() { let config = config.take(); let testfile = testfile.take(); let mut _mm = MetricMap::new(); run_metrics(config, testfile, &mut _mm); + } else { + do spawn_sched(SingleThreaded) { + let config = config.take(); + let testfile = testfile.take(); + let mut _mm = MetricMap::new(); + run_metrics(config, testfile, &mut _mm); + } } }