2
0

tempfile.rs 2.0 KB

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