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