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:
commit
d2aa3dec8a
53 changed files with 645 additions and 650 deletions
|
@ -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"
|
||||
|
|
|
@ -5,3 +5,5 @@
|
|||
extern crate test;
|
||||
|
||||
mod hash;
|
||||
mod path;
|
||||
mod time;
|
||||
|
|
114
library/std/benches/path.rs
Normal file
114
library/std/benches/path.rs
Normal 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());
|
||||
}
|
47
library/std/benches/time.rs
Normal file
47
library/std/benches/time.rs
Normal 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);
|
|
@ -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};
|
||||
|
|
120
library/std/src/env/tests.rs
vendored
120
library/std/src/env/tests.rs
vendored
|
@ -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())
|
||||
);
|
||||
}
|
|
@ -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")]
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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::{
|
||||
|
|
|
@ -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::{
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -529,6 +529,3 @@ pub fn get_backtrace_style() -> Option<BacktraceStyle> {
|
|||
Err(new) => BacktraceStyle::from_u8(new),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -681,6 +681,3 @@ unsafe impl<#[may_dangle] T> Drop for OnceLock<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -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())
|
||||
);
|
||||
}
|
||||
|
|
166
library/std/tests/env_modify.rs
Normal file
166
library/std/tests/env_modify.rs
Normal 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();
|
||||
}
|
|
@ -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,
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
42
library/std/tests/floats/lib.rs
Normal file
42
library/std/tests/floats/lib.rs
Normal 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;
|
|
@ -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]
|
|
@ -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,
|
|
@ -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");
|
|
@ -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
|
|
@ -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() {
|
|
@ -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();
|
31
library/std/tests/sync/lib.rs
Normal file
31
library/std/tests/sync/lib.rs
Normal 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;
|
|
@ -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") {
|
|
@ -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") {
|
|
@ -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") {
|
|
@ -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)>);
|
||||
|
|
@ -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() {
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
|
@ -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() {
|
|
@ -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`.
|
|
@ -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() {
|
4
library/std/tests/thread_local/lib.rs
Normal file
4
library/std/tests/thread_local/lib.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
|
||||
mod tests;
|
||||
|
||||
mod dynamic_tests;
|
|
@ -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)>);
|
|
@ -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);
|
Loading…
Add table
Add a link
Reference in a new issue