diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 839fdc96632d1..909d9bf4093b3 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1595,3 +1595,19 @@ fn test_read_dir_infinite_loop() { // Check for duplicate errors assert!(dir.filter(|e| e.is_err()).take(2).count() < 2); } + +#[test] +fn rename_directory() { + let tmpdir = tmpdir(); + let old_path = tmpdir.join("foo/bar/baz"); + fs::create_dir_all(&old_path).unwrap(); + let test_file = &old_path.join("temp.txt"); + + File::create(test_file).unwrap(); + + let new_path = tmpdir.join("quux/blat"); + fs::create_dir_all(&new_path).unwrap(); + fs::rename(&old_path, &new_path.join("newdir")).unwrap(); + assert!(new_path.join("newdir").is_dir()); + assert!(new_path.join("newdir/temp.txt").exists()); +} diff --git a/library/std/tests/common/mod.rs b/library/std/tests/common/mod.rs new file mode 100644 index 0000000000000..fce220223a055 --- /dev/null +++ b/library/std/tests/common/mod.rs @@ -0,0 +1,58 @@ +#![allow(unused)] + +use std::env; +use std::fs; +use std::path::{Path, PathBuf}; +use std::thread; +use rand::RngCore; + +/// Copied from `std::test_helpers::test_rng`, since these tests rely on the +/// seed not being the same for every RNG invocation too. +#[track_caller] +pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng { + use core::hash::{BuildHasher, Hash, Hasher}; + let mut hasher = std::collections::hash_map::RandomState::new().build_hasher(); + core::panic::Location::caller().hash(&mut hasher); + let hc64 = hasher.finish(); + let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::>(); + let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap(); + rand::SeedableRng::from_seed(seed) +} + +// Copied from std::sys_common::io +pub struct TempDir(PathBuf); + +impl TempDir { + pub fn join(&self, path: &str) -> PathBuf { + let TempDir(ref p) = *self; + p.join(path) + } + + pub fn path(&self) -> &Path { + let TempDir(ref p) = *self; + p + } +} + +impl Drop for TempDir { + fn drop(&mut self) { + // Gee, seeing how we're testing the fs module I sure hope that we + // at least implement this correctly! + let TempDir(ref p) = *self; + let result = fs::remove_dir_all(p); + // Avoid panicking while panicking as this causes the process to + // immediately abort, without displaying test results. + if !thread::panicking() { + result.unwrap(); + } + } +} + +#[track_caller] // for `test_rng` +pub fn tmpdir() -> TempDir { + let p = env::temp_dir(); + let mut r = test_rng(); + let ret = p.join(&format!("rust-{}", r.next_u32())); + fs::create_dir(&ret).unwrap(); + TempDir(ret) +} diff --git a/library/std/tests/create_dir_all_bare.rs b/library/std/tests/create_dir_all_bare.rs new file mode 100644 index 0000000000000..fe789323f97c0 --- /dev/null +++ b/library/std/tests/create_dir_all_bare.rs @@ -0,0 +1,39 @@ +#![cfg(all(test, not(any(target_os = "emscripten", target_env = "sgx"))))] + +//! Note that this test changes the current directory so +//! should not be in the same process as other tests. +use std::env; +use std::fs; +use std::path::{Path, PathBuf}; + +mod common; + +// On some platforms, setting the current directory will prevent deleting it. +// So this helper ensures the current directory is reset. +struct CurrentDir(PathBuf); +impl CurrentDir { + fn new() -> Self { + Self(env::current_dir().unwrap()) + } + fn set(&self, path: &Path) { + env::set_current_dir(path).unwrap(); + } + fn with(path: &Path, f: impl FnOnce()) { + let current_dir = Self::new(); + current_dir.set(path); + f(); + } +} +impl Drop for CurrentDir { + fn drop(&mut self) { + env::set_current_dir(&self.0).unwrap(); + } +} + +#[test] +fn create_dir_all_bare() { + let tmpdir = common::tmpdir(); + CurrentDir::with(tmpdir.path(), || { + fs::create_dir_all("create-dir-all-bare").unwrap(); + }); +} diff --git a/library/std/tests/env.rs b/library/std/tests/env.rs index aae2c49d8982e..96b4f372b8b10 100644 --- a/library/std/tests/env.rs +++ b/library/std/tests/env.rs @@ -3,18 +3,8 @@ use std::ffi::{OsStr, OsString}; use rand::distributions::{Alphanumeric, DistString}; -/// Copied from `std::test_helpers::test_rng`, since these tests rely on the -/// seed not being the same for every RNG invocation too. -#[track_caller] -pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng { - use core::hash::{BuildHasher, Hash, Hasher}; - let mut hasher = std::collections::hash_map::RandomState::new().build_hasher(); - core::panic::Location::caller().hash(&mut hasher); - let hc64 = hasher.finish(); - let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::>(); - let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap(); - rand::SeedableRng::from_seed(seed) -} +mod common; +use common::test_rng; #[track_caller] fn make_rand_name() -> OsString { diff --git a/tests/ui-fulldeps/create-dir-all-bare.rs b/tests/ui-fulldeps/create-dir-all-bare.rs deleted file mode 100644 index 4554680ec2470..0000000000000 --- a/tests/ui-fulldeps/create-dir-all-bare.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -use std::env; -use std::fs; -use std::path::PathBuf; - -fn main() { - let path = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); - env::set_current_dir(&path).unwrap(); - fs::create_dir_all("create-dir-all-bare").unwrap(); -} diff --git a/tests/ui-fulldeps/rename-directory.rs b/tests/ui-fulldeps/rename-directory.rs deleted file mode 100644 index 8fc340cb91872..0000000000000 --- a/tests/ui-fulldeps/rename-directory.rs +++ /dev/null @@ -1,30 +0,0 @@ -// run-pass - -#![allow(unused_must_use)] -#![allow(unused_imports)] -// This test can't be a unit test in std, -// because it needs TempDir, which is in extra - -// ignore-cross-compile - -use std::env; -use std::ffi::CString; -use std::fs::{self, File}; -use std::path::PathBuf; - -fn rename_directory() { - let tmpdir = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); - let old_path = tmpdir.join("foo/bar/baz"); - fs::create_dir_all(&old_path).unwrap(); - let test_file = &old_path.join("temp.txt"); - - File::create(test_file).unwrap(); - - let new_path = tmpdir.join("quux/blat"); - fs::create_dir_all(&new_path).unwrap(); - fs::rename(&old_path, &new_path.join("newdir")); - assert!(new_path.join("newdir").is_dir()); - assert!(new_path.join("newdir/temp.txt").exists()); -} - -pub fn main() { rename_directory() } diff --git a/tests/ui-fulldeps/issue-15149.rs b/tests/ui-fulldeps/std/issue-15149.rs similarity index 100% rename from tests/ui-fulldeps/issue-15149.rs rename to tests/ui-fulldeps/std/issue-15149.rs diff --git a/tests/ui-fulldeps/issue-81357-unsound-file-methods.rs b/tests/ui-fulldeps/std/issue-81357-unsound-file-methods.rs similarity index 100% rename from tests/ui-fulldeps/issue-81357-unsound-file-methods.rs rename to tests/ui-fulldeps/std/issue-81357-unsound-file-methods.rs diff --git a/tests/ui-fulldeps/stdio-from.rs b/tests/ui-fulldeps/std/stdio-from.rs similarity index 100% rename from tests/ui-fulldeps/stdio-from.rs rename to tests/ui-fulldeps/std/stdio-from.rs diff --git a/tests/ui-fulldeps/switch-stdout.rs b/tests/ui-fulldeps/std/switch-stdout.rs similarity index 100% rename from tests/ui-fulldeps/switch-stdout.rs rename to tests/ui-fulldeps/std/switch-stdout.rs