1 #![deny(rust_2018_idioms)]
4 use std
::ffi
::{OsStr, OsString}
;
6 use std
::io
::{Read, Seek, SeekFrom, Write}
;
7 use std
::path
::{Path, PathBuf}
;
8 use tempfile
::{tempdir, Builder, NamedTempFile, TempPath}
;
10 fn exists
<P
: AsRef
<Path
>>(path
: P
) -> bool
{
11 std
::fs
::metadata(path
.as_ref()).is_ok()
16 let tmpfile
= NamedTempFile
::with_prefix("prefix").unwrap();
17 let name
= tmpfile
.path().file_name().unwrap().to_str().unwrap();
18 assert
!(name
.starts_with("prefix"));
23 let mut tmpfile
= NamedTempFile
::new().unwrap();
24 write
!(tmpfile
, "abcde").unwrap();
25 tmpfile
.seek(SeekFrom
::Start(0)).unwrap();
26 let mut buf
= String
::new();
27 tmpfile
.read_to_string(&mut buf
).unwrap();
28 assert_eq
!("abcde", buf
);
33 let tmpfile
= NamedTempFile
::new().unwrap();
34 let path
= tmpfile
.path().to_path_buf();
35 assert
!(exists(&path
));
37 assert
!(!exists(&path
));
42 let mut tmpfile
= NamedTempFile
::new().unwrap();
43 let old_path
= tmpfile
.path().to_path_buf();
44 let persist_path
= env
::temp_dir().join("persisted_temporary_file");
45 write
!(tmpfile
, "abcde").unwrap();
47 assert
!(exists(&old_path
));
48 let mut f
= tmpfile
.persist(&persist_path
).unwrap();
49 assert
!(!exists(&old_path
));
51 // Check original file
52 f
.seek(SeekFrom
::Start(0)).unwrap();
53 let mut buf
= String
::new();
54 f
.read_to_string(&mut buf
).unwrap();
55 assert_eq
!("abcde", buf
);
59 // Try opening it at the new path.
60 let mut f
= File
::open(&persist_path
).unwrap();
61 f
.seek(SeekFrom
::Start(0)).unwrap();
62 let mut buf
= String
::new();
63 f
.read_to_string(&mut buf
).unwrap();
64 assert_eq
!("abcde", buf
);
66 std
::fs
::remove_file(&persist_path
).unwrap();
70 fn test_persist_noclobber() {
71 let mut tmpfile
= NamedTempFile
::new().unwrap();
72 let old_path
= tmpfile
.path().to_path_buf();
73 let persist_target
= NamedTempFile
::new().unwrap();
74 let persist_path
= persist_target
.path().to_path_buf();
75 write
!(tmpfile
, "abcde").unwrap();
76 assert
!(exists(&old_path
));
78 tmpfile
= tmpfile
.persist_noclobber(&persist_path
).unwrap_err().into();
79 assert
!(exists(&old_path
));
80 std
::fs
::remove_file(&persist_path
).unwrap();
83 tmpfile
.persist_noclobber(&persist_path
).unwrap();
84 // Try opening it at the new path.
85 let mut f
= File
::open(&persist_path
).unwrap();
86 f
.seek(SeekFrom
::Start(0)).unwrap();
87 let mut buf
= String
::new();
88 f
.read_to_string(&mut buf
).unwrap();
89 assert_eq
!("abcde", buf
);
90 std
::fs
::remove_file(&persist_path
).unwrap();
94 fn test_customnamed() {
95 let tmpfile
= Builder
::new()
101 let name
= tmpfile
.path().file_name().unwrap().to_str().unwrap();
102 assert
!(name
.starts_with("tmp"));
103 assert
!(name
.ends_with(".rs"));
104 assert_eq
!(name
.len(), 18);
109 let mut tmpfile
= Builder
::new().append(true).tempfile().unwrap();
110 tmpfile
.write_all(b
"a").unwrap();
111 tmpfile
.seek(SeekFrom
::Start(0)).unwrap();
112 tmpfile
.write_all(b
"b").unwrap();
114 tmpfile
.seek(SeekFrom
::Start(0)).unwrap();
115 let mut buf
= vec
![0u8; 1];
116 tmpfile
.read_exact(&mut buf
).unwrap();
117 assert_eq
!(buf
, b
"a");
122 let source
= NamedTempFile
::new().unwrap();
123 let mut first
= source
.reopen().unwrap();
124 let mut second
= source
.reopen().unwrap();
127 write
!(first
, "abcde").expect("write failed");
128 let mut buf
= String
::new();
129 second
.read_to_string(&mut buf
).unwrap();
130 assert_eq
!("abcde", buf
);
134 fn test_into_file() {
135 let mut file
= NamedTempFile
::new().unwrap();
136 let path
= file
.path().to_owned();
137 write
!(file
, "abcde").expect("write failed");
139 assert
!(path
.exists());
140 let mut file
= file
.into_file();
141 assert
!(!path
.exists());
143 file
.seek(SeekFrom
::Start(0)).unwrap();
144 let mut buf
= String
::new();
145 file
.read_to_string(&mut buf
).unwrap();
146 assert_eq
!("abcde", buf
);
151 let tmpfile
= NamedTempFile
::new().unwrap();
152 (&tmpfile
).write_all(b
"abcde").unwrap();
153 (&tmpfile
).seek(SeekFrom
::Start(0)).unwrap();
154 let mut buf
= String
::new();
155 (&tmpfile
).read_to_string(&mut buf
).unwrap();
156 assert_eq
!("abcde", buf
);
161 let mut tmpfile
= NamedTempFile
::new().unwrap();
162 write
!(tmpfile
, "abcde").unwrap();
164 let path
= tmpfile
.into_temp_path();
165 assert
!(path
.is_file());
169 fn test_temppath_persist() {
170 let mut tmpfile
= NamedTempFile
::new().unwrap();
171 write
!(tmpfile
, "abcde").unwrap();
173 let tmppath
= tmpfile
.into_temp_path();
175 let old_path
= tmppath
.to_path_buf();
176 let persist_path
= env
::temp_dir().join("persisted_temppath_file");
179 assert
!(exists(&old_path
));
180 tmppath
.persist(&persist_path
).unwrap();
181 assert
!(!exists(&old_path
));
185 // Try opening it at the new path.
186 let mut f
= File
::open(&persist_path
).unwrap();
187 f
.seek(SeekFrom
::Start(0)).unwrap();
188 let mut buf
= String
::new();
189 f
.read_to_string(&mut buf
).unwrap();
190 assert_eq
!("abcde", buf
);
193 std
::fs
::remove_file(&persist_path
).unwrap();
197 fn test_temppath_persist_noclobber() {
198 let mut tmpfile
= NamedTempFile
::new().unwrap();
199 write
!(tmpfile
, "abcde").unwrap();
201 let mut tmppath
= tmpfile
.into_temp_path();
203 let old_path
= tmppath
.to_path_buf();
204 let persist_target
= NamedTempFile
::new().unwrap();
205 let persist_path
= persist_target
.path().to_path_buf();
207 assert
!(exists(&old_path
));
210 tmppath
= tmppath
.persist_noclobber(&persist_path
).unwrap_err().into();
211 assert
!(exists(&old_path
));
212 std
::fs
::remove_file(&persist_path
).unwrap();
213 drop(persist_target
);
216 tmppath
.persist_noclobber(&persist_path
).unwrap();
218 // Try opening it at the new path.
219 let mut f
= File
::open(&persist_path
).unwrap();
220 f
.seek(SeekFrom
::Start(0)).unwrap();
221 let mut buf
= String
::new();
222 f
.read_to_string(&mut buf
).unwrap();
223 assert_eq
!("abcde", buf
);
224 std
::fs
::remove_file(&persist_path
).unwrap();
228 fn temp_path_from_existing() {
229 let tmp_dir
= tempdir().unwrap();
230 let tmp_file_path_1
= tmp_dir
.path().join("testfile1");
231 let tmp_file_path_2
= tmp_dir
.path().join("testfile2");
233 File
::create(&tmp_file_path_1
).unwrap();
234 assert
!(tmp_file_path_1
.exists(), "Test file 1 hasn't been created");
236 File
::create(&tmp_file_path_2
).unwrap();
237 assert
!(tmp_file_path_2
.exists(), "Test file 2 hasn't been created");
239 let tmp_path
= TempPath
::from_path(&tmp_file_path_1
);
241 tmp_file_path_1
.exists(),
242 "Test file has been deleted before dropping TempPath"
247 !tmp_file_path_1
.exists(),
248 "Test file exists after dropping TempPath"
251 tmp_file_path_2
.exists(),
252 "Test file 2 has been deleted before dropping TempDir"
257 #[allow(unreachable_code)]
258 fn temp_path_from_argument_types() {
259 // This just has to compile
262 TempPath
::from_path("");
263 TempPath
::from_path(String
::new());
264 TempPath
::from_path(OsStr
::new(""));
265 TempPath
::from_path(OsString
::new());
266 TempPath
::from_path(Path
::new(""));
267 TempPath
::from_path(PathBuf
::new());
268 TempPath
::from_path(PathBuf
::new().into_boxed_path());
272 fn test_write_after_close() {
273 let path
= NamedTempFile
::new().unwrap().into_temp_path();
274 File
::create(path
).unwrap().write_all(b
"test").unwrap();
278 fn test_change_dir() {
279 env
::set_current_dir(env
::temp_dir()).unwrap();
280 let tmpfile
= NamedTempFile
::new_in(".").unwrap();
281 let path
= env
::current_dir().unwrap().join(tmpfile
.path());
282 env
::set_current_dir("/").unwrap();
284 assert
!(!exists(path
))
288 fn test_into_parts() {
289 let mut file
= NamedTempFile
::new().unwrap();
290 write
!(file
, "abcd").expect("write failed");
292 let (mut file
, temp_path
) = file
.into_parts();
294 let path
= temp_path
.to_path_buf();
296 assert
!(path
.exists());
298 assert
!(!path
.exists());
300 write
!(file
, "efgh").expect("write failed");
302 file
.seek(SeekFrom
::Start(0)).unwrap();
303 let mut buf
= String
::new();
304 file
.read_to_string(&mut buf
).unwrap();
305 assert_eq
!("abcdefgh", buf
);
309 fn test_from_parts() {
310 let mut file
= NamedTempFile
::new().unwrap();
311 write
!(file
, "abcd").expect("write failed");
313 let (file
, temp_path
) = file
.into_parts();
315 let file
= NamedTempFile
::from_parts(file
, temp_path
);
317 assert
!(file
.path().exists());
322 let mut tmpfile
= NamedTempFile
::new().unwrap();
323 write
!(tmpfile
, "abcde").unwrap();
324 let (mut f
, temp_path
) = tmpfile
.into_parts();
327 assert
!(exists(&temp_path
));
328 path
= temp_path
.keep().unwrap();
329 assert
!(exists(&path
));
331 // Check original file
332 f
.seek(SeekFrom
::Start(0)).unwrap();
333 let mut buf
= String
::new();
334 f
.read_to_string(&mut buf
).unwrap();
335 assert_eq
!("abcde", buf
);
339 // Try opening it again.
340 let mut f
= File
::open(&path
).unwrap();
341 f
.seek(SeekFrom
::Start(0)).unwrap();
342 let mut buf
= String
::new();
343 f
.read_to_string(&mut buf
).unwrap();
344 assert_eq
!("abcde", buf
);
346 std
::fs
::remove_file(&path
).unwrap();
351 let tmpfile
= Builder
::new().make(|path
| File
::create(path
)).unwrap();
353 assert
!(tmpfile
.path().is_file());
358 let tmp_dir
= tempdir().unwrap();
360 let tmpfile
= Builder
::new()
361 .make_in(tmp_dir
.path(), |path
| File
::create(path
))
364 assert
!(tmpfile
.path().is_file());
365 assert_eq
!(tmpfile
.path().parent(), Some(tmp_dir
.path()));
369 fn test_make_fnmut() {
372 // Show that an FnMut can be used.
373 let tmpfile
= Builder
::new()
380 assert
!(tmpfile
.path().is_file());
386 use std
::os
::unix
::net
::UnixListener
;
388 let temp_sock
= Builder
::new()
392 .make(|path
| UnixListener
::bind(path
))
395 assert
!(temp_sock
.path().exists());
400 fn test_make_uds_conflict() {
401 use std
::os
::unix
::net
::UnixListener
;
402 use std
::sync
::atomic
::{AtomicUsize, Ordering}
;
405 // Check that retries happen correctly by racing N different threads.
407 const NTHREADS
: usize = 20;
409 // The number of times our callback was called.
410 let tries
= Arc
::new(AtomicUsize
::new(0));
412 let mut threads
= Vec
::with_capacity(NTHREADS
);
414 for _
in 0..NTHREADS
{
415 let tries
= tries
.clone();
416 threads
.push(std
::thread
::spawn(move || {
417 // Ensure that every thread uses the same seed so we are guaranteed
418 // to retry. Note that fastrand seeds are thread-local.
426 tries
.fetch_add(1, Ordering
::Relaxed
);
427 UnixListener
::bind(path
)
432 // Join all threads, but don't drop the temp file yet. Otherwise, we won't
433 // get a deterministic number of `tries`.
434 let sockets
: Vec
<_
> = threads
436 .map(|thread
| thread
.join().unwrap().unwrap())
439 // Number of tries is exactly equal to (n*(n+1))/2.
441 tries
.load(Ordering
::Relaxed
),
442 (NTHREADS
* (NTHREADS
+ 1)) / 2
445 for socket
in sockets
{
446 assert
!(socket
.path().exists());
452 fn test_overly_generic_bounds() {
453 pub struct Foo
<T
>(T
);
457 T
: Sync
+ Send
+ '
static,
458 for<'a
> &'a T
: Write
+ Read
,
460 pub fn new(foo
: T
) -> Self {
465 // Don't really need to run this. Only care if it compiles.
466 if let Ok(file
) = File
::open("i_do_not_exist") {