| #![deny(rust_2018_idioms)] | 
 |  | 
 | use std::ffi::{OsStr, OsString}; | 
 | use std::fs::File; | 
 | use std::io::{Read, Seek, SeekFrom, Write}; | 
 | use std::path::{Path, PathBuf}; | 
 | use tempfile::{env, tempdir, Builder, NamedTempFile, TempPath}; | 
 |  | 
 | fn exists<P: AsRef<Path>>(path: P) -> bool { | 
 |     std::fs::metadata(path.as_ref()).is_ok() | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_prefix() { | 
 |     let tmpfile = NamedTempFile::with_prefix("prefix").unwrap(); | 
 |     let name = tmpfile.path().file_name().unwrap().to_str().unwrap(); | 
 |     assert!(name.starts_with("prefix")); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_basic() { | 
 |     let mut tmpfile = NamedTempFile::new().unwrap(); | 
 |     write!(tmpfile, "abcde").unwrap(); | 
 |     tmpfile.seek(SeekFrom::Start(0)).unwrap(); | 
 |     let mut buf = String::new(); | 
 |     tmpfile.read_to_string(&mut buf).unwrap(); | 
 |     assert_eq!("abcde", buf); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_deleted() { | 
 |     let tmpfile = NamedTempFile::new().unwrap(); | 
 |     let path = tmpfile.path().to_path_buf(); | 
 |     assert!(exists(&path)); | 
 |     drop(tmpfile); | 
 |     assert!(!exists(&path)); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_persist() { | 
 |     let mut tmpfile = NamedTempFile::new().unwrap(); | 
 |     let old_path = tmpfile.path().to_path_buf(); | 
 |     let persist_path = env::temp_dir().join("persisted_temporary_file"); | 
 |     write!(tmpfile, "abcde").unwrap(); | 
 |     { | 
 |         assert!(exists(&old_path)); | 
 |         let mut f = tmpfile.persist(&persist_path).unwrap(); | 
 |         assert!(!exists(&old_path)); | 
 |  | 
 |         // Check original file | 
 |         f.seek(SeekFrom::Start(0)).unwrap(); | 
 |         let mut buf = String::new(); | 
 |         f.read_to_string(&mut buf).unwrap(); | 
 |         assert_eq!("abcde", buf); | 
 |     } | 
 |  | 
 |     { | 
 |         // Try opening it at the new path. | 
 |         let mut f = File::open(&persist_path).unwrap(); | 
 |         f.seek(SeekFrom::Start(0)).unwrap(); | 
 |         let mut buf = String::new(); | 
 |         f.read_to_string(&mut buf).unwrap(); | 
 |         assert_eq!("abcde", buf); | 
 |     } | 
 |     std::fs::remove_file(&persist_path).unwrap(); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_persist_noclobber() { | 
 |     let mut tmpfile = NamedTempFile::new().unwrap(); | 
 |     let old_path = tmpfile.path().to_path_buf(); | 
 |     let persist_target = NamedTempFile::new().unwrap(); | 
 |     let persist_path = persist_target.path().to_path_buf(); | 
 |     write!(tmpfile, "abcde").unwrap(); | 
 |     assert!(exists(&old_path)); | 
 |     { | 
 |         tmpfile = tmpfile.persist_noclobber(&persist_path).unwrap_err().into(); | 
 |         assert!(exists(&old_path)); | 
 |         std::fs::remove_file(&persist_path).unwrap(); | 
 |         drop(persist_target); | 
 |     } | 
 |     tmpfile.persist_noclobber(&persist_path).unwrap(); | 
 |     // Try opening it at the new path. | 
 |     let mut f = File::open(&persist_path).unwrap(); | 
 |     f.seek(SeekFrom::Start(0)).unwrap(); | 
 |     let mut buf = String::new(); | 
 |     f.read_to_string(&mut buf).unwrap(); | 
 |     assert_eq!("abcde", buf); | 
 |     std::fs::remove_file(&persist_path).unwrap(); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_customnamed() { | 
 |     let tmpfile = Builder::new() | 
 |         .prefix("tmp") | 
 |         .suffix(&".rs") | 
 |         .rand_bytes(12) | 
 |         .tempfile() | 
 |         .unwrap(); | 
 |     let name = tmpfile.path().file_name().unwrap().to_str().unwrap(); | 
 |     assert!(name.starts_with("tmp")); | 
 |     assert!(name.ends_with(".rs")); | 
 |     assert_eq!(name.len(), 18); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_append() { | 
 |     let mut tmpfile = Builder::new().append(true).tempfile().unwrap(); | 
 |     tmpfile.write_all(b"a").unwrap(); | 
 |     tmpfile.seek(SeekFrom::Start(0)).unwrap(); | 
 |     tmpfile.write_all(b"b").unwrap(); | 
 |  | 
 |     tmpfile.seek(SeekFrom::Start(0)).unwrap(); | 
 |     let mut buf = vec![0u8; 1]; | 
 |     tmpfile.read_exact(&mut buf).unwrap(); | 
 |     assert_eq!(buf, b"a"); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_reopen() { | 
 |     let source = NamedTempFile::new().unwrap(); | 
 |     let mut first = source.reopen().unwrap(); | 
 |     let mut second = source.reopen().unwrap(); | 
 |     drop(source); | 
 |  | 
 |     write!(first, "abcde").expect("write failed"); | 
 |     let mut buf = String::new(); | 
 |     second.read_to_string(&mut buf).unwrap(); | 
 |     assert_eq!("abcde", buf); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_into_file() { | 
 |     let mut file = NamedTempFile::new().unwrap(); | 
 |     let path = file.path().to_owned(); | 
 |     write!(file, "abcde").expect("write failed"); | 
 |  | 
 |     assert!(path.exists()); | 
 |     let mut file = file.into_file(); | 
 |     assert!(!path.exists()); | 
 |  | 
 |     file.seek(SeekFrom::Start(0)).unwrap(); | 
 |     let mut buf = String::new(); | 
 |     file.read_to_string(&mut buf).unwrap(); | 
 |     assert_eq!("abcde", buf); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_immut() { | 
 |     let tmpfile = NamedTempFile::new().unwrap(); | 
 |     (&tmpfile).write_all(b"abcde").unwrap(); | 
 |     (&tmpfile).seek(SeekFrom::Start(0)).unwrap(); | 
 |     let mut buf = String::new(); | 
 |     (&tmpfile).read_to_string(&mut buf).unwrap(); | 
 |     assert_eq!("abcde", buf); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_temppath() { | 
 |     let mut tmpfile = NamedTempFile::new().unwrap(); | 
 |     write!(tmpfile, "abcde").unwrap(); | 
 |  | 
 |     let path = tmpfile.into_temp_path(); | 
 |     assert!(path.is_file()); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_temppath_persist() { | 
 |     let mut tmpfile = NamedTempFile::new().unwrap(); | 
 |     write!(tmpfile, "abcde").unwrap(); | 
 |  | 
 |     let tmppath = tmpfile.into_temp_path(); | 
 |  | 
 |     let old_path = tmppath.to_path_buf(); | 
 |     let persist_path = env::temp_dir().join("persisted_temppath_file"); | 
 |  | 
 |     { | 
 |         assert!(exists(&old_path)); | 
 |         tmppath.persist(&persist_path).unwrap(); | 
 |         assert!(!exists(&old_path)); | 
 |     } | 
 |  | 
 |     { | 
 |         // Try opening it at the new path. | 
 |         let mut f = File::open(&persist_path).unwrap(); | 
 |         f.seek(SeekFrom::Start(0)).unwrap(); | 
 |         let mut buf = String::new(); | 
 |         f.read_to_string(&mut buf).unwrap(); | 
 |         assert_eq!("abcde", buf); | 
 |     } | 
 |  | 
 |     std::fs::remove_file(&persist_path).unwrap(); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_temppath_persist_noclobber() { | 
 |     let mut tmpfile = NamedTempFile::new().unwrap(); | 
 |     write!(tmpfile, "abcde").unwrap(); | 
 |  | 
 |     let mut tmppath = tmpfile.into_temp_path(); | 
 |  | 
 |     let old_path = tmppath.to_path_buf(); | 
 |     let persist_target = NamedTempFile::new().unwrap(); | 
 |     let persist_path = persist_target.path().to_path_buf(); | 
 |  | 
 |     assert!(exists(&old_path)); | 
 |  | 
 |     { | 
 |         tmppath = tmppath.persist_noclobber(&persist_path).unwrap_err().into(); | 
 |         assert!(exists(&old_path)); | 
 |         std::fs::remove_file(&persist_path).unwrap(); | 
 |         drop(persist_target); | 
 |     } | 
 |  | 
 |     tmppath.persist_noclobber(&persist_path).unwrap(); | 
 |  | 
 |     // Try opening it at the new path. | 
 |     let mut f = File::open(&persist_path).unwrap(); | 
 |     f.seek(SeekFrom::Start(0)).unwrap(); | 
 |     let mut buf = String::new(); | 
 |     f.read_to_string(&mut buf).unwrap(); | 
 |     assert_eq!("abcde", buf); | 
 |     std::fs::remove_file(&persist_path).unwrap(); | 
 | } | 
 |  | 
 | #[test] | 
 | fn temp_path_from_existing() { | 
 |     let tmp_dir = tempdir().unwrap(); | 
 |     let tmp_file_path_1 = tmp_dir.path().join("testfile1"); | 
 |     let tmp_file_path_2 = tmp_dir.path().join("testfile2"); | 
 |  | 
 |     File::create(&tmp_file_path_1).unwrap(); | 
 |     assert!(tmp_file_path_1.exists(), "Test file 1 hasn't been created"); | 
 |  | 
 |     File::create(&tmp_file_path_2).unwrap(); | 
 |     assert!(tmp_file_path_2.exists(), "Test file 2 hasn't been created"); | 
 |  | 
 |     let tmp_path = TempPath::from_path(&tmp_file_path_1); | 
 |     assert!( | 
 |         tmp_file_path_1.exists(), | 
 |         "Test file has been deleted before dropping TempPath" | 
 |     ); | 
 |  | 
 |     drop(tmp_path); | 
 |     assert!( | 
 |         !tmp_file_path_1.exists(), | 
 |         "Test file exists after dropping TempPath" | 
 |     ); | 
 |     assert!( | 
 |         tmp_file_path_2.exists(), | 
 |         "Test file 2 has been deleted before dropping TempDir" | 
 |     ); | 
 | } | 
 |  | 
 | #[test] | 
 | #[allow(unreachable_code)] | 
 | fn temp_path_from_argument_types() { | 
 |     // This just has to compile | 
 |     return; | 
 |  | 
 |     TempPath::from_path(""); | 
 |     TempPath::from_path(String::new()); | 
 |     TempPath::from_path(OsStr::new("")); | 
 |     TempPath::from_path(OsString::new()); | 
 |     TempPath::from_path(Path::new("")); | 
 |     TempPath::from_path(PathBuf::new()); | 
 |     TempPath::from_path(PathBuf::new().into_boxed_path()); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_write_after_close() { | 
 |     let path = NamedTempFile::new().unwrap().into_temp_path(); | 
 |     File::create(path).unwrap().write_all(b"test").unwrap(); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_change_dir() { | 
 |     std::env::set_current_dir(env::temp_dir()).unwrap(); | 
 |     let tmpfile = NamedTempFile::new_in(".").unwrap(); | 
 |     let path = std::env::current_dir().unwrap().join(tmpfile.path()); | 
 |     std::env::set_current_dir("/").unwrap(); | 
 |     drop(tmpfile); | 
 |     assert!(!exists(path)) | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_into_parts() { | 
 |     let mut file = NamedTempFile::new().unwrap(); | 
 |     write!(file, "abcd").expect("write failed"); | 
 |  | 
 |     let (mut file, temp_path) = file.into_parts(); | 
 |  | 
 |     let path = temp_path.to_path_buf(); | 
 |  | 
 |     assert!(path.exists()); | 
 |     drop(temp_path); | 
 |     assert!(!path.exists()); | 
 |  | 
 |     write!(file, "efgh").expect("write failed"); | 
 |  | 
 |     file.seek(SeekFrom::Start(0)).unwrap(); | 
 |     let mut buf = String::new(); | 
 |     file.read_to_string(&mut buf).unwrap(); | 
 |     assert_eq!("abcdefgh", buf); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_from_parts() { | 
 |     let mut file = NamedTempFile::new().unwrap(); | 
 |     write!(file, "abcd").expect("write failed"); | 
 |  | 
 |     let (file, temp_path) = file.into_parts(); | 
 |  | 
 |     let file = NamedTempFile::from_parts(file, temp_path); | 
 |  | 
 |     assert!(file.path().exists()); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_keep() { | 
 |     let mut tmpfile = NamedTempFile::new().unwrap(); | 
 |     write!(tmpfile, "abcde").unwrap(); | 
 |     let (mut f, temp_path) = tmpfile.into_parts(); | 
 |     let path; | 
 |     { | 
 |         assert!(exists(&temp_path)); | 
 |         path = temp_path.keep().unwrap(); | 
 |         assert!(exists(&path)); | 
 |  | 
 |         // Check original file | 
 |         f.seek(SeekFrom::Start(0)).unwrap(); | 
 |         let mut buf = String::new(); | 
 |         f.read_to_string(&mut buf).unwrap(); | 
 |         assert_eq!("abcde", buf); | 
 |     } | 
 |  | 
 |     { | 
 |         // Try opening it again. | 
 |         let mut f = File::open(&path).unwrap(); | 
 |         f.seek(SeekFrom::Start(0)).unwrap(); | 
 |         let mut buf = String::new(); | 
 |         f.read_to_string(&mut buf).unwrap(); | 
 |         assert_eq!("abcde", buf); | 
 |     } | 
 |     std::fs::remove_file(&path).unwrap(); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_builder_keep() { | 
 |     let mut tmpfile = Builder::new().keep(true).tempfile().unwrap(); | 
 |     write!(tmpfile, "abcde").unwrap(); | 
 |     let path = tmpfile.path().to_owned(); | 
 |     drop(tmpfile); | 
 |  | 
 |     { | 
 |         // Try opening it again. | 
 |         let mut f = File::open(&path).unwrap(); | 
 |         let mut buf = String::new(); | 
 |         f.read_to_string(&mut buf).unwrap(); | 
 |         assert_eq!("abcde", buf); | 
 |     } | 
 |     std::fs::remove_file(&path).unwrap(); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_make() { | 
 |     let tmpfile = Builder::new().make(|path| File::create(path)).unwrap(); | 
 |  | 
 |     assert!(tmpfile.path().is_file()); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_make_in() { | 
 |     let tmp_dir = tempdir().unwrap(); | 
 |  | 
 |     let tmpfile = Builder::new() | 
 |         .make_in(tmp_dir.path(), |path| File::create(path)) | 
 |         .unwrap(); | 
 |  | 
 |     assert!(tmpfile.path().is_file()); | 
 |     assert_eq!(tmpfile.path().parent(), Some(tmp_dir.path())); | 
 | } | 
 |  | 
 | #[test] | 
 | fn test_make_fnmut() { | 
 |     let mut count = 0; | 
 |  | 
 |     // Show that an FnMut can be used. | 
 |     let tmpfile = Builder::new() | 
 |         .make(|path| { | 
 |             count += 1; | 
 |             File::create(path) | 
 |         }) | 
 |         .unwrap(); | 
 |  | 
 |     assert!(tmpfile.path().is_file()); | 
 | } | 
 |  | 
 | #[cfg(unix)] | 
 | #[test] | 
 | fn test_make_uds() { | 
 |     use std::os::unix::net::UnixListener; | 
 |  | 
 |     let temp_sock = Builder::new() | 
 |         .prefix("tmp") | 
 |         .suffix(".sock") | 
 |         .rand_bytes(12) | 
 |         .make(|path| UnixListener::bind(path)) | 
 |         .unwrap(); | 
 |  | 
 |     assert!(temp_sock.path().exists()); | 
 | } | 
 |  | 
 | #[cfg(unix)] | 
 | #[test] | 
 | fn test_make_uds_conflict() { | 
 |     use std::os::unix::net::UnixListener; | 
 |     use std::sync::atomic::{AtomicUsize, Ordering}; | 
 |     use std::sync::Arc; | 
 |  | 
 |     // Check that retries happen correctly by racing N different threads. | 
 |  | 
 |     const NTHREADS: usize = 20; | 
 |  | 
 |     // The number of times our callback was called. | 
 |     let tries = Arc::new(AtomicUsize::new(0)); | 
 |  | 
 |     let mut threads = Vec::with_capacity(NTHREADS); | 
 |  | 
 |     for _ in 0..NTHREADS { | 
 |         let tries = tries.clone(); | 
 |         threads.push(std::thread::spawn(move || { | 
 |             // Ensure that every thread uses the same seed so we are guaranteed | 
 |             // to retry. Note that fastrand seeds are thread-local. | 
 |             fastrand::seed(42); | 
 |  | 
 |             Builder::new() | 
 |                 .prefix("tmp") | 
 |                 .suffix(".sock") | 
 |                 .rand_bytes(12) | 
 |                 .make(|path| { | 
 |                     tries.fetch_add(1, Ordering::Relaxed); | 
 |                     UnixListener::bind(path) | 
 |                 }) | 
 |         })); | 
 |     } | 
 |  | 
 |     // Join all threads, but don't drop the temp file yet. Otherwise, we won't | 
 |     // get a deterministic number of `tries`. | 
 |     let sockets: Vec<_> = threads | 
 |         .into_iter() | 
 |         .map(|thread| thread.join().unwrap().unwrap()) | 
 |         .collect(); | 
 |  | 
 |     // Number of tries is exactly equal to (n*(n+1))/2. | 
 |     assert_eq!( | 
 |         tries.load(Ordering::Relaxed), | 
 |         (NTHREADS * (NTHREADS + 1)) / 2 | 
 |     ); | 
 |  | 
 |     for socket in sockets { | 
 |         assert!(socket.path().exists()); | 
 |     } | 
 | } | 
 |  | 
 | // Issue #224. | 
 | #[test] | 
 | fn test_overly_generic_bounds() { | 
 |     pub struct Foo<T>(T); | 
 |  | 
 |     impl<T> Foo<T> | 
 |     where | 
 |         T: Sync + Send + 'static, | 
 |         for<'a> &'a T: Write + Read, | 
 |     { | 
 |         pub fn new(foo: T) -> Self { | 
 |             Self(foo) | 
 |         } | 
 |     } | 
 |  | 
 |     // Don't really need to run this. Only care if it compiles. | 
 |     if let Ok(file) = File::open("i_do_not_exist") { | 
 |         let mut f; | 
 |         let _x = { | 
 |             f = Foo::new(file); | 
 |             &mut f | 
 |         }; | 
 |     } | 
 | } |