]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
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 | ||
c34b1796 AL |
21 | #![feature(old_io, old_path, os, old_fs)] |
22 | ||
23 | use std::old_path::{Path, GenericPath}; | |
85aaf69f SL |
24 | use std::old_io::fs::PathExtensions; |
25 | use std::old_io::{fs, TempDir}; | |
26 | use std::old_io; | |
c34b1796 | 27 | use std::env; |
1a4d82fc | 28 | use std::sync::mpsc::channel; |
85aaf69f | 29 | use std::thread; |
1a4d82fc JJ |
30 | |
31 | fn test_tempdir() { | |
32 | let path = { | |
33 | let p = TempDir::new_in(&Path::new("."), "foobar").unwrap(); | |
34 | let p = p.path(); | |
35 | assert!(p.as_str().unwrap().contains("foobar")); | |
36 | p.clone() | |
37 | }; | |
38 | assert!(!path.exists()); | |
39 | } | |
40 | ||
41 | fn test_rm_tempdir() { | |
42 | let (tx, rx) = channel(); | |
85aaf69f | 43 | let f = move|| -> () { |
1a4d82fc JJ |
44 | let tmp = TempDir::new("test_rm_tempdir").unwrap(); |
45 | tx.send(tmp.path().clone()).unwrap(); | |
46 | panic!("panic to unwind past `tmp`"); | |
47 | }; | |
85aaf69f | 48 | thread::spawn(f).join(); |
1a4d82fc JJ |
49 | let path = rx.recv().unwrap(); |
50 | assert!(!path.exists()); | |
51 | ||
52 | let tmp = TempDir::new("test_rm_tempdir").unwrap(); | |
53 | let path = tmp.path().clone(); | |
85aaf69f | 54 | let f = move|| -> () { |
1a4d82fc JJ |
55 | let _tmp = tmp; |
56 | panic!("panic to unwind past `tmp`"); | |
57 | }; | |
85aaf69f | 58 | thread::spawn(f).join(); |
1a4d82fc JJ |
59 | assert!(!path.exists()); |
60 | ||
61 | let path; | |
62 | { | |
85aaf69f | 63 | let f = move || { |
1a4d82fc JJ |
64 | TempDir::new("test_rm_tempdir").unwrap() |
65 | }; | |
85aaf69f SL |
66 | // FIXME(#16640) `: TempDir` annotation shouldn't be necessary |
67 | let tmp: TempDir = thread::scoped(f).join(); | |
1a4d82fc JJ |
68 | path = tmp.path().clone(); |
69 | assert!(path.exists()); | |
70 | } | |
71 | assert!(!path.exists()); | |
72 | ||
73 | let path; | |
74 | { | |
75 | let tmp = TempDir::new("test_rm_tempdir").unwrap(); | |
76 | path = tmp.into_inner(); | |
77 | } | |
78 | assert!(path.exists()); | |
79 | fs::rmdir_recursive(&path); | |
80 | assert!(!path.exists()); | |
81 | } | |
82 | ||
83 | fn test_rm_tempdir_close() { | |
84 | let (tx, rx) = channel(); | |
85aaf69f | 85 | let f = move|| -> () { |
1a4d82fc JJ |
86 | let tmp = TempDir::new("test_rm_tempdir").unwrap(); |
87 | tx.send(tmp.path().clone()).unwrap(); | |
88 | tmp.close(); | |
89 | panic!("panic when unwinding past `tmp`"); | |
90 | }; | |
85aaf69f | 91 | thread::spawn(f).join(); |
1a4d82fc JJ |
92 | let path = rx.recv().unwrap(); |
93 | assert!(!path.exists()); | |
94 | ||
95 | let tmp = TempDir::new("test_rm_tempdir").unwrap(); | |
96 | let path = tmp.path().clone(); | |
85aaf69f | 97 | let f = move|| -> () { |
1a4d82fc JJ |
98 | let tmp = tmp; |
99 | tmp.close(); | |
100 | panic!("panic when unwinding past `tmp`"); | |
101 | }; | |
85aaf69f | 102 | thread::spawn(f).join(); |
1a4d82fc JJ |
103 | assert!(!path.exists()); |
104 | ||
105 | let path; | |
106 | { | |
85aaf69f | 107 | let f = move || { |
1a4d82fc JJ |
108 | TempDir::new("test_rm_tempdir").unwrap() |
109 | }; | |
85aaf69f SL |
110 | // FIXME(#16640) `: TempDir` annotation shouldn't be necessary |
111 | let tmp: TempDir = thread::scoped(f).join(); | |
1a4d82fc JJ |
112 | path = tmp.path().clone(); |
113 | assert!(path.exists()); | |
114 | tmp.close(); | |
115 | } | |
116 | assert!(!path.exists()); | |
117 | ||
118 | let path; | |
119 | { | |
120 | let tmp = TempDir::new("test_rm_tempdir").unwrap(); | |
121 | path = tmp.into_inner(); | |
122 | } | |
123 | assert!(path.exists()); | |
124 | fs::rmdir_recursive(&path); | |
125 | assert!(!path.exists()); | |
126 | } | |
127 | ||
128 | // Ideally these would be in std::os but then core would need | |
129 | // to depend on std | |
130 | fn recursive_mkdir_rel() { | |
131 | let path = Path::new("frob"); | |
c34b1796 | 132 | let cwd = Path::new(env::current_dir().unwrap().to_str().unwrap()); |
1a4d82fc JJ |
133 | println!("recursive_mkdir_rel: Making: {} in cwd {} [{}]", path.display(), |
134 | cwd.display(), path.exists()); | |
85aaf69f | 135 | fs::mkdir_recursive(&path, old_io::USER_RWX); |
1a4d82fc | 136 | assert!(path.is_dir()); |
85aaf69f | 137 | fs::mkdir_recursive(&path, old_io::USER_RWX); |
1a4d82fc JJ |
138 | assert!(path.is_dir()); |
139 | } | |
140 | ||
141 | fn recursive_mkdir_dot() { | |
142 | let dot = Path::new("."); | |
85aaf69f | 143 | fs::mkdir_recursive(&dot, old_io::USER_RWX); |
1a4d82fc | 144 | let dotdot = Path::new(".."); |
85aaf69f | 145 | fs::mkdir_recursive(&dotdot, old_io::USER_RWX); |
1a4d82fc JJ |
146 | } |
147 | ||
148 | fn recursive_mkdir_rel_2() { | |
149 | let path = Path::new("./frob/baz"); | |
c34b1796 | 150 | let cwd = Path::new(env::current_dir().unwrap().to_str().unwrap()); |
1a4d82fc JJ |
151 | println!("recursive_mkdir_rel_2: Making: {} in cwd {} [{}]", path.display(), |
152 | cwd.display(), path.exists()); | |
85aaf69f | 153 | fs::mkdir_recursive(&path, old_io::USER_RWX); |
1a4d82fc JJ |
154 | assert!(path.is_dir()); |
155 | assert!(path.dir_path().is_dir()); | |
156 | let path2 = Path::new("quux/blat"); | |
157 | println!("recursive_mkdir_rel_2: Making: {} in cwd {}", path2.display(), | |
158 | cwd.display()); | |
85aaf69f | 159 | fs::mkdir_recursive(&path2, old_io::USER_RWX); |
1a4d82fc JJ |
160 | assert!(path2.is_dir()); |
161 | assert!(path2.dir_path().is_dir()); | |
162 | } | |
163 | ||
164 | // Ideally this would be in core, but needs TempFile | |
165 | pub fn test_rmdir_recursive_ok() { | |
85aaf69f | 166 | let rwx = old_io::USER_RWX; |
1a4d82fc JJ |
167 | |
168 | let tmpdir = TempDir::new("test").ok().expect("test_rmdir_recursive_ok: \ | |
169 | couldn't create temp dir"); | |
170 | let tmpdir = tmpdir.path(); | |
171 | let root = tmpdir.join("foo"); | |
172 | ||
173 | println!("making {}", root.display()); | |
174 | fs::mkdir(&root, rwx); | |
175 | fs::mkdir(&root.join("foo"), rwx); | |
176 | fs::mkdir(&root.join("foo").join("bar"), rwx); | |
177 | fs::mkdir(&root.join("foo").join("bar").join("blat"), rwx); | |
178 | fs::rmdir_recursive(&root); | |
179 | assert!(!root.exists()); | |
180 | assert!(!root.join("bar").exists()); | |
181 | assert!(!root.join("bar").join("blat").exists()); | |
182 | } | |
183 | ||
184 | pub fn dont_double_panic() { | |
85aaf69f | 185 | let r: Result<(), _> = thread::spawn(move|| { |
1a4d82fc JJ |
186 | let tmpdir = TempDir::new("test").unwrap(); |
187 | // Remove the temporary directory so that TempDir sees | |
188 | // an error on drop | |
189 | fs::rmdir(tmpdir.path()); | |
190 | // Panic. If TempDir panics *again* due to the rmdir | |
191 | // error then the process will abort. | |
192 | panic!(); | |
193 | }).join(); | |
194 | assert!(r.is_err()); | |
195 | } | |
196 | ||
197 | fn in_tmpdir<F>(f: F) where F: FnOnce() { | |
198 | let tmpdir = TempDir::new("test").ok().expect("can't make tmpdir"); | |
c34b1796 | 199 | assert!(env::set_current_dir(tmpdir.path().as_str().unwrap()).is_ok()); |
1a4d82fc JJ |
200 | |
201 | f(); | |
202 | } | |
203 | ||
204 | pub fn main() { | |
205 | in_tmpdir(test_tempdir); | |
206 | in_tmpdir(test_rm_tempdir); | |
207 | in_tmpdir(test_rm_tempdir_close); | |
208 | in_tmpdir(recursive_mkdir_rel); | |
209 | in_tmpdir(recursive_mkdir_dot); | |
210 | in_tmpdir(recursive_mkdir_rel_2); | |
211 | in_tmpdir(test_rmdir_recursive_ok); | |
212 | in_tmpdir(dont_double_panic); | |
213 | } |