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