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 #[test]
test_pathological_cleaner()30 fn test_pathological_cleaner() {
31 let tmpdir = tempfile::tempdir().unwrap();
32 let (tx, rx) = sync_channel(0);
33 let cleaner_thread = thread::spawn(move || {
34 let tmp_path = rx.recv().unwrap();
35 while rx.try_recv() == Err(TryRecvError::Empty) {
36 let files = fs::read_dir(&tmp_path).unwrap();
37 for f in files {
38 // skip errors
39 if f.is_err() {
40 continue;
41 }
42 let f = f.unwrap();
43 let _ = fs::remove_file(f.path());
44 }
45 }
46 });
47
48 // block until cleaner_thread makes progress
49 tx.send(tmpdir.path().to_owned()).unwrap();
50 // need 40-400 iterations to encounter race with cleaner on original system
51 for _ in 0..10000 {
52 let mut tmpfile = tempfile::tempfile_in(&tmpdir).unwrap();
53 write!(tmpfile, "abcde").unwrap();
54 tmpfile.seek(SeekFrom::Start(0)).unwrap();
55 let mut buf = String::new();
56 tmpfile.read_to_string(&mut buf).unwrap();
57 assert_eq!("abcde", buf);
58 }
59
60 // close the channel to make cleaner_thread exit
61 drop(tx);
62 cleaner_thread.join().expect("The cleaner thread failed");
63 }
64