1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 package org.eclipse.jgit.util;
45
46 import static org.junit.Assert.assertEquals;
47 import static org.junit.Assert.assertFalse;
48 import static org.junit.Assert.assertTrue;
49 import static org.junit.Assert.fail;
50
51 import java.io.File;
52 import java.io.IOException;
53 import java.util.regex.Matcher;
54
55 import org.eclipse.jgit.junit.JGitTestUtil;
56 import org.junit.After;
57 import org.junit.Before;
58 import org.junit.Test;
59
60 public class FileUtilTest {
61 private File trash;
62
63 @Before
64 public void setUp() throws Exception {
65 trash = File.createTempFile("tmp_", "");
66 trash.delete();
67 assertTrue("mkdir " + trash, trash.mkdir());
68 }
69
70 @After
71 public void tearDown() throws Exception {
72 FileUtils.delete(trash, FileUtils.RECURSIVE | FileUtils.RETRY);
73 }
74
75 @Test
76 public void testDeleteFile() throws IOException {
77 File f = new File(trash, "test");
78 FileUtils.createNewFile(f);
79 FileUtils.delete(f);
80 assertFalse(f.exists());
81
82 try {
83 FileUtils.delete(f);
84 fail("deletion of non-existing file must fail");
85 } catch (IOException e) {
86
87 }
88
89 try {
90 FileUtils.delete(f, FileUtils.SKIP_MISSING);
91 } catch (IOException e) {
92 fail("deletion of non-existing file must not fail with option SKIP_MISSING");
93 }
94 }
95
96 @Test
97 public void testDeleteRecursive() throws IOException {
98 File f1 = new File(trash, "test/test/a");
99 FileUtils.mkdirs(f1.getParentFile());
100 FileUtils.createNewFile(f1);
101 File f2 = new File(trash, "test/test/b");
102 FileUtils.createNewFile(f2);
103 File d = new File(trash, "test");
104 FileUtils.delete(d, FileUtils.RECURSIVE);
105 assertFalse(d.exists());
106
107 try {
108 FileUtils.delete(d, FileUtils.RECURSIVE);
109 fail("recursive deletion of non-existing directory must fail");
110 } catch (IOException e) {
111
112 }
113
114 try {
115 FileUtils.delete(d, FileUtils.RECURSIVE | FileUtils.SKIP_MISSING);
116 } catch (IOException e) {
117 fail("recursive deletion of non-existing directory must not fail with option SKIP_MISSING");
118 }
119 }
120
121 @Test
122
123 public void testDeleteRecursiveEmpty() throws IOException {
124 File f1 = new File(trash, "test/test/a");
125 File f2 = new File(trash, "test/a");
126 File d1 = new File(trash, "test");
127 File d2 = new File(trash, "test/test");
128 File d3 = new File(trash, "test/b");
129 FileUtils.mkdirs(f1.getParentFile());
130 FileUtils.createNewFile(f2);
131 FileUtils.createNewFile(f1);
132 FileUtils.mkdirs(d3);
133
134
135 try {
136 FileUtils.delete(d1, FileUtils.EMPTY_DIRECTORIES_ONLY);
137 fail("delete should fail");
138 } catch (IOException e1) {
139 try {
140 FileUtils.delete(d1, FileUtils.EMPTY_DIRECTORIES_ONLY|FileUtils.RECURSIVE);
141 fail("delete should fail");
142 } catch (IOException e2) {
143
144 assertTrue(f1.exists());
145 assertTrue(f2.exists());
146 assertTrue(d1.exists());
147 assertTrue(d2.exists());
148 assertTrue(d3.exists());
149 }
150 }
151
152
153 assertTrue(f1.delete());
154 assertTrue(f2.delete());
155
156
157 try {
158 FileUtils.delete(d1, FileUtils.EMPTY_DIRECTORIES_ONLY);
159 fail("delete should fail");
160 } catch (IOException e2) {
161
162 assertTrue(d1.exists());
163 assertTrue(d2.exists());
164 assertTrue(d3.exists());
165 }
166
167
168 FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY
169 | FileUtils.RECURSIVE);
170 assertFalse(d2.exists());
171
172
173 try {
174 FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY);
175 fail("Cannot delete non-existent entity");
176 } catch (IOException e) {
177
178 }
179
180
181 FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY
182 | FileUtils.SKIP_MISSING);
183 FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY
184 | FileUtils.RECURSIVE | FileUtils.SKIP_MISSING);
185
186
187 FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY
188 | FileUtils.IGNORE_ERRORS);
189 FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY
190 | FileUtils.RECURSIVE | FileUtils.IGNORE_ERRORS);
191 }
192
193 @Test
194 public void testDeleteRecursiveEmptyNeedsToCheckFilesFirst()
195 throws IOException {
196 File d1 = new File(trash, "test");
197 File d2 = new File(trash, "test/a");
198 File d3 = new File(trash, "test/b");
199 File f1 = new File(trash, "test/c");
200 File d4 = new File(trash, "test/d");
201 FileUtils.mkdirs(d1);
202 FileUtils.mkdirs(d2);
203 FileUtils.mkdirs(d3);
204 FileUtils.mkdirs(d4);
205 FileUtils.createNewFile(f1);
206
207
208 try {
209 FileUtils.delete(d1, FileUtils.EMPTY_DIRECTORIES_ONLY
210 | FileUtils.RECURSIVE);
211 fail("delete should fail");
212 } catch (IOException e) {
213
214 assertTrue(f1.exists());
215 assertTrue(d1.exists());
216 assertTrue(d2.exists());
217 assertTrue(d3.exists());
218 assertTrue(d4.exists());
219 }
220 }
221
222 @Test
223 public void testDeleteRecursiveEmptyDirectoriesOnlyButIsFile()
224 throws IOException {
225 File f1 = new File(trash, "test/test/a");
226 FileUtils.mkdirs(f1.getParentFile());
227 FileUtils.createNewFile(f1);
228 try {
229 FileUtils.delete(f1, FileUtils.EMPTY_DIRECTORIES_ONLY);
230 fail("delete should fail");
231 } catch (IOException e) {
232 assertTrue(f1.exists());
233 }
234 }
235
236 @Test
237 public void testMkdir() throws IOException {
238 File d = new File(trash, "test");
239 FileUtils.mkdir(d);
240 assertTrue(d.exists() && d.isDirectory());
241
242 try {
243 FileUtils.mkdir(d);
244 fail("creation of existing directory must fail");
245 } catch (IOException e) {
246
247 }
248
249 FileUtils.mkdir(d, true);
250 assertTrue(d.exists() && d.isDirectory());
251
252 assertTrue(d.delete());
253 File f = new File(trash, "test");
254 FileUtils.createNewFile(f);
255 try {
256 FileUtils.mkdir(d);
257 fail("creation of directory having same path as existing file must"
258 + " fail");
259 } catch (IOException e) {
260
261 }
262 assertTrue(f.delete());
263 }
264
265 @Test
266 public void testMkdirs() throws IOException {
267 File root = new File(trash, "test");
268 assertTrue(root.mkdir());
269
270 File d = new File(root, "test/test");
271 FileUtils.mkdirs(d);
272 assertTrue(d.exists() && d.isDirectory());
273
274 try {
275 FileUtils.mkdirs(d);
276 fail("creation of existing directory hierarchy must fail");
277 } catch (IOException e) {
278
279 }
280
281 FileUtils.mkdirs(d, true);
282 assertTrue(d.exists() && d.isDirectory());
283
284 FileUtils.delete(root, FileUtils.RECURSIVE);
285 File f = new File(trash, "test");
286 FileUtils.createNewFile(f);
287 try {
288 FileUtils.mkdirs(d);
289 fail("creation of directory having path conflicting with existing"
290 + " file must fail");
291 } catch (IOException e) {
292
293 }
294 assertTrue(f.delete());
295 }
296
297 @Test
298 public void testCreateNewFile() throws IOException {
299 File f = new File(trash, "x");
300 FileUtils.createNewFile(f);
301 assertTrue(f.exists());
302
303 try {
304 FileUtils.createNewFile(f);
305 fail("creation of already existing file must fail");
306 } catch (IOException e) {
307
308 }
309
310 FileUtils.delete(f);
311 }
312
313 @Test
314 public void testDeleteEmptyTreeOk() throws IOException {
315 File t = new File(trash, "t");
316 FileUtils.mkdir(t);
317 FileUtils.mkdir(new File(t, "d"));
318 FileUtils.mkdir(new File(new File(t, "d"), "e"));
319 FileUtils.delete(t, FileUtils.EMPTY_DIRECTORIES_ONLY | FileUtils.RECURSIVE);
320 assertFalse(t.exists());
321 }
322
323 @Test
324 public void testDeleteNotEmptyTreeNotOk() throws IOException {
325 File t = new File(trash, "t");
326 FileUtils.mkdir(t);
327 FileUtils.mkdir(new File(t, "d"));
328 File f = new File(new File(t, "d"), "f");
329 FileUtils.createNewFile(f);
330 FileUtils.mkdir(new File(new File(t, "d"), "e"));
331 try {
332 FileUtils.delete(t, FileUtils.EMPTY_DIRECTORIES_ONLY | FileUtils.RECURSIVE);
333 fail("expected failure to delete f");
334 } catch (IOException e) {
335 assertTrue(e.getMessage().endsWith(f.getAbsolutePath()));
336 }
337 assertTrue(t.exists());
338 }
339
340 @Test
341 public void testDeleteNotEmptyTreeNotOkButIgnoreFail() throws IOException {
342 File t = new File(trash, "t");
343 FileUtils.mkdir(t);
344 FileUtils.mkdir(new File(t, "d"));
345 File f = new File(new File(t, "d"), "f");
346 FileUtils.createNewFile(f);
347 File e = new File(new File(t, "d"), "e");
348 FileUtils.mkdir(e);
349 FileUtils.delete(t, FileUtils.EMPTY_DIRECTORIES_ONLY | FileUtils.RECURSIVE
350 | FileUtils.IGNORE_ERRORS);
351
352 assertTrue(t.exists());
353 assertTrue(f.exists());
354 assertFalse(e.exists());
355 }
356
357 @Test
358 public void testRenameOverNonExistingFile() throws IOException {
359 File d = new File(trash, "d");
360 FileUtils.mkdirs(d);
361 File f1 = new File(trash, "d/f");
362 File f2 = new File(trash, "d/g");
363 JGitTestUtil.write(f1, "f1");
364
365 FileUtils.rename(f1, f2);
366 assertFalse(f1.exists());
367 assertTrue(f2.exists());
368 assertEquals("f1", JGitTestUtil.read(f2));
369 }
370
371 @Test
372 public void testRenameOverExistingFile() throws IOException {
373 File d = new File(trash, "d");
374 FileUtils.mkdirs(d);
375 File f1 = new File(trash, "d/f");
376 File f2 = new File(trash, "d/g");
377 JGitTestUtil.write(f1, "f1");
378 JGitTestUtil.write(f2, "f2");
379
380 FileUtils.rename(f1, f2);
381 assertFalse(f1.exists());
382 assertTrue(f2.exists());
383 assertEquals("f1", JGitTestUtil.read(f2));
384 }
385
386 @Test
387 public void testRenameOverExistingNonEmptyDirectory() throws IOException {
388 File d = new File(trash, "d");
389 FileUtils.mkdirs(d);
390 File f1 = new File(trash, "d/f");
391 File f2 = new File(trash, "d/g");
392 File d1 = new File(trash, "d/g/h/i");
393 File f3 = new File(trash, "d/g/h/f");
394 FileUtils.mkdirs(d1);
395 JGitTestUtil.write(f1, "f1");
396 JGitTestUtil.write(f3, "f3");
397
398 try {
399 FileUtils.rename(f1, f2);
400 fail("rename to non-empty directory should fail");
401 } catch (IOException e) {
402 assertEquals("f1", JGitTestUtil.read(f1));
403 assertEquals("f3", JGitTestUtil.read(f3));
404
405 }
406 }
407
408 @Test
409 public void testRenameOverExistingEmptyDirectory() throws IOException {
410 File d = new File(trash, "d");
411 FileUtils.mkdirs(d);
412 File f1 = new File(trash, "d/f");
413 File f2 = new File(trash, "d/g");
414 File d1 = new File(trash, "d/g/h/i");
415 FileUtils.mkdirs(d1);
416 JGitTestUtil.write(f1, "f1");
417
418 FileUtils.rename(f1, f2);
419 assertFalse(f1.exists());
420 assertTrue(f2.exists());
421 assertEquals("f1", JGitTestUtil.read(f2));
422 }
423
424 @Test
425 public void testCreateSymlink() throws IOException {
426 FS fs = FS.DETECTED;
427 try {
428 fs.createSymLink(new File(trash, "x"), "y");
429 } catch (IOException e) {
430 if (fs.supportsSymlinks())
431 fail("FS claims to support symlinks but attempt to create symlink failed");
432 return;
433 }
434 assertTrue(fs.supportsSymlinks());
435 String target = fs.readSymLink(new File(trash, "x"));
436 assertEquals("y", target);
437 }
438
439 @Test
440 public void testRelativize_doc() {
441
442 String base = toOSPathString("c:\\Users\\jdoe\\eclipse\\git\\project");
443 String other = toOSPathString("c:\\Users\\jdoe\\eclipse\\git\\another_project\\pom.xml");
444 String expected = toOSPathString("..\\another_project\\pom.xml");
445
446 String actual = FileUtils.relativize(base, other);
447 assertEquals(expected, actual);
448 }
449
450 @Test
451 public void testRelativize_mixedCase() {
452 SystemReader systemReader = SystemReader.getInstance();
453 String base = toOSPathString("C:\\git\\jgit");
454 String other = toOSPathString("C:\\Git\\test\\d\\f.txt");
455 String expectedCaseInsensitive = toOSPathString("..\\test\\d\\f.txt");
456 String expectedCaseSensitive = toOSPathString("..\\..\\Git\\test\\d\\f.txt");
457
458 if (systemReader.isWindows()) {
459 String actual = FileUtils.relativize(base, other);
460 assertEquals(expectedCaseInsensitive, actual);
461 } else if (systemReader.isMacOS()) {
462 String actual = FileUtils.relativize(base, other);
463 assertEquals(expectedCaseInsensitive, actual);
464 } else {
465 String actual = FileUtils.relativize(base, other);
466 assertEquals(expectedCaseSensitive, actual);
467 }
468 }
469
470 @Test
471 public void testRelativize_scheme() {
472 String base = toOSPathString("file:/home/eclipse/runtime-New_configuration/project_1/file.java");
473 String other = toOSPathString("file:/home/eclipse/runtime-New_configuration/project");
474
475 String expected = toOSPathString("../../project");
476
477 String actual = FileUtils.relativize(base, other);
478 assertEquals(expected, actual);
479 }
480
481 @Test
482 public void testRelativize_equalPaths() {
483 String base = toOSPathString("file:/home/eclipse/runtime-New_configuration/project_1");
484 String other = toOSPathString("file:/home/eclipse/runtime-New_configuration/project_1");
485 String expected = "";
486
487 String actual = FileUtils.relativize(base, other);
488 assertEquals(expected, actual);
489 }
490
491 @Test
492 public void testRelativize_whitespaces() {
493 String base = toOSPathString("/home/eclipse 3.4/runtime New_configuration/project_1");
494 String other = toOSPathString("/home/eclipse 3.4/runtime New_configuration/project_1/file");
495 String expected = "file";
496
497 String actual = FileUtils.relativize(base, other);
498 assertEquals(expected, actual);
499 }
500
501 private String toOSPathString(String path) {
502 return path.replaceAll("/|\\\\",
503 Matcher.quoteReplacement(File.separator));
504 }
505 }