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 | |