diff options
Diffstat (limited to 'vendor/tempfile/tests')
-rw-r--r-- | vendor/tempfile/tests/namedtempfile.rs | 473 | ||||
-rw-r--r-- | vendor/tempfile/tests/spooled.rs | 307 | ||||
-rw-r--r-- | vendor/tempfile/tests/tempdir.rs | 176 | ||||
-rw-r--r-- | vendor/tempfile/tests/tempfile.rs | 68 |
4 files changed, 1024 insertions, 0 deletions
diff --git a/vendor/tempfile/tests/namedtempfile.rs b/vendor/tempfile/tests/namedtempfile.rs new file mode 100644 index 0000000..4b940b6 --- /dev/null +++ b/vendor/tempfile/tests/namedtempfile.rs @@ -0,0 +1,473 @@ +#![deny(rust_2018_idioms)] + +use std::env; +use std::ffi::{OsStr, OsString}; +use std::fs::File; +use std::io::{Read, Seek, SeekFrom, Write}; +use std::path::{Path, PathBuf}; +use tempfile::{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() { + env::set_current_dir(env::temp_dir()).unwrap(); + let tmpfile = NamedTempFile::new_in(".").unwrap(); + let path = env::current_dir().unwrap().join(tmpfile.path()); + 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_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 + }; + } +} diff --git a/vendor/tempfile/tests/spooled.rs b/vendor/tempfile/tests/spooled.rs new file mode 100644 index 0000000..a3bcc03 --- /dev/null +++ b/vendor/tempfile/tests/spooled.rs @@ -0,0 +1,307 @@ +#![deny(rust_2018_idioms)] + +use std::io::{Read, Seek, SeekFrom, Write}; + +use tempfile::{spooled_tempfile, SpooledTempFile}; + +#[test] +fn test_automatic_rollover() { + let mut t = spooled_tempfile(10); + let mut buf = Vec::new(); + + assert!(!t.is_rolled()); + assert_eq!(t.stream_position().unwrap(), 0); + assert_eq!(t.read_to_end(&mut buf).unwrap(), 0); + assert_eq!(buf.as_slice(), b""); + buf.clear(); + + assert_eq!(t.write(b"abcde").unwrap(), 5); + + assert!(!t.is_rolled()); + assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); + assert_eq!(t.read_to_end(&mut buf).unwrap(), 5); + assert_eq!(buf.as_slice(), b"abcde"); + + assert_eq!(t.write(b"fghijklmno").unwrap(), 10); + + assert_eq!(t.stream_position().unwrap(), 15); + assert!(t.is_rolled()); +} + +#[test] +fn test_explicit_rollover() { + let mut t = SpooledTempFile::new(100); + assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26); + assert_eq!(t.stream_position().unwrap(), 26); + assert!(!t.is_rolled()); + + // roll over explicitly + assert!(t.roll().is_ok()); + assert!(t.is_rolled()); + assert_eq!(t.stream_position().unwrap(), 26); + + let mut buf = Vec::new(); + assert_eq!(t.read_to_end(&mut buf).unwrap(), 0); + assert_eq!(buf.as_slice(), b""); + buf.clear(); + + assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); + assert_eq!(t.read_to_end(&mut buf).unwrap(), 26); + assert_eq!(buf.as_slice(), b"abcdefghijklmnopqrstuvwxyz"); + assert_eq!(t.stream_position().unwrap(), 26); +} + +// called by test_seek_{buffer, file} +// assumes t is empty and offset is 0 to start +fn test_seek(t: &mut SpooledTempFile) { + assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26); + + assert_eq!(t.stream_position().unwrap(), 26); // tell() + assert_eq!(t.seek(SeekFrom::Current(-1)).unwrap(), 25); + assert_eq!(t.seek(SeekFrom::Current(1)).unwrap(), 26); + assert_eq!(t.seek(SeekFrom::Current(1)).unwrap(), 27); + assert_eq!(t.seek(SeekFrom::Current(-27)).unwrap(), 0); + assert!(t.seek(SeekFrom::Current(-1)).is_err()); + assert!(t.seek(SeekFrom::Current(-1245)).is_err()); + + assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); + assert_eq!(t.seek(SeekFrom::Start(1)).unwrap(), 1); + assert_eq!(t.seek(SeekFrom::Start(26)).unwrap(), 26); + assert_eq!(t.seek(SeekFrom::Start(27)).unwrap(), 27); + // // these are build errors + // assert!(t.seek(SeekFrom::Start(-1)).is_err()); + // assert!(t.seek(SeekFrom::Start(-1000)).is_err()); + + assert_eq!(t.seek(SeekFrom::End(0)).unwrap(), 26); + assert_eq!(t.seek(SeekFrom::End(-1)).unwrap(), 25); + assert_eq!(t.seek(SeekFrom::End(-26)).unwrap(), 0); + assert!(t.seek(SeekFrom::End(-27)).is_err()); + assert!(t.seek(SeekFrom::End(-99)).is_err()); + assert_eq!(t.seek(SeekFrom::End(1)).unwrap(), 27); + assert_eq!(t.seek(SeekFrom::End(1)).unwrap(), 27); +} + +#[test] +fn test_seek_buffer() { + let mut t = spooled_tempfile(100); + test_seek(&mut t); +} + +#[test] +fn test_seek_file() { + let mut t = SpooledTempFile::new(10); + test_seek(&mut t); +} + +fn test_seek_read(t: &mut SpooledTempFile) { + assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26); + + let mut buf = Vec::new(); + + // we're at the end + assert_eq!(t.read_to_end(&mut buf).unwrap(), 0); + assert_eq!(buf.as_slice(), b""); + buf.clear(); + + // seek to start, read whole thing + assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); + assert_eq!(t.read_to_end(&mut buf).unwrap(), 26); + assert_eq!(buf.as_slice(), b"abcdefghijklmnopqrstuvwxyz"); + buf.clear(); + + // now we're at the end again + assert_eq!(t.stream_position().unwrap(), 26); // tell() + assert_eq!(t.read_to_end(&mut buf).unwrap(), 0); + assert_eq!(buf.as_slice(), b""); + buf.clear(); + + // seek to somewhere in the middle, read a bit + assert_eq!(t.seek(SeekFrom::Start(5)).unwrap(), 5); + let mut buf = [0; 5]; + assert!(t.read_exact(&mut buf).is_ok()); + assert_eq!(buf, *b"fghij"); + + // read again from current spot + assert_eq!(t.stream_position().unwrap(), 10); // tell() + assert!(t.read_exact(&mut buf).is_ok()); + assert_eq!(buf, *b"klmno"); + + let mut buf = [0; 15]; + // partial read + assert_eq!(t.read(&mut buf).unwrap(), 11); + assert_eq!(buf[0..11], *b"pqrstuvwxyz"); + + // try to read off the end: UnexpectedEof + assert!(t.read_exact(&mut buf).is_err()); +} + +#[test] +fn test_seek_read_buffer() { + let mut t = spooled_tempfile(100); + test_seek_read(&mut t); +} + +#[test] +fn test_seek_read_file() { + let mut t = SpooledTempFile::new(10); + test_seek_read(&mut t); +} + +fn test_overwrite_middle(t: &mut SpooledTempFile) { + assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26); + + assert_eq!(t.seek(SeekFrom::Start(10)).unwrap(), 10); + assert_eq!(t.write(b"0123456789").unwrap(), 10); + assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); + + let mut buf = Vec::new(); + assert_eq!(t.read_to_end(&mut buf).unwrap(), 26); + assert_eq!(buf.as_slice(), b"abcdefghij0123456789uvwxyz"); +} + +#[test] +fn test_overwrite_middle_of_buffer() { + let mut t = spooled_tempfile(100); + test_overwrite_middle(&mut t); +} + +#[test] +fn test_overwrite_middle_of_file() { + let mut t = SpooledTempFile::new(10); + test_overwrite_middle(&mut t); +} + +#[test] +fn test_overwrite_and_extend_buffer() { + let mut t = spooled_tempfile(100); + assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26); + assert_eq!(t.seek(SeekFrom::End(-5)).unwrap(), 21); + assert_eq!(t.write(b"0123456789").unwrap(), 10); + assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); + let mut buf = Vec::new(); + assert_eq!(t.read_to_end(&mut buf).unwrap(), 31); + assert_eq!(buf.as_slice(), b"abcdefghijklmnopqrstu0123456789"); + assert!(!t.is_rolled()); +} + +#[test] +fn test_overwrite_and_extend_rollover() { + let mut t = SpooledTempFile::new(20); + assert_eq!(t.write(b"abcdefghijklmno").unwrap(), 15); + assert!(!t.is_rolled()); + assert_eq!(t.seek(SeekFrom::End(-5)).unwrap(), 10); + assert_eq!(t.stream_position().unwrap(), 10); // tell() + assert!(!t.is_rolled()); + assert_eq!(t.write(b"0123456789)!@#$%^&*(").unwrap(), 20); + assert!(t.is_rolled()); + assert_eq!(t.stream_position().unwrap(), 30); // tell() + let mut buf = Vec::new(); + assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); + assert_eq!(t.read_to_end(&mut buf).unwrap(), 30); + assert_eq!(buf.as_slice(), b"abcdefghij0123456789)!@#$%^&*("); +} + +fn test_sparse(t: &mut SpooledTempFile) { + assert_eq!(t.write(b"abcde").unwrap(), 5); + assert_eq!(t.seek(SeekFrom::Current(5)).unwrap(), 10); + assert_eq!(t.write(b"klmno").unwrap(), 5); + assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); + let mut buf = Vec::new(); + assert_eq!(t.read_to_end(&mut buf).unwrap(), 15); + assert_eq!(buf.as_slice(), b"abcde\0\0\0\0\0klmno"); +} + +#[test] +fn test_sparse_buffer() { + let mut t = spooled_tempfile(100); + test_sparse(&mut t); +} + +#[test] +fn test_sparse_file() { + let mut t = SpooledTempFile::new(1); + test_sparse(&mut t); +} + +#[test] +fn test_sparse_write_rollover() { + let mut t = spooled_tempfile(10); + assert_eq!(t.write(b"abcde").unwrap(), 5); + assert!(!t.is_rolled()); + assert_eq!(t.seek(SeekFrom::Current(5)).unwrap(), 10); + assert!(!t.is_rolled()); + assert_eq!(t.write(b"klmno").unwrap(), 5); + assert!(t.is_rolled()); + assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); + let mut buf = Vec::new(); + assert_eq!(t.read_to_end(&mut buf).unwrap(), 15); + assert_eq!(buf.as_slice(), b"abcde\0\0\0\0\0klmno"); +} + +fn test_set_len(t: &mut SpooledTempFile) { + let mut buf: Vec<u8> = Vec::new(); + + assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26); + + // truncate to 10 bytes + assert!(t.set_len(10).is_ok()); + + // position should not have moved + assert_eq!(t.stream_position().unwrap(), 26); // tell() + + assert_eq!(t.read_to_end(&mut buf).unwrap(), 0); + assert_eq!(buf.as_slice(), b""); + assert_eq!(t.stream_position().unwrap(), 26); // tell() + buf.clear(); + + // read whole thing + assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); + assert_eq!(t.read_to_end(&mut buf).unwrap(), 10); + assert_eq!(buf.as_slice(), b"abcdefghij"); + buf.clear(); + + // set_len to expand beyond the end + assert!(t.set_len(40).is_ok()); + assert_eq!(t.stream_position().unwrap(), 10); // tell() + assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); + assert_eq!(t.read_to_end(&mut buf).unwrap(), 40); + assert_eq!( + buf.as_slice(), + &b"abcdefghij\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"[..] + ); +} + +#[test] +fn test_set_len_buffer() { + let mut t = spooled_tempfile(100); + test_set_len(&mut t); +} + +#[test] +fn test_set_len_file() { + let mut t = spooled_tempfile(100); + test_set_len(&mut t); +} + +#[test] +fn test_set_len_rollover() { + let mut buf: Vec<u8> = Vec::new(); + + let mut t = spooled_tempfile(10); + assert_eq!(t.write(b"abcde").unwrap(), 5); + assert!(!t.is_rolled()); + assert_eq!(t.stream_position().unwrap(), 5); // tell() + + assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); + assert_eq!(t.read_to_end(&mut buf).unwrap(), 5); + assert_eq!(buf.as_slice(), b"abcde"); + assert_eq!(t.stream_position().unwrap(), 5); // tell() + buf.clear(); + + assert!(t.set_len(20).is_ok()); + assert!(t.is_rolled()); + assert_eq!(t.stream_position().unwrap(), 5); // tell() + assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); + assert_eq!(t.read_to_end(&mut buf).unwrap(), 20); + assert_eq!(buf.as_slice(), b"abcde\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); +} diff --git a/vendor/tempfile/tests/tempdir.rs b/vendor/tempfile/tests/tempdir.rs new file mode 100644 index 0000000..8ca7984 --- /dev/null +++ b/vendor/tempfile/tests/tempdir.rs @@ -0,0 +1,176 @@ +// 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}; + +fn test_tempdir() { + let path = { + let p = Builder::new().prefix("foobar").tempdir_in(".").unwrap(); + let p = p.path(); + assert!(p.to_str().unwrap().contains("foobar")); + p.to_path_buf() + }; + assert!(!path.exists()); +} + +fn test_prefix() { + let tmpfile = TempDir::with_prefix_in("prefix", ".").unwrap(); + let name = tmpfile.path().file_name().unwrap().to_str().unwrap(); + assert!(name.starts_with("prefix")); +} + +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 = TempDir::new().unwrap(); + 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 = TempDir::new().unwrap(); + 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 || TempDir::new().unwrap(); + + let tmp = thread::spawn(f).join().unwrap(); + path = tmp.path().to_path_buf(); + assert!(path.exists()); + } + assert!(!path.exists()); + + let path; + { + let tmp = TempDir::new().unwrap(); + path = tmp.into_path(); + } + assert!(path.exists()); + fs::remove_dir_all(&path).unwrap(); + assert!(!path.exists()); +} + +fn test_rm_tempdir_close() { + let (tx, rx) = channel(); + let f = move || { + let tmp = TempDir::new().unwrap(); + tx.send(tmp.path().to_path_buf()).unwrap(); + tmp.close().unwrap(); + panic!("panic when unwinding past `tmp`"); + }; + let _ = thread::spawn(f).join(); + let path = rx.recv().unwrap(); + assert!(!path.exists()); + + let tmp = TempDir::new().unwrap(); + let path = tmp.path().to_path_buf(); + let f = move || { + let tmp = tmp; + tmp.close().unwrap(); + panic!("panic when unwinding past `tmp`"); + }; + let _ = thread::spawn(f).join(); + assert!(!path.exists()); + + let path; + { + let f = move || TempDir::new().unwrap(); + + let tmp = thread::spawn(f).join().unwrap(); + path = tmp.path().to_path_buf(); + assert!(path.exists()); + tmp.close().unwrap(); + } + assert!(!path.exists()); + + let path; + { + let tmp = TempDir::new().unwrap(); + path = tmp.into_path(); + } + assert!(path.exists()); + fs::remove_dir_all(&path).unwrap(); + assert!(!path.exists()); +} + +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 + fs::remove_dir(tmpdir.path()).unwrap(); + // 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 = TempDir::new().unwrap(); + assert!(env::set_current_dir(tmpdir.path()).is_ok()); + + f(); +} + +fn pass_as_asref_path() { + let tempdir = TempDir::new().unwrap(); + 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_prefix); + in_tmpdir(test_customnamed); + in_tmpdir(test_rm_tempdir); + in_tmpdir(test_rm_tempdir_close); + in_tmpdir(dont_double_panic); + in_tmpdir(pass_as_asref_path); +} diff --git a/vendor/tempfile/tests/tempfile.rs b/vendor/tempfile/tests/tempfile.rs new file mode 100644 index 0000000..c2f6844 --- /dev/null +++ b/vendor/tempfile/tests/tempfile.rs @@ -0,0 +1,68 @@ +#![deny(rust_2018_idioms)] + +use std::fs; +use std::io::{Read, Seek, SeekFrom, Write}; +#[cfg(target_os = "linux")] +use std::{ + sync::mpsc::{sync_channel, TryRecvError}, + thread, +}; + +#[test] +fn test_basic() { + let mut tmpfile = tempfile::tempfile().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_cleanup() { + let tmpdir = tempfile::tempdir().unwrap(); + { + let mut tmpfile = tempfile::tempfile_in(&tmpdir).unwrap(); + write!(tmpfile, "abcde").unwrap(); + } + let num_files = fs::read_dir(&tmpdir).unwrap().count(); + assert!(num_files == 0); +} + +// Only run this test on Linux. MacOS doesn't like us creating so many files, apparently. +#[cfg(target_os = "linux")] +#[test] +fn test_pathological_cleaner() { + let tmpdir = tempfile::tempdir().unwrap(); + let (tx, rx) = sync_channel(0); + let cleaner_thread = thread::spawn(move || { + let tmp_path = rx.recv().unwrap(); + while rx.try_recv() == Err(TryRecvError::Empty) { + let files = fs::read_dir(&tmp_path).unwrap(); + for f in files { + // skip errors + if f.is_err() { + continue; + } + let f = f.unwrap(); + let _ = fs::remove_file(f.path()); + } + } + }); + + // block until cleaner_thread makes progress + tx.send(tmpdir.path().to_owned()).unwrap(); + // need 40-400 iterations to encounter race with cleaner on original system + for _ in 0..10000 { + let mut tmpfile = tempfile::tempfile_in(&tmpdir).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); + } + + // close the channel to make cleaner_thread exit + drop(tx); + cleaner_thread.join().expect("The cleaner thread failed"); +} |