| 1 | #![deny (rust_2018_idioms)] |
| 2 | |
| 3 | use std::fs; |
| 4 | use std::io::{Read, Seek, SeekFrom, Write}; |
| 5 | #[cfg (target_os = "linux" )] |
| 6 | use std::{ |
| 7 | sync::mpsc::{sync_channel, TryRecvError}, |
| 8 | thread, |
| 9 | }; |
| 10 | |
| 11 | #[test] |
| 12 | fn test_basic() { |
| 13 | let mut tmpfile = tempfile::tempfile().unwrap(); |
| 14 | write!(tmpfile, "abcde" ).unwrap(); |
| 15 | tmpfile.seek(SeekFrom::Start(0)).unwrap(); |
| 16 | let mut buf = String::new(); |
| 17 | tmpfile.read_to_string(&mut buf).unwrap(); |
| 18 | assert_eq!("abcde" , buf); |
| 19 | } |
| 20 | |
| 21 | #[test] |
| 22 | fn test_cleanup() { |
| 23 | let tmpdir = tempfile::tempdir().unwrap(); |
| 24 | { |
| 25 | let mut tmpfile = tempfile::tempfile_in(&tmpdir).unwrap(); |
| 26 | write!(tmpfile, "abcde" ).unwrap(); |
| 27 | } |
| 28 | let num_files = fs::read_dir(&tmpdir).unwrap().count(); |
| 29 | assert!(num_files == 0); |
| 30 | } |
| 31 | |
| 32 | // Only run this test on Linux. MacOS doesn't like us creating so many files, apparently. |
| 33 | #[cfg (target_os = "linux" )] |
| 34 | #[test] |
| 35 | fn test_pathological_cleaner() { |
| 36 | let tmpdir = tempfile::tempdir().unwrap(); |
| 37 | let (tx, rx) = sync_channel(0); |
| 38 | let cleaner_thread = thread::spawn(move || { |
| 39 | let tmp_path = rx.recv().unwrap(); |
| 40 | while rx.try_recv() == Err(TryRecvError::Empty) { |
| 41 | let files = fs::read_dir(&tmp_path).unwrap(); |
| 42 | for f in files { |
| 43 | // skip errors |
| 44 | if f.is_err() { |
| 45 | continue; |
| 46 | } |
| 47 | let f = f.unwrap(); |
| 48 | let _ = fs::remove_file(f.path()); |
| 49 | } |
| 50 | } |
| 51 | }); |
| 52 | |
| 53 | // block until cleaner_thread makes progress |
| 54 | tx.send(tmpdir.path().to_owned()).unwrap(); |
| 55 | // need 40-400 iterations to encounter race with cleaner on original system |
| 56 | for _ in 0..10000 { |
| 57 | let mut tmpfile = tempfile::tempfile_in(&tmpdir).unwrap(); |
| 58 | write!(tmpfile, "abcde" ).unwrap(); |
| 59 | tmpfile.seek(SeekFrom::Start(0)).unwrap(); |
| 60 | let mut buf = String::new(); |
| 61 | tmpfile.read_to_string(&mut buf).unwrap(); |
| 62 | assert_eq!("abcde" , buf); |
| 63 | } |
| 64 | |
| 65 | // close the channel to make cleaner_thread exit |
| 66 | drop(tx); |
| 67 | cleaner_thread.join().expect("The cleaner thread failed" ); |
| 68 | } |
| 69 | |