1
Fork 0

Rollup merge of #135621 - bjorn3:move_tests_to_stdtests, r=Noratrieb

Move some std tests to integration tests

Unit tests directly inside of standard library crates require a very fragile way of building that is hard to reproduce outside of bootstrap.

Follow up to https://github.com/rust-lang/rust/pull/133859
This commit is contained in:
Jacob Pratt 2025-02-04 05:36:50 -05:00 committed by GitHub
commit d2aa3dec8a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
53 changed files with 645 additions and 650 deletions

View file

@ -7,6 +7,7 @@ license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/rust.git"
description = "The Rust Standard Library"
edition = "2021"
autobenches = false
[lib]
crate-type = ["dylib", "rlib"]
@ -130,6 +131,18 @@ name = "pipe-subprocess"
path = "tests/pipe_subprocess.rs"
harness = false
[[test]]
name = "sync"
path = "tests/sync/lib.rs"
[[test]]
name = "floats"
path = "tests/floats/lib.rs"
[[test]]
name = "thread_local"
path = "tests/thread_local/lib.rs"
[[bench]]
name = "stdbenches"
path = "benches/lib.rs"

View file

@ -5,3 +5,5 @@
extern crate test;
mod hash;
mod path;
mod time;

114
library/std/benches/path.rs Normal file
View file

@ -0,0 +1,114 @@
use core::hint::black_box;
use std::collections::{BTreeSet, HashSet};
use std::hash::{DefaultHasher, Hash, Hasher};
use std::path::*;
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) {
let prefix = "my/home";
let mut paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
paths.sort();
b.iter(|| {
black_box(paths.as_mut_slice()).sort_unstable();
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_long(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = BTreeSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
b.iter(|| {
set.remove(paths[500].as_path());
set.insert(paths[500].as_path());
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) {
let prefix = "my/home";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = BTreeSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
b.iter(|| {
set.remove(paths[500].as_path());
set.insert(paths[500].as_path());
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_hashset(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = HashSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
b.iter(|| {
set.remove(paths[500].as_path());
set.insert(black_box(paths[500].as_path()))
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_hashset_miss(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = HashSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
let probe = PathBuf::from(prefix).join("other");
b.iter(|| set.remove(black_box(probe.as_path())));
}
#[bench]
fn bench_hash_path_short(b: &mut test::Bencher) {
let mut hasher = DefaultHasher::new();
let path = Path::new("explorer.exe");
b.iter(|| black_box(path).hash(&mut hasher));
black_box(hasher.finish());
}
#[bench]
fn bench_hash_path_long(b: &mut test::Bencher) {
let mut hasher = DefaultHasher::new();
let path =
Path::new("/aaaaa/aaaaaa/./../aaaaaaaa/bbbbbbbbbbbbb/ccccccccccc/ddddddddd/eeeeeee.fff");
b.iter(|| black_box(path).hash(&mut hasher));
black_box(hasher.finish());
}

View file

@ -0,0 +1,47 @@
use std::time::Instant;
#[cfg(not(target_arch = "wasm32"))]
use test::{Bencher, black_box};
macro_rules! bench_instant_threaded {
($bench_name:ident, $thread_count:expr) => {
#[bench]
#[cfg(not(target_arch = "wasm32"))]
fn $bench_name(b: &mut Bencher) -> std::thread::Result<()> {
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
let running = Arc::new(AtomicBool::new(true));
let threads: Vec<_> = (0..$thread_count)
.map(|_| {
let flag = Arc::clone(&running);
std::thread::spawn(move || {
while flag.load(Ordering::Relaxed) {
black_box(Instant::now());
}
})
})
.collect();
b.iter(|| {
let a = Instant::now();
let b = Instant::now();
assert!(b >= a);
});
running.store(false, Ordering::Relaxed);
for t in threads {
t.join()?;
}
Ok(())
}
};
}
bench_instant_threaded!(instant_contention_01_threads, 0);
bench_instant_threaded!(instant_contention_02_threads, 1);
bench_instant_threaded!(instant_contention_04_threads, 3);
bench_instant_threaded!(instant_contention_08_threads, 7);
bench_instant_threaded!(instant_contention_16_threads, 15);

View file

@ -10,9 +10,6 @@
#![stable(feature = "env", since = "1.0.0")]
#[cfg(test)]
mod tests;
use crate::error::Error;
use crate::ffi::{OsStr, OsString};
use crate::path::{Path, PathBuf};

View file

@ -1,120 +0,0 @@
use super::*;
#[test]
#[cfg_attr(any(target_os = "emscripten", target_os = "wasi", target_env = "sgx"), ignore)]
fn test_self_exe_path() {
let path = current_exe();
assert!(path.is_ok());
let path = path.unwrap();
// Hard to test this function
assert!(path.is_absolute());
}
#[test]
fn test() {
assert!((!Path::new("test-path").is_absolute()));
#[cfg(not(target_env = "sgx"))]
current_dir().unwrap();
}
#[test]
#[cfg(windows)]
fn split_paths_windows() {
use crate::path::PathBuf;
fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
split_paths(unparsed).collect::<Vec<_>>()
== parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
}
assert!(check_parse("", &mut [""]));
assert!(check_parse(r#""""#, &mut [""]));
assert!(check_parse(";;", &mut ["", "", ""]));
assert!(check_parse(r"c:\", &mut [r"c:\"]));
assert!(check_parse(r"c:\;", &mut [r"c:\", ""]));
assert!(check_parse(r"c:\;c:\Program Files\", &mut [r"c:\", r"c:\Program Files\"]));
assert!(check_parse(r#"c:\;c:\"foo"\"#, &mut [r"c:\", r"c:\foo\"]));
assert!(check_parse(r#"c:\;c:\"foo;bar"\;c:\baz"#, &mut [r"c:\", r"c:\foo;bar\", r"c:\baz"]));
}
#[test]
#[cfg(unix)]
fn split_paths_unix() {
use crate::path::PathBuf;
fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
split_paths(unparsed).collect::<Vec<_>>()
== parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
}
assert!(check_parse("", &mut [""]));
assert!(check_parse("::", &mut ["", "", ""]));
assert!(check_parse("/", &mut ["/"]));
assert!(check_parse("/:", &mut ["/", ""]));
assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"]));
}
#[test]
#[cfg(unix)]
fn join_paths_unix() {
use crate::ffi::OsStr;
fn test_eq(input: &[&str], output: &str) -> bool {
&*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
}
assert!(test_eq(&[], ""));
assert!(test_eq(&["/bin", "/usr/bin", "/usr/local/bin"], "/bin:/usr/bin:/usr/local/bin"));
assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""], ":/bin:::/usr/bin:"));
assert!(join_paths(["/te:st"].iter().cloned()).is_err());
}
#[test]
#[cfg(windows)]
fn join_paths_windows() {
use crate::ffi::OsStr;
fn test_eq(input: &[&str], output: &str) -> bool {
&*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
}
assert!(test_eq(&[], ""));
assert!(test_eq(&[r"c:\windows", r"c:\"], r"c:\windows;c:\"));
assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""], r";c:\windows;;;c:\;"));
assert!(test_eq(&[r"c:\te;st", r"c:\"], r#""c:\te;st";c:\"#));
assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err());
}
#[test]
fn args_debug() {
assert_eq!(
format!("Args {{ inner: {:?} }}", args().collect::<Vec<_>>()),
format!("{:?}", args())
);
}
#[test]
fn args_os_debug() {
assert_eq!(
format!("ArgsOs {{ inner: {:?} }}", args_os().collect::<Vec<_>>()),
format!("{:?}", args_os())
);
}
#[test]
fn vars_debug() {
assert_eq!(
format!("Vars {{ inner: {:?} }}", vars().collect::<Vec<_>>()),
format!("{:?}", vars())
);
}
#[test]
fn vars_os_debug() {
assert_eq!(
format!("VarsOs {{ inner: {:?} }}", vars_os().collect::<Vec<_>>()),
format!("{:?}", vars_os())
);
}

View file

@ -1,9 +1,6 @@
#![doc = include_str!("../../core/src/error.md")]
#![stable(feature = "rust1", since = "1.0.0")]
#[cfg(test)]
mod tests;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::error::Error;
#[unstable(feature = "error_generic_member_access", issue = "99301")]

View file

@ -4,9 +4,6 @@
//!
//! Mathematically significant numbers are provided in the `consts` sub-module.
#[cfg(test)]
mod tests;
#[unstable(feature = "f128", issue = "116909")]
pub use core::f128::consts;

View file

@ -4,9 +4,6 @@
//!
//! Mathematically significant numbers are provided in the `consts` sub-module.
#[cfg(test)]
mod tests;
#[unstable(feature = "f16", issue = "116909")]
pub use core::f16::consts;

View file

@ -12,9 +12,6 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![allow(missing_docs)]
#[cfg(test)]
mod tests;
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated, deprecated_in_future)]
pub use core::f32::{

View file

@ -12,9 +12,6 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![allow(missing_docs)]
#[cfg(test)]
mod tests;
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated, deprecated_in_future)]
pub use core::f64::{

View file

@ -372,18 +372,3 @@ macro_rules! dbg {
($($crate::dbg!($val)),+,)
};
}
/// Verify that floats are within a tolerance of each other, 1.0e-6 by default.
#[cfg(test)]
macro_rules! assert_approx_eq {
($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, 1.0e-6) }};
($a:expr, $b:expr, $lim:expr) => {{
let (a, b) = (&$a, &$b);
let diff = (*a - *b).abs();
assert!(
diff < $lim,
"{a:?} is not approximately equal to {b:?} (threshold {lim:?}, difference {diff:?})",
lim = $lim
);
}};
}

View file

@ -6,9 +6,6 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![allow(missing_docs)]
#[cfg(test)]
mod tests;
#[stable(feature = "int_error_matching", since = "1.55.0")]
pub use core::num::IntErrorKind;
#[stable(feature = "generic_nonzero", since = "1.79.0")]
@ -29,28 +26,3 @@ pub use core::num::{FpCategory, ParseFloatError, ParseIntError, TryFromIntError}
pub use core::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize};
#[stable(feature = "nonzero", since = "1.28.0")]
pub use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize};
#[cfg(test)]
use crate::fmt;
#[cfg(test)]
use crate::ops::{Add, Div, Mul, Rem, Sub};
/// Helper function for testing numeric operations
#[cfg(test)]
pub fn test_num<T>(ten: T, two: T)
where
T: PartialEq
+ Add<Output = T>
+ Sub<Output = T>
+ Mul<Output = T>
+ Div<Output = T>
+ Rem<Output = T>
+ fmt::Debug
+ Copy,
{
assert_eq!(ten.add(two), ten + two);
assert_eq!(ten.sub(two), ten - two);
assert_eq!(ten.mul(two), ten * two);
assert_eq!(ten.div(two), ten / two);
assert_eq!(ten.rem(two), ten % two);
}

View file

@ -529,6 +529,3 @@ pub fn get_backtrace_style() -> Option<BacktraceStyle> {
Err(new) => BacktraceStyle::from_u8(new),
}
}
#[cfg(test)]
mod tests;

View file

@ -67,9 +67,6 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![deny(unsafe_op_in_unsafe_fn)]
#[cfg(test)]
mod tests;
use core::clone::CloneToUninit;
use crate::borrow::{Borrow, Cow};

View file

@ -1,6 +1,3 @@
#[cfg(test)]
mod tests;
use crate::fmt;
// FIXME(nonpoison_mutex,nonpoison_condvar): switch to nonpoison versions once they are available
use crate::sync::{Condvar, Mutex};

View file

@ -350,6 +350,3 @@ unsafe impl<T: Sync + Send, F: Send> Sync for LazyLock<T, F> {}
impl<T: RefUnwindSafe + UnwindSafe, F: UnwindSafe> RefUnwindSafe for LazyLock<T, F> {}
#[stable(feature = "lazy_cell", since = "1.80.0")]
impl<T: UnwindSafe, F: UnwindSafe> UnwindSafe for LazyLock<T, F> {}
#[cfg(test)]
mod tests;

View file

@ -137,12 +137,6 @@
#![stable(feature = "rust1", since = "1.0.0")]
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
mod tests;
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
mod sync_tests;
// MPSC channels are built as a wrapper around MPMC channels, which
// were ported from the `crossbeam-channel` crate. MPMC channels are
// not exposed publicly, but if you are curious about the implementation,
@ -737,9 +731,10 @@ impl<T> SyncSender<T> {
// Attempts to send for a value on this receiver, returning an error if the
// corresponding channel has hung up, or if it waits more than `timeout`.
//
// This method is currently private and only used for tests.
#[allow(unused)]
fn send_timeout(&self, t: T, timeout: Duration) -> Result<(), mpmc::SendTimeoutError<T>> {
// This method is currently only used for tests.
#[unstable(issue = "none", feature = "std_internals")]
#[doc(hidden)]
pub fn send_timeout(&self, t: T, timeout: Duration) -> Result<(), mpmc::SendTimeoutError<T>> {
self.inner.send_timeout(t, timeout)
}
}

View file

@ -681,6 +681,3 @@ unsafe impl<#[may_dangle] T> Drop for OnceLock<T> {
}
}
}
#[cfg(test)]
mod tests;

View file

@ -1,6 +1,3 @@
#[cfg(test)]
mod tests;
use crate::fmt;
use crate::sync::poison::{self, LockResult, MutexGuard, PoisonError, mutex};
use crate::sys::sync as sys;

View file

@ -1,6 +1,3 @@
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
mod tests;
use crate::cell::UnsafeCell;
use crate::fmt;
use crate::marker::PhantomData;

View file

@ -3,9 +3,6 @@
//! This primitive is meant to be used to run one-time initialization. An
//! example use case would be for initializing an FFI library.
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
mod tests;
use crate::fmt;
use crate::panic::{RefUnwindSafe, UnwindSafe};
use crate::sys::sync as sys;

View file

@ -1,6 +1,3 @@
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
mod tests;
use crate::cell::UnsafeCell;
use crate::fmt;
use crate::marker::PhantomData;

View file

@ -1,6 +1,3 @@
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
mod tests;
use cfg_if::cfg_if;
use crate::cell::UnsafeCell;
@ -324,7 +321,10 @@ impl<T: ?Sized> ReentrantLock<T> {
/// Otherwise, an RAII guard is returned.
///
/// This function does not block.
pub(crate) fn try_lock(&self) -> Option<ReentrantLockGuard<'_, T>> {
// FIXME maybe make it a public part of the API?
#[unstable(issue = "none", feature = "std_internals")]
#[doc(hidden)]
pub fn try_lock(&self) -> Option<ReentrantLockGuard<'_, T>> {
let this_thread = current_id();
// Safety: We only touch lock_count when we own the inner mutex.
// Additionally, we only call `self.owner.set()` while holding

View file

@ -2,12 +2,6 @@
#![unstable(feature = "thread_local_internals", issue = "none")]
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
mod tests;
#[cfg(test)]
mod dynamic_tests;
use crate::cell::{Cell, RefCell};
use crate::error::Error;
use crate::fmt;

View file

@ -31,9 +31,6 @@
#![stable(feature = "time", since = "1.3.0")]
#[cfg(test)]
mod tests;
#[stable(feature = "time", since = "1.3.0")]
pub use core::time::Duration;
#[stable(feature = "duration_checked_float", since = "1.66.0")]

View file

@ -1,163 +1,123 @@
use std::env::*;
use std::ffi::{OsStr, OsString};
use rand::distributions::{Alphanumeric, DistString};
use std::path::Path;
mod common;
use std::thread;
use common::test_rng;
#[test]
#[cfg_attr(any(target_os = "emscripten", target_os = "wasi", target_env = "sgx"), ignore)]
fn test_self_exe_path() {
let path = current_exe();
assert!(path.is_ok());
let path = path.unwrap();
#[track_caller]
fn make_rand_name() -> OsString {
let n = format!("TEST{}", Alphanumeric.sample_string(&mut test_rng(), 10));
let n = OsString::from(n);
assert!(var_os(&n).is_none());
n
}
fn eq(a: Option<OsString>, b: Option<&str>) {
assert_eq!(a.as_ref().map(|s| &**s), b.map(OsStr::new).map(|s| &*s));
// Hard to test this function
assert!(path.is_absolute());
}
#[test]
fn test_set_var() {
let n = make_rand_name();
set_var(&n, "VALUE");
eq(var_os(&n), Some("VALUE"));
fn test() {
assert!((!Path::new("test-path").is_absolute()));
#[cfg(not(target_env = "sgx"))]
current_dir().unwrap();
}
#[test]
fn test_remove_var() {
let n = make_rand_name();
set_var(&n, "VALUE");
remove_var(&n);
eq(var_os(&n), None);
}
#[test]
fn test_set_var_overwrite() {
let n = make_rand_name();
set_var(&n, "1");
set_var(&n, "2");
eq(var_os(&n), Some("2"));
set_var(&n, "");
eq(var_os(&n), Some(""));
}
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_var_big() {
let mut s = "".to_string();
let mut i = 0;
while i < 100 {
s.push_str("aaaaaaaaaa");
i += 1;
}
let n = make_rand_name();
set_var(&n, &s);
eq(var_os(&n), Some(&s));
}
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_env_set_get_huge() {
let n = make_rand_name();
let s = "x".repeat(10000);
set_var(&n, &s);
eq(var_os(&n), Some(&s));
remove_var(&n);
eq(var_os(&n), None);
}
#[test]
fn test_env_set_var() {
let n = make_rand_name();
let mut e = vars_os();
set_var(&n, "VALUE");
assert!(!e.any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
assert!(vars_os().any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
}
#[test]
#[cfg_attr(not(any(unix, windows)), ignore, allow(unused))]
#[allow(deprecated)]
fn env_home_dir() {
#[cfg(windows)]
fn split_paths_windows() {
use std::path::PathBuf;
fn var_to_os_string(var: Result<String, VarError>) -> Option<OsString> {
match var {
Ok(var) => Some(OsString::from(var)),
Err(VarError::NotUnicode(var)) => Some(var),
_ => None,
}
fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
split_paths(unparsed).collect::<Vec<_>>()
== parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
}
cfg_if::cfg_if! {
if #[cfg(unix)] {
let oldhome = var_to_os_string(var("HOME"));
assert!(check_parse("", &mut [""]));
assert!(check_parse(r#""""#, &mut [""]));
assert!(check_parse(";;", &mut ["", "", ""]));
assert!(check_parse(r"c:\", &mut [r"c:\"]));
assert!(check_parse(r"c:\;", &mut [r"c:\", ""]));
assert!(check_parse(r"c:\;c:\Program Files\", &mut [r"c:\", r"c:\Program Files\"]));
assert!(check_parse(r#"c:\;c:\"foo"\"#, &mut [r"c:\", r"c:\foo\"]));
assert!(check_parse(r#"c:\;c:\"foo;bar"\;c:\baz"#, &mut [r"c:\", r"c:\foo;bar\", r"c:\baz"]));
}
set_var("HOME", "/home/MountainView");
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
#[test]
#[cfg(unix)]
fn split_paths_unix() {
use std::path::PathBuf;
remove_var("HOME");
if cfg!(target_os = "android") {
assert!(home_dir().is_none());
} else {
// When HOME is not set, some platforms return `None`,
// but others return `Some` with a default.
// Just check that it is not "/home/MountainView".
assert_ne!(home_dir(), Some(PathBuf::from("/home/MountainView")));
}
if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
} else if #[cfg(windows)] {
let oldhome = var_to_os_string(var("HOME"));
let olduserprofile = var_to_os_string(var("USERPROFILE"));
remove_var("HOME");
remove_var("USERPROFILE");
assert!(home_dir().is_some());
set_var("HOME", "/home/PaloAlto");
assert_ne!(home_dir(), Some(PathBuf::from("/home/PaloAlto")), "HOME must not be used");
set_var("USERPROFILE", "/home/MountainView");
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
remove_var("HOME");
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
set_var("USERPROFILE", "");
assert_ne!(home_dir(), Some(PathBuf::from("")), "Empty USERPROFILE must be ignored");
remove_var("USERPROFILE");
if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
if let Some(olduserprofile) = olduserprofile { set_var("USERPROFILE", olduserprofile); }
}
fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
split_paths(unparsed).collect::<Vec<_>>()
== parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
}
assert!(check_parse("", &mut [""]));
assert!(check_parse("::", &mut ["", "", ""]));
assert!(check_parse("/", &mut ["/"]));
assert!(check_parse("/:", &mut ["/", ""]));
assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"]));
}
#[test] // miri shouldn't detect any data race in this fn
#[cfg_attr(any(not(miri), target_os = "emscripten"), ignore)]
fn test_env_get_set_multithreaded() {
let getter = thread::spawn(|| {
for _ in 0..100 {
let _ = var_os("foo");
}
});
#[test]
#[cfg(unix)]
fn join_paths_unix() {
use std::ffi::OsStr;
let setter = thread::spawn(|| {
for _ in 0..100 {
set_var("foo", "bar");
}
});
fn test_eq(input: &[&str], output: &str) -> bool {
&*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
}
let _ = getter.join();
let _ = setter.join();
assert!(test_eq(&[], ""));
assert!(test_eq(&["/bin", "/usr/bin", "/usr/local/bin"], "/bin:/usr/bin:/usr/local/bin"));
assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""], ":/bin:::/usr/bin:"));
assert!(join_paths(["/te:st"].iter().cloned()).is_err());
}
#[test]
#[cfg(windows)]
fn join_paths_windows() {
use std::ffi::OsStr;
fn test_eq(input: &[&str], output: &str) -> bool {
&*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
}
assert!(test_eq(&[], ""));
assert!(test_eq(&[r"c:\windows", r"c:\"], r"c:\windows;c:\"));
assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""], r";c:\windows;;;c:\;"));
assert!(test_eq(&[r"c:\te;st", r"c:\"], r#""c:\te;st";c:\"#));
assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err());
}
#[test]
fn args_debug() {
assert_eq!(
format!("Args {{ inner: {:?} }}", args().collect::<Vec<_>>()),
format!("{:?}", args())
);
}
#[test]
fn args_os_debug() {
assert_eq!(
format!("ArgsOs {{ inner: {:?} }}", args_os().collect::<Vec<_>>()),
format!("{:?}", args_os())
);
}
#[test]
fn vars_debug() {
assert_eq!(
format!("Vars {{ inner: {:?} }}", vars().collect::<Vec<_>>()),
format!("{:?}", vars())
);
}
#[test]
fn vars_os_debug() {
assert_eq!(
format!("VarsOs {{ inner: {:?} }}", vars_os().collect::<Vec<_>>()),
format!("{:?}", vars_os())
);
}

View file

@ -0,0 +1,166 @@
// These tests are in a separate integration test as they modify the environment,
// and would otherwise cause some other tests to fail.
use std::env::*;
use std::ffi::{OsStr, OsString};
use rand::distributions::{Alphanumeric, DistString};
mod common;
use std::thread;
use common::test_rng;
#[track_caller]
fn make_rand_name() -> OsString {
let n = format!("TEST{}", Alphanumeric.sample_string(&mut test_rng(), 10));
let n = OsString::from(n);
assert!(var_os(&n).is_none());
n
}
fn eq(a: Option<OsString>, b: Option<&str>) {
assert_eq!(a.as_ref().map(|s| &**s), b.map(OsStr::new).map(|s| &*s));
}
#[test]
fn test_set_var() {
let n = make_rand_name();
set_var(&n, "VALUE");
eq(var_os(&n), Some("VALUE"));
}
#[test]
fn test_remove_var() {
let n = make_rand_name();
set_var(&n, "VALUE");
remove_var(&n);
eq(var_os(&n), None);
}
#[test]
fn test_set_var_overwrite() {
let n = make_rand_name();
set_var(&n, "1");
set_var(&n, "2");
eq(var_os(&n), Some("2"));
set_var(&n, "");
eq(var_os(&n), Some(""));
}
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_var_big() {
let mut s = "".to_string();
let mut i = 0;
while i < 100 {
s.push_str("aaaaaaaaaa");
i += 1;
}
let n = make_rand_name();
set_var(&n, &s);
eq(var_os(&n), Some(&s));
}
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_env_set_get_huge() {
let n = make_rand_name();
let s = "x".repeat(10000);
set_var(&n, &s);
eq(var_os(&n), Some(&s));
remove_var(&n);
eq(var_os(&n), None);
}
#[test]
fn test_env_set_var() {
let n = make_rand_name();
let mut e = vars_os();
set_var(&n, "VALUE");
assert!(!e.any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
assert!(vars_os().any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
}
#[test]
#[cfg_attr(not(any(unix, windows)), ignore, allow(unused))]
#[allow(deprecated)]
fn env_home_dir() {
use std::path::PathBuf;
fn var_to_os_string(var: Result<String, VarError>) -> Option<OsString> {
match var {
Ok(var) => Some(OsString::from(var)),
Err(VarError::NotUnicode(var)) => Some(var),
_ => None,
}
}
cfg_if::cfg_if! {
if #[cfg(unix)] {
let oldhome = var_to_os_string(var("HOME"));
set_var("HOME", "/home/MountainView");
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
remove_var("HOME");
if cfg!(target_os = "android") {
assert!(home_dir().is_none());
} else {
// When HOME is not set, some platforms return `None`,
// but others return `Some` with a default.
// Just check that it is not "/home/MountainView".
assert_ne!(home_dir(), Some(PathBuf::from("/home/MountainView")));
}
if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
} else if #[cfg(windows)] {
let oldhome = var_to_os_string(var("HOME"));
let olduserprofile = var_to_os_string(var("USERPROFILE"));
remove_var("HOME");
remove_var("USERPROFILE");
assert!(home_dir().is_some());
set_var("HOME", "/home/PaloAlto");
assert_ne!(home_dir(), Some(PathBuf::from("/home/PaloAlto")), "HOME must not be used");
set_var("USERPROFILE", "/home/MountainView");
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
remove_var("HOME");
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
set_var("USERPROFILE", "");
assert_ne!(home_dir(), Some(PathBuf::from("")), "Empty USERPROFILE must be ignored");
remove_var("USERPROFILE");
if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
if let Some(olduserprofile) = olduserprofile { set_var("USERPROFILE", olduserprofile); }
}
}
}
#[test] // miri shouldn't detect any data race in this fn
#[cfg_attr(any(not(miri), target_os = "emscripten"), ignore)]
fn test_env_get_set_multithreaded() {
let getter = thread::spawn(|| {
for _ in 0..100 {
let _ = var_os("foo");
}
});
let setter = thread::spawn(|| {
for _ in 0..100 {
set_var("foo", "bar");
}
});
let _ = getter.join();
let _ = setter.join();
}

View file

@ -1,7 +1,8 @@
use core::error::Request;
#![feature(error_generic_member_access, error_reporter)]
use super::Error;
use crate::fmt;
use std::backtrace::Backtrace;
use std::error::{Error, Report, Request};
use std::fmt;
#[derive(Debug, PartialEq)]
struct A;
@ -38,9 +39,6 @@ fn downcasting() {
}
}
use crate::backtrace::Backtrace;
use crate::error::Report;
#[derive(Debug)]
struct SuperError {
source: SuperErrorSideKick,

View file

@ -1,11 +1,11 @@
// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
#![cfg(reliable_f128)]
use crate::f128::consts;
use crate::num::FpCategory as Fp;
use std::f128::consts;
use std::num::FpCategory as Fp;
#[cfg(reliable_f128_math)]
use crate::ops::Rem;
use crate::ops::{Add, Div, Mul, Sub};
use std::ops::Rem;
use std::ops::{Add, Div, Mul, Sub};
// Note these tolerances make sense around zero, but not for more extreme exponents.
@ -762,8 +762,6 @@ fn test_ln_gamma() {
#[test]
fn test_real_consts() {
use super::consts;
let pi: f128 = consts::PI;
let frac_pi_2: f128 = consts::FRAC_PI_2;
let frac_pi_3: f128 = consts::FRAC_PI_3;

View file

@ -1,8 +1,8 @@
// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
#![cfg(reliable_f16)]
use crate::f16::consts;
use crate::num::{FpCategory as Fp, *};
use std::f16::consts;
use std::num::FpCategory as Fp;
/// Tolerance for results on the order of 10.0e-2
#[allow(unused)]
@ -54,7 +54,7 @@ macro_rules! assert_f16_biteq {
#[test]
fn test_num_f16() {
test_num(10f16, 2f16);
crate::test_num(10f16, 2f16);
}
#[test]
@ -734,7 +734,6 @@ fn test_ln_gamma() {
#[test]
fn test_real_consts() {
// FIXME(f16_f128): add math tests when available
use super::consts;
let pi: f16 = consts::PI;
let frac_pi_2: f16 = consts::FRAC_PI_2;

View file

@ -1,5 +1,5 @@
use crate::f32::consts;
use crate::num::{FpCategory as Fp, *};
use std::f32::consts;
use std::num::FpCategory as Fp;
/// Smallest number
const TINY_BITS: u32 = 0x1;
@ -35,7 +35,7 @@ macro_rules! assert_f32_biteq {
#[test]
fn test_num_f32() {
test_num(10f32, 2f32);
crate::test_num(10f32, 2f32);
}
#[test]
@ -700,8 +700,6 @@ fn test_ln_gamma() {
#[test]
fn test_real_consts() {
use super::consts;
let pi: f32 = consts::PI;
let frac_pi_2: f32 = consts::FRAC_PI_2;
let frac_pi_3: f32 = consts::FRAC_PI_3;

View file

@ -1,5 +1,5 @@
use crate::f64::consts;
use crate::num::{FpCategory as Fp, *};
use std::f64::consts;
use std::num::FpCategory as Fp;
/// Smallest number
const TINY_BITS: u64 = 0x1;
@ -35,7 +35,7 @@ macro_rules! assert_f64_biteq {
#[test]
fn test_num_f64() {
test_num(10f64, 2f64);
crate::test_num(10f64, 2f64);
}
#[test]
@ -680,7 +680,6 @@ fn test_ln_gamma() {
#[test]
fn test_real_consts() {
use super::consts;
let pi: f64 = consts::PI;
let frac_pi_2: f64 = consts::FRAC_PI_2;
let frac_pi_3: f64 = consts::FRAC_PI_3;

View file

@ -0,0 +1,42 @@
#![feature(f16, f128, float_gamma, float_minimum_maximum)]
use std::fmt;
use std::ops::{Add, Div, Mul, Rem, Sub};
/// Verify that floats are within a tolerance of each other, 1.0e-6 by default.
macro_rules! assert_approx_eq {
($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, 1.0e-6) }};
($a:expr, $b:expr, $lim:expr) => {{
let (a, b) = (&$a, &$b);
let diff = (*a - *b).abs();
assert!(
diff < $lim,
"{a:?} is not approximately equal to {b:?} (threshold {lim:?}, difference {diff:?})",
lim = $lim
);
}};
}
/// Helper function for testing numeric operations
pub fn test_num<T>(ten: T, two: T)
where
T: PartialEq
+ Add<Output = T>
+ Sub<Output = T>
+ Mul<Output = T>
+ Div<Output = T>
+ Rem<Output = T>
+ fmt::Debug
+ Copy,
{
assert_eq!(ten.add(two), ten + two);
assert_eq!(ten.sub(two), ten - two);
assert_eq!(ten.mul(two), ten * two);
assert_eq!(ten.div(two), ten / two);
assert_eq!(ten.rem(two), ten % two);
}
mod f128;
mod f16;
mod f32;
mod f64;

View file

@ -1,4 +1,4 @@
use crate::ops::Mul;
use std::ops::Mul;
#[test]
fn test_saturating_add_uint() {
@ -190,8 +190,8 @@ fn test_uint_to_str_overflow() {
assert_eq!(u64_val.to_string(), "0");
}
fn from_str<T: crate::str::FromStr>(t: &str) -> Option<T> {
crate::str::FromStr::from_str(t).ok()
fn from_str<T: std::str::FromStr>(t: &str) -> Option<T> {
std::str::FromStr::from_str(t).ok()
}
#[test]

View file

@ -1,9 +1,9 @@
#![allow(dead_code)]
use crate::cell::RefCell;
use crate::panic::{AssertUnwindSafe, UnwindSafe};
use crate::rc::Rc;
use crate::sync::{Arc, Mutex, RwLock};
use std::cell::RefCell;
use std::panic::{AssertUnwindSafe, UnwindSafe};
use std::rc::Rc;
use std::sync::{Arc, Mutex, RwLock};
struct Foo {
a: i32,

View file

@ -1,10 +1,19 @@
use core::hint::black_box;
#![feature(
clone_to_uninit,
path_add_extension,
path_file_prefix,
maybe_uninit_slice,
os_string_pathbuf_leak
)]
use super::*;
use crate::collections::{BTreeSet, HashSet};
use crate::hash::DefaultHasher;
use crate::mem::MaybeUninit;
use crate::ptr;
use std::clone::CloneToUninit;
use std::ffi::OsStr;
use std::hash::{DefaultHasher, Hash, Hasher};
use std::mem::MaybeUninit;
use std::path::*;
use std::ptr;
use std::rc::Rc;
use std::sync::Arc;
#[allow(unknown_lints, unused_macro_rules)]
macro_rules! t (
@ -110,7 +119,7 @@ macro_rules! t (
#[test]
fn into() {
use crate::borrow::Cow;
use std::borrow::Cow;
let static_path = Path::new("/home/foo");
let static_cow_path: Cow<'static, Path> = static_path.into();
@ -1525,7 +1534,7 @@ pub fn test_with_added_extension() {
#[test]
fn test_eq_receivers() {
use crate::borrow::Cow;
use std::borrow::Cow;
let borrowed: &Path = Path::new("foo/bar");
let mut owned: PathBuf = PathBuf::new();
@ -1550,7 +1559,7 @@ fn test_eq_receivers() {
#[test]
pub fn test_compare() {
use crate::hash::{DefaultHasher, Hash, Hasher};
use std::hash::{DefaultHasher, Hash, Hasher};
fn hash<T: Hash>(t: T) -> u64 {
let mut s = DefaultHasher::new();
@ -1867,12 +1876,12 @@ fn test_ord() {
#[test]
#[cfg(any(unix, target_os = "wasi"))]
fn test_unix_absolute() {
use crate::path::absolute;
use std::path::absolute;
assert!(absolute("").is_err());
let relative = "a/b";
let mut expected = crate::env::current_dir().unwrap();
let mut expected = std::env::current_dir().unwrap();
expected.push(relative);
assert_eq!(absolute(relative).unwrap().as_os_str(), expected.as_os_str());
@ -1888,7 +1897,7 @@ fn test_unix_absolute() {
);
// Test leading `.` and `..` components
let curdir = crate::env::current_dir().unwrap();
let curdir = std::env::current_dir().unwrap();
assert_eq!(absolute("./a").unwrap().as_os_str(), curdir.join("a").as_os_str());
assert_eq!(absolute("../a").unwrap().as_os_str(), curdir.join("../a").as_os_str()); // return /pwd/../a
}
@ -1896,12 +1905,12 @@ fn test_unix_absolute() {
#[test]
#[cfg(windows)]
fn test_windows_absolute() {
use crate::path::absolute;
use std::path::absolute;
// An empty path is an error.
assert!(absolute("").is_err());
let relative = r"a\b";
let mut expected = crate::env::current_dir().unwrap();
let mut expected = std::env::current_dir().unwrap();
expected.push(relative);
assert_eq!(absolute(relative).unwrap().as_os_str(), expected.as_os_str());
@ -1953,116 +1962,6 @@ fn test_extension_path_sep_alternate() {
assert_eq!(path, Path::new("path/to/file.d\\test"));
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) {
let prefix = "my/home";
let mut paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
paths.sort();
b.iter(|| {
black_box(paths.as_mut_slice()).sort_unstable();
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_long(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = BTreeSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
b.iter(|| {
set.remove(paths[500].as_path());
set.insert(paths[500].as_path());
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) {
let prefix = "my/home";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = BTreeSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
b.iter(|| {
set.remove(paths[500].as_path());
set.insert(paths[500].as_path());
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_hashset(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = HashSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
b.iter(|| {
set.remove(paths[500].as_path());
set.insert(black_box(paths[500].as_path()))
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_hashset_miss(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = HashSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
let probe = PathBuf::from(prefix).join("other");
b.iter(|| set.remove(black_box(probe.as_path())));
}
#[bench]
fn bench_hash_path_short(b: &mut test::Bencher) {
let mut hasher = DefaultHasher::new();
let path = Path::new("explorer.exe");
b.iter(|| black_box(path).hash(&mut hasher));
black_box(hasher.finish());
}
#[bench]
fn bench_hash_path_long(b: &mut test::Bencher) {
let mut hasher = DefaultHasher::new();
let path =
Path::new("/aaaaa/aaaaaa/./../aaaaaaaa/bbbbbbbbbbbbb/ccccccccccc/ddddddddd/eeeeeee.fff");
b.iter(|| black_box(path).hash(&mut hasher));
black_box(hasher.finish());
}
#[test]
fn clone_to_uninit() {
let a = Path::new("hello.txt");

View file

@ -1,6 +1,6 @@
use crate::sync::mpsc::{TryRecvError, channel};
use crate::sync::{Arc, Barrier};
use crate::thread;
use std::sync::mpsc::{TryRecvError, channel};
use std::sync::{Arc, Barrier};
use std::thread;
#[test]
#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads

View file

@ -1,8 +1,8 @@
use crate::sync::atomic::{AtomicBool, Ordering};
use crate::sync::mpsc::channel;
use crate::sync::{Arc, Condvar, Mutex};
use crate::thread;
use crate::time::Duration;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::channel;
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
use std::time::Duration;
#[test]
fn smoke() {

View file

@ -1,8 +1,8 @@
use crate::cell::LazyCell;
use crate::sync::atomic::AtomicUsize;
use crate::sync::atomic::Ordering::SeqCst;
use crate::sync::{LazyLock, Mutex, OnceLock};
use crate::{panic, thread};
use std::cell::LazyCell;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use std::sync::{LazyLock, Mutex, OnceLock};
use std::{panic, thread};
fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
thread::spawn(f).join().unwrap()
@ -149,7 +149,7 @@ fn is_sync_send() {
#[should_panic = "has previously been poisoned"]
fn lazy_force_mut_panic() {
let mut lazy = LazyLock::<String>::new(|| panic!());
crate::panic::catch_unwind(crate::panic::AssertUnwindSafe(|| {
panic::catch_unwind(panic::AssertUnwindSafe(|| {
let _ = LazyLock::force_mut(&mut lazy);
}))
.unwrap_err();

View file

@ -0,0 +1,31 @@
#![feature(lazy_get)]
#![feature(mapped_lock_guards)]
#![feature(mpmc_channel)]
#![feature(once_cell_try)]
#![feature(lock_value_accessors)]
#![feature(reentrant_lock)]
#![feature(rwlock_downgrade)]
#![feature(std_internals)]
#![allow(internal_features)]
mod barrier;
mod condvar;
mod lazy_lock;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod mpmc;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod mpsc;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod mpsc_sync;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod mutex;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod once;
mod once_lock;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod reentrant_lock;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod rwlock;
#[path = "../common/mod.rs"]
mod common;

View file

@ -1,5 +1,6 @@
use super::*;
use crate::{env, thread};
use std::sync::mpmc::*;
use std::time::{Duration, Instant};
use std::{env, thread};
pub fn stress_factor() -> usize {
match env::var("RUST_TEST_STRESS") {

View file

@ -1,5 +1,6 @@
use super::*;
use crate::{env, thread};
use std::sync::mpsc::*;
use std::time::{Duration, Instant};
use std::{env, thread};
pub fn stress_factor() -> usize {
match env::var("RUST_TEST_STRESS") {

View file

@ -1,7 +1,8 @@
use super::*;
use crate::rc::Rc;
use crate::sync::mpmc::SendTimeoutError;
use crate::{env, thread};
use std::rc::Rc;
use std::sync::mpmc::SendTimeoutError;
use std::sync::mpsc::*;
use std::time::Duration;
use std::{env, thread};
pub fn stress_factor() -> usize {
match env::var("RUST_TEST_STRESS") {

View file

@ -1,10 +1,10 @@
use crate::fmt::Debug;
use crate::ops::FnMut;
use crate::panic::{self, AssertUnwindSafe};
use crate::sync::atomic::{AtomicUsize, Ordering};
use crate::sync::mpsc::channel;
use crate::sync::{Arc, Condvar, MappedMutexGuard, Mutex, MutexGuard, TryLockError};
use crate::{hint, mem, thread};
use std::fmt::Debug;
use std::ops::FnMut;
use std::panic::{self, AssertUnwindSafe};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::channel;
use std::sync::{Arc, Condvar, MappedMutexGuard, Mutex, MutexGuard, TryLockError};
use std::{hint, mem, thread};
struct Packet<T>(Arc<(Mutex<T>, Condvar)>);

View file

@ -1,9 +1,9 @@
use super::Once;
use crate::sync::atomic::AtomicBool;
use crate::sync::atomic::Ordering::Relaxed;
use crate::sync::mpsc::channel;
use crate::time::Duration;
use crate::{panic, thread};
use std::sync::Once;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::Relaxed;
use std::sync::mpsc::channel;
use std::time::Duration;
use std::{panic, thread};
#[test]
fn smoke_once() {

View file

@ -1,8 +1,8 @@
use crate::sync::OnceLock;
use crate::sync::atomic::AtomicUsize;
use crate::sync::atomic::Ordering::SeqCst;
use crate::sync::mpsc::channel;
use crate::{panic, thread};
use std::sync::OnceLock;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use std::sync::mpsc::channel;
use std::{panic, thread};
fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
thread::spawn(f).join().unwrap()
@ -33,15 +33,6 @@ fn sync_once_cell_get_mut() {
assert_eq!(c.get_mut(), Some(&mut 92));
}
#[test]
fn sync_once_cell_get_unchecked() {
let c = OnceLock::new();
c.set(92).unwrap();
unsafe {
assert_eq!(c.get_unchecked(), &92);
}
}
#[test]
#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
fn sync_once_cell_drop() {
@ -88,7 +79,6 @@ fn get_or_try_init() {
let res = panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() }));
assert!(res.is_err());
assert!(!cell.is_initialized());
assert!(cell.get().is_none());
assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
@ -174,7 +164,7 @@ fn sync_once_cell_does_not_leak_partially_constructed_boxes() {
break;
}
#[cfg(target_env = "sgx")]
crate::thread::yield_now();
std::thread::yield_now();
}
});
}

View file

@ -1,7 +1,6 @@
use super::ReentrantLock;
use crate::cell::RefCell;
use crate::sync::Arc;
use crate::thread;
use std::cell::RefCell;
use std::sync::{Arc, ReentrantLock};
use std::thread;
#[test]
fn smoke() {

View file

@ -1,15 +1,15 @@
use rand::Rng;
use crate::fmt::Debug;
use crate::ops::FnMut;
use crate::panic::{self, AssertUnwindSafe};
use crate::sync::atomic::{AtomicUsize, Ordering};
use crate::sync::mpsc::channel;
use crate::sync::{
use std::fmt::Debug;
use std::ops::FnMut;
use std::panic::{self, AssertUnwindSafe};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::channel;
use std::sync::{
Arc, MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
TryLockError,
};
use crate::{hint, mem, thread};
use std::{hint, mem, thread};
use rand::Rng;
#[derive(Eq, PartialEq, Debug)]
struct NonCopy(i32);
@ -57,7 +57,7 @@ fn frob() {
let tx = tx.clone();
let r = r.clone();
thread::spawn(move || {
let mut rng = crate::test_helpers::test_rng();
let mut rng = crate::common::test_rng();
for _ in 0..M {
if rng.gen_bool(1.0 / (N as f64)) {
drop(r.write().unwrap());
@ -704,7 +704,7 @@ fn test_downgrade_atomic() {
// Wait for a good amount of time so that evil threads go to sleep.
// Note: this is not strictly necessary...
let eternity = crate::time::Duration::from_millis(42);
let eternity = std::time::Duration::from_millis(42);
thread::sleep(eternity);
// Once everyone is asleep, set the value to `NEW_VALUE`.

View file

@ -1,6 +1,6 @@
use crate::cell::RefCell;
use crate::collections::HashMap;
use crate::thread_local;
use std::cell::RefCell;
use std::collections::HashMap;
use std::thread_local;
#[test]
fn smoke() {

View file

@ -0,0 +1,4 @@
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod tests;
mod dynamic_tests;

View file

@ -1,8 +1,8 @@
use crate::cell::{Cell, UnsafeCell};
use crate::sync::atomic::{AtomicU8, Ordering};
use crate::sync::{Arc, Condvar, Mutex};
use crate::thread::{self, Builder, LocalKey};
use crate::thread_local;
use std::cell::{Cell, UnsafeCell};
use std::sync::atomic::{AtomicU8, Ordering};
use std::sync::{Arc, Condvar, Mutex};
use std::thread::{self, Builder, LocalKey};
use std::thread_local;
#[derive(Clone, Default)]
struct Signal(Arc<(Mutex<bool>, Condvar)>);

View file

@ -1,9 +1,7 @@
use core::fmt::Debug;
#![feature(duration_constants)]
#[cfg(not(target_arch = "wasm32"))]
use test::{Bencher, black_box};
use super::{Duration, Instant, SystemTime, UNIX_EPOCH};
use std::fmt::Debug;
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
macro_rules! assert_almost_eq {
($a:expr, $b:expr) => {{
@ -29,10 +27,10 @@ fn instant_monotonic() {
#[test]
#[cfg(not(target_arch = "wasm32"))]
fn instant_monotonic_concurrent() -> crate::thread::Result<()> {
fn instant_monotonic_concurrent() -> std::thread::Result<()> {
let threads: Vec<_> = (0..8)
.map(|_| {
crate::thread::spawn(|| {
std::thread::spawn(|| {
let mut old = Instant::now();
let count = if cfg!(miri) { 1_000 } else { 5_000_000 };
for _ in 0..count {
@ -229,46 +227,3 @@ fn big_math() {
check(instant.checked_add(Duration::from_secs(100)), Instant::checked_sub);
check(instant.checked_add(Duration::from_secs(i64::MAX as _)), Instant::checked_sub);
}
macro_rules! bench_instant_threaded {
($bench_name:ident, $thread_count:expr) => {
#[bench]
#[cfg(not(target_arch = "wasm32"))]
fn $bench_name(b: &mut Bencher) -> crate::thread::Result<()> {
use crate::sync::Arc;
use crate::sync::atomic::{AtomicBool, Ordering};
let running = Arc::new(AtomicBool::new(true));
let threads: Vec<_> = (0..$thread_count)
.map(|_| {
let flag = Arc::clone(&running);
crate::thread::spawn(move || {
while flag.load(Ordering::Relaxed) {
black_box(Instant::now());
}
})
})
.collect();
b.iter(|| {
let a = Instant::now();
let b = Instant::now();
assert!(b >= a);
});
running.store(false, Ordering::Relaxed);
for t in threads {
t.join()?;
}
Ok(())
}
};
}
bench_instant_threaded!(instant_contention_01_threads, 0);
bench_instant_threaded!(instant_contention_02_threads, 1);
bench_instant_threaded!(instant_contention_04_threads, 3);
bench_instant_threaded!(instant_contention_08_threads, 7);
bench_instant_threaded!(instant_contention_16_threads, 15);