]> git.lizzy.rs Git - rust.git/blob - src/test/run-pass/tempfile.rs
Merge pull request #20510 from tshepang/patch-6
[rust.git] / src / test / run-pass / tempfile.rs
1 // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // ignore-windows TempDir may cause IoError on windows: #10463
12
13 // These tests are here to exercise the functionality of the `tempfile` module.
14 // One might expect these tests to be located in that module, but sadly they
15 // cannot. The tests need to invoke `os::change_dir` which cannot be done in the
16 // normal test infrastructure. If the tests change the current working
17 // directory, then *all* tests which require relative paths suddenly break b/c
18 // they're in a different location than before. Hence, these tests are all run
19 // serially here.
20
21 use std::io::fs::PathExtensions;
22 use std::io::{fs, TempDir};
23 use std::io;
24 use std::os;
25 use std::sync::mpsc::channel;
26 use std::thread::Thread;
27
28 fn test_tempdir() {
29     let path = {
30         let p = TempDir::new_in(&Path::new("."), "foobar").unwrap();
31         let p = p.path();
32         assert!(p.as_vec().ends_with(b"foobar"));
33         p.clone()
34     };
35     assert!(!path.exists());
36 }
37
38 fn test_rm_tempdir() {
39     let (tx, rx) = channel();
40     let f = move|:| -> () {
41         let tmp = TempDir::new("test_rm_tempdir").unwrap();
42         tx.send(tmp.path().clone()).unwrap();
43         panic!("panic to unwind past `tmp`");
44     };
45     let _ = Thread::spawn(f).join();
46     let path = rx.recv().unwrap();
47     assert!(!path.exists());
48
49     let tmp = TempDir::new("test_rm_tempdir").unwrap();
50     let path = tmp.path().clone();
51     let f = move|:| -> () {
52         let _tmp = tmp;
53         panic!("panic to unwind past `tmp`");
54     };
55     let _ = Thread::spawn(f).join();
56     assert!(!path.exists());
57
58     let path;
59     {
60         let f = move|:| {
61             TempDir::new("test_rm_tempdir").unwrap()
62         };
63         let tmp = Thread::spawn(f).join().ok().expect("test_rm_tmdir");
64         path = tmp.path().clone();
65         assert!(path.exists());
66     }
67     assert!(!path.exists());
68
69     let path;
70     {
71         let tmp = TempDir::new("test_rm_tempdir").unwrap();
72         path = tmp.into_inner();
73     }
74     assert!(path.exists());
75     fs::rmdir_recursive(&path);
76     assert!(!path.exists());
77 }
78
79 fn test_rm_tempdir_close() {
80     let (tx, rx) = channel();
81     let f = move|:| -> () {
82         let tmp = TempDir::new("test_rm_tempdir").unwrap();
83         tx.send(tmp.path().clone()).unwrap();
84         tmp.close();
85         panic!("panic when unwinding past `tmp`");
86     };
87     let _ = Thread::spawn(f).join();
88     let path = rx.recv().unwrap();
89     assert!(!path.exists());
90
91     let tmp = TempDir::new("test_rm_tempdir").unwrap();
92     let path = tmp.path().clone();
93     let f = move|:| -> () {
94         let tmp = tmp;
95         tmp.close();
96         panic!("panic when unwinding past `tmp`");
97     };
98     let _ = Thread::spawn(f).join();
99     assert!(!path.exists());
100
101     let path;
102     {
103         let f = move|:| {
104             TempDir::new("test_rm_tempdir").unwrap()
105         };
106         let tmp = Thread::spawn(f).join().ok().expect("test_rm_tmdir");
107         path = tmp.path().clone();
108         assert!(path.exists());
109         tmp.close();
110     }
111     assert!(!path.exists());
112
113     let path;
114     {
115         let tmp = TempDir::new("test_rm_tempdir").unwrap();
116         path = tmp.into_inner();
117     }
118     assert!(path.exists());
119     fs::rmdir_recursive(&path);
120     assert!(!path.exists());
121 }
122
123 // Ideally these would be in std::os but then core would need
124 // to depend on std
125 fn recursive_mkdir_rel() {
126     let path = Path::new("frob");
127     let cwd = os::getcwd().unwrap();
128     println!("recursive_mkdir_rel: Making: {} in cwd {} [{}]", path.display(),
129            cwd.display(), path.exists());
130     fs::mkdir_recursive(&path, io::USER_RWX);
131     assert!(path.is_dir());
132     fs::mkdir_recursive(&path, io::USER_RWX);
133     assert!(path.is_dir());
134 }
135
136 fn recursive_mkdir_dot() {
137     let dot = Path::new(".");
138     fs::mkdir_recursive(&dot, io::USER_RWX);
139     let dotdot = Path::new("..");
140     fs::mkdir_recursive(&dotdot, io::USER_RWX);
141 }
142
143 fn recursive_mkdir_rel_2() {
144     let path = Path::new("./frob/baz");
145     let cwd = os::getcwd().unwrap();
146     println!("recursive_mkdir_rel_2: Making: {} in cwd {} [{}]", path.display(),
147            cwd.display(), path.exists());
148     fs::mkdir_recursive(&path, io::USER_RWX);
149     assert!(path.is_dir());
150     assert!(path.dir_path().is_dir());
151     let path2 = Path::new("quux/blat");
152     println!("recursive_mkdir_rel_2: Making: {} in cwd {}", path2.display(),
153            cwd.display());
154     fs::mkdir_recursive(&path2, io::USER_RWX);
155     assert!(path2.is_dir());
156     assert!(path2.dir_path().is_dir());
157 }
158
159 // Ideally this would be in core, but needs TempFile
160 pub fn test_rmdir_recursive_ok() {
161     let rwx = io::USER_RWX;
162
163     let tmpdir = TempDir::new("test").ok().expect("test_rmdir_recursive_ok: \
164                                                    couldn't create temp dir");
165     let tmpdir = tmpdir.path();
166     let root = tmpdir.join("foo");
167
168     println!("making {}", root.display());
169     fs::mkdir(&root, rwx);
170     fs::mkdir(&root.join("foo"), rwx);
171     fs::mkdir(&root.join("foo").join("bar"), rwx);
172     fs::mkdir(&root.join("foo").join("bar").join("blat"), rwx);
173     fs::rmdir_recursive(&root);
174     assert!(!root.exists());
175     assert!(!root.join("bar").exists());
176     assert!(!root.join("bar").join("blat").exists());
177 }
178
179 pub fn dont_double_panic() {
180     let r: Result<(), _> = Thread::spawn(move|| {
181         let tmpdir = TempDir::new("test").unwrap();
182         // Remove the temporary directory so that TempDir sees
183         // an error on drop
184         fs::rmdir(tmpdir.path());
185         // Panic. If TempDir panics *again* due to the rmdir
186         // error then the process will abort.
187         panic!();
188     }).join();
189     assert!(r.is_err());
190 }
191
192 fn in_tmpdir(f: ||) {
193     let tmpdir = TempDir::new("test").ok().expect("can't make tmpdir");
194     assert!(os::change_dir(tmpdir.path()).is_ok());
195
196     f();
197 }
198
199 pub fn main() {
200     in_tmpdir(test_tempdir);
201     in_tmpdir(test_rm_tempdir);
202     in_tmpdir(test_rm_tempdir_close);
203     in_tmpdir(recursive_mkdir_rel);
204     in_tmpdir(recursive_mkdir_dot);
205     in_tmpdir(recursive_mkdir_rel_2);
206     in_tmpdir(test_rmdir_recursive_ok);
207     in_tmpdir(dont_double_panic);
208 }