123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
- // file at the top-level directory of this distribution and at
- // http://rust-lang.org/COPYRIGHT.
- //
- // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
- // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
- // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
- // option. This file may not be copied, modified, or distributed
- // except according to those terms.
- #![deny(rust_2018_idioms)]
- use std::env;
- use std::fs;
- use std::path::Path;
- use std::sync::mpsc::channel;
- use std::thread;
- use tempfile::{Builder, TempDir};
- macro_rules! t {
- ($e:expr) => {
- match $e {
- Ok(n) => n,
- Err(e) => panic!("error: {}", e),
- }
- };
- }
- trait PathExt {
- fn exists(&self) -> bool;
- fn is_dir(&self) -> bool;
- }
- impl PathExt for Path {
- fn exists(&self) -> bool {
- fs::metadata(self).is_ok()
- }
- fn is_dir(&self) -> bool {
- fs::metadata(self).map(|m| m.is_dir()).unwrap_or(false)
- }
- }
- fn test_tempdir() {
- let path = {
- let p = t!(Builder::new().prefix("foobar").tempdir_in(&Path::new(".")));
- let p = p.path();
- assert!(p.to_str().unwrap().contains("foobar"));
- p.to_path_buf()
- };
- assert!(!path.exists());
- }
- #[test]
- fn test_customnamed() {
- let tmpfile = Builder::new()
- .prefix("prefix")
- .suffix("suffix")
- .rand_bytes(12)
- .tempdir()
- .unwrap();
- let name = tmpfile.path().file_name().unwrap().to_str().unwrap();
- assert!(name.starts_with("prefix"));
- assert!(name.ends_with("suffix"));
- assert_eq!(name.len(), 24);
- }
- fn test_rm_tempdir() {
- let (tx, rx) = channel();
- let f = move || -> () {
- let tmp = t!(TempDir::new());
- tx.send(tmp.path().to_path_buf()).unwrap();
- panic!("panic to unwind past `tmp`");
- };
- let _ = thread::spawn(f).join();
- let path = rx.recv().unwrap();
- assert!(!path.exists());
- let tmp = t!(TempDir::new());
- let path = tmp.path().to_path_buf();
- let f = move || -> () {
- let _tmp = tmp;
- panic!("panic to unwind past `tmp`");
- };
- let _ = thread::spawn(f).join();
- assert!(!path.exists());
- let path;
- {
- let f = move || t!(TempDir::new());
- let tmp = thread::spawn(f).join().unwrap();
- path = tmp.path().to_path_buf();
- assert!(path.exists());
- }
- assert!(!path.exists());
- let path;
- {
- let tmp = t!(TempDir::new());
- path = tmp.into_path();
- }
- assert!(path.exists());
- t!(fs::remove_dir_all(&path));
- assert!(!path.exists());
- }
- fn test_rm_tempdir_close() {
- let (tx, rx) = channel();
- let f = move || -> () {
- let tmp = t!(TempDir::new());
- tx.send(tmp.path().to_path_buf()).unwrap();
- t!(tmp.close());
- panic!("panic when unwinding past `tmp`");
- };
- let _ = thread::spawn(f).join();
- let path = rx.recv().unwrap();
- assert!(!path.exists());
- let tmp = t!(TempDir::new());
- let path = tmp.path().to_path_buf();
- let f = move || -> () {
- let tmp = tmp;
- t!(tmp.close());
- panic!("panic when unwinding past `tmp`");
- };
- let _ = thread::spawn(f).join();
- assert!(!path.exists());
- let path;
- {
- let f = move || t!(TempDir::new());
- let tmp = thread::spawn(f).join().unwrap();
- path = tmp.path().to_path_buf();
- assert!(path.exists());
- t!(tmp.close());
- }
- assert!(!path.exists());
- let path;
- {
- let tmp = t!(TempDir::new());
- path = tmp.into_path();
- }
- assert!(path.exists());
- t!(fs::remove_dir_all(&path));
- assert!(!path.exists());
- }
- // Ideally these would be in std::os but then core would need
- // to depend on std
- fn recursive_mkdir_rel() {
- let path = Path::new("frob");
- let cwd = env::current_dir().unwrap();
- println!(
- "recursive_mkdir_rel: Making: {} in cwd {} [{}]",
- path.display(),
- cwd.display(),
- path.exists()
- );
- t!(fs::create_dir(&path));
- assert!(path.is_dir());
- t!(fs::create_dir_all(&path));
- assert!(path.is_dir());
- }
- fn recursive_mkdir_dot() {
- let dot = Path::new(".");
- t!(fs::create_dir_all(&dot));
- let dotdot = Path::new("..");
- t!(fs::create_dir_all(&dotdot));
- }
- fn recursive_mkdir_rel_2() {
- let path = Path::new("./frob/baz");
- let cwd = env::current_dir().unwrap();
- println!(
- "recursive_mkdir_rel_2: Making: {} in cwd {} [{}]",
- path.display(),
- cwd.display(),
- path.exists()
- );
- t!(fs::create_dir_all(&path));
- assert!(path.is_dir());
- assert!(path.parent().unwrap().is_dir());
- let path2 = Path::new("quux/blat");
- println!(
- "recursive_mkdir_rel_2: Making: {} in cwd {}",
- path2.display(),
- cwd.display()
- );
- t!(fs::create_dir("quux"));
- t!(fs::create_dir_all(&path2));
- assert!(path2.is_dir());
- assert!(path2.parent().unwrap().is_dir());
- }
- // Ideally this would be in core, but needs TempFile
- pub fn test_remove_dir_all_ok() {
- let tmpdir = t!(TempDir::new());
- let tmpdir = tmpdir.path();
- let root = tmpdir.join("foo");
- println!("making {}", root.display());
- t!(fs::create_dir(&root));
- t!(fs::create_dir(&root.join("foo")));
- t!(fs::create_dir(&root.join("foo").join("bar")));
- t!(fs::create_dir(&root.join("foo").join("bar").join("blat")));
- t!(fs::remove_dir_all(&root));
- assert!(!root.exists());
- assert!(!root.join("bar").exists());
- assert!(!root.join("bar").join("blat").exists());
- }
- pub fn dont_double_panic() {
- let r: Result<(), _> = thread::spawn(move || {
- let tmpdir = TempDir::new().unwrap();
- // Remove the temporary directory so that TempDir sees
- // an error on drop
- t!(fs::remove_dir(tmpdir.path()));
- // Panic. If TempDir panics *again* due to the rmdir
- // error then the process will abort.
- panic!();
- })
- .join();
- assert!(r.is_err());
- }
- fn in_tmpdir<F>(f: F)
- where
- F: FnOnce(),
- {
- let tmpdir = t!(TempDir::new());
- assert!(env::set_current_dir(tmpdir.path()).is_ok());
- f();
- }
- pub fn pass_as_asref_path() {
- let tempdir = t!(TempDir::new());
- takes_asref_path(&tempdir);
- fn takes_asref_path<T: AsRef<Path>>(path: T) {
- let path = path.as_ref();
- assert!(path.exists());
- }
- }
- #[test]
- fn main() {
- in_tmpdir(test_tempdir);
- in_tmpdir(test_rm_tempdir);
- in_tmpdir(test_rm_tempdir_close);
- in_tmpdir(recursive_mkdir_rel);
- in_tmpdir(recursive_mkdir_dot);
- in_tmpdir(recursive_mkdir_rel_2);
- in_tmpdir(test_remove_dir_all_ok);
- in_tmpdir(dont_double_panic);
- in_tmpdir(pass_as_asref_path);
- }
|