View Javadoc

1   // Copyright (C) 2004 - 2011 Philip Aston
2   // All rights reserved.
3   //
4   // This file is part of The Grinder software distribution. Refer to
5   // the file LICENSE which is part of The Grinder distribution for
6   // licensing details. The Grinder distribution is available on the
7   // Internet at http://grinder.sourceforge.net/
8   //
9   // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
12  // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
13  // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
14  // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15  // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16  // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
17  // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
18  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
19  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
20  // OF THE POSSIBILITY OF SUCH DAMAGE.
21  
22  package net.grinder.util;
23  
24  import static net.grinder.testutility.AssertUtilities.assertArraysEqual;
25  import static net.grinder.testutility.FileUtilities.createRandomFile;
26  import static org.junit.Assert.assertEquals;
27  import static org.junit.Assert.assertFalse;
28  import static org.junit.Assert.assertNull;
29  import static org.junit.Assert.assertSame;
30  import static org.junit.Assert.assertTrue;
31  import static org.junit.Assert.fail;
32  
33  import java.io.File;
34  import java.io.FileFilter;
35  import java.io.IOException;
36  import java.util.HashSet;
37  import java.util.Set;
38  
39  import net.grinder.testutility.AbstractJUnit4FileTestCase;
40  import net.grinder.testutility.AssertUtilities;
41  import net.grinder.testutility.FileUtilities;
42  import net.grinder.testutility.Serializer;
43  
44  import org.junit.Test;
45  
46  
47  /**
48   * Unit test case for {@link Directory}.
49   *
50   * @author Philip Aston
51   */
52  public class TestDirectory extends AbstractJUnit4FileTestCase {
53  
54    @Test public void testConstruction() throws Exception {
55  
56      final File file = new File(getDirectory(), "x");
57      assertTrue(file.createNewFile());
58  
59      try {
60        new Directory(file);
61        fail("Expected DirectoryException");
62      }
63      catch (final Directory.DirectoryException e) {
64      }
65  
66      final Directory directory = new Directory(getDirectory());
67      assertEquals(0, directory.getWarnings().length);
68  
69      assertEquals(getDirectory(), directory.getFile());
70  
71      assertEquals(new File("."), new Directory(null).getFile());
72    }
73  
74    @Test public void testDefaultConstructor() throws Exception {
75  
76      final Directory directory = new Directory();
77      final File cwd = new File(System.getProperty("user.dir"));
78      assertEquals(cwd.getCanonicalPath(),
79                   directory.getFile().getCanonicalPath());
80    }
81  
82    @Test public void testEquality() throws Exception {
83  
84      final Directory d1 = new Directory(getDirectory());
85      final Directory d2 = new Directory(getDirectory());
86  
87      final File f = new File(getDirectory(), "comeonpilgrimyouknowhelovesyou");
88      assertTrue(f.mkdir());
89  
90      final Directory d3 = new Directory(f);
91  
92      assertEquals(d1, d1);
93      assertEquals(d1, d2);
94      AssertUtilities.assertNotEquals(d2, d3);
95  
96      assertEquals(d1.hashCode(), d1.hashCode());
97      assertEquals(d1.hashCode(), d2.hashCode());
98  
99      AssertUtilities.assertNotEquals(d1, null);
100     AssertUtilities.assertNotEquals(d1, f);
101   }
102 
103   @Test public void testListContents() throws Exception {
104 
105     final Directory directory = new Directory(getDirectory());
106 
107     final String[] files = {
108       "first/three",
109       "will-not-be-picked-up",
110       "because/they/are/too/old",
111       "directory/foo/bah/blah",
112       "directory/blah",
113       "a/b/c/d/e",
114       "a/b/f/g/h",
115       "a/b/f/g/i",
116       "x",
117       "y/z",
118       "another",
119     };
120 
121     final Set<File> expected = new HashSet<File>();
122 
123     for (int i=0; i<files.length; ++i) {
124       final File file = new File(getDirectory(), files[i]);
125       file.getParentFile().mkdirs();
126       assertTrue(file.createNewFile());
127 
128       if (i < 3) {
129         assertTrue(file.setLastModified(10000L * (i + 1)));
130       }
131       else {
132         // Result uses relative paths.
133         expected.add(new File(files[i]));
134       }
135     }
136 
137     final File[] badDirectories = {
138       new File(getDirectory(), "directory/foo/bah/blah.cantread"),
139       new File(getDirectory(), "cantread"),
140     };
141 
142     for (final File badDirectorie : badDirectories) {
143       badDirectorie.getParentFile().mkdirs();
144       assertTrue(badDirectorie.mkdir());
145       FileUtilities.setCanAccess(badDirectorie, false);
146     }
147 
148     final File[] filesAfterTimeT = directory.listContents(
149       new FileFilter() {
150         @Override
151         public boolean accept(File file) {
152           return file.isDirectory() || file.lastModified() > 50000L;
153         }
154       });
155 
156     for (final File element : filesAfterTimeT) {
157       assertTrue("Contains " + element,
158                  expected.contains(element));
159     }
160 
161     final String[] warnings = directory.getWarnings();
162     assertEquals(badDirectories.length, warnings.length);
163 
164     final StringBuffer warningsBuffer = new StringBuffer();
165 
166     for (final String warning : warnings) {
167       warningsBuffer.append(warning);
168       warningsBuffer.append("\n");
169     }
170 
171     final String warningsString = warningsBuffer.toString();
172 
173     for (final File badDirectorie : badDirectories) {
174       assertTrue(warningsBuffer + " contains " + badDirectorie.getPath(),
175                  warningsString.indexOf(badDirectorie.getPath()) > -1);
176 
177       FileUtilities.setCanAccess(badDirectorie, true);
178     }
179 
180     final File[] allFiles =
181       directory.listContents(Directory.getMatchAllFilesFilter());
182     assertEquals(files.length, allFiles.length);
183   }
184 
185   @Test public void testDeleteContents() throws Exception {
186 
187     final Directory directory = new Directory(getDirectory());
188 
189     final String[] files = {
190       "directory/foo/bah/blah",
191       "directory/blah",
192       "a/b/c/d/e",
193       "a/b/f/g/h",
194       "a/b/f/g/i",
195       "x",
196       "y/z",
197       "another",
198     };
199 
200     for (final String file2 : files) {
201       final File file = new File(getDirectory(), file2);
202       file.getParentFile().mkdirs();
203       assertTrue(file.createNewFile());
204     }
205 
206     assertTrue(getDirectory().list().length > 0);
207 
208     directory.deleteContents();
209 
210     assertEquals(0, getDirectory().list().length);
211 
212     // Can't test that deleteContents() throws an exception if
213     // contents couldn't be deleted as File.delete() ignores file
214     // permissions on W2K.
215   }
216 
217   @Test public void testCreate() throws Exception {
218     final String[] directories = {
219       "toplevel",
220       "down/a/few",
221     };
222 
223     for (final String directorie : directories) {
224       final Directory directory =
225         new Directory(new File(getDirectory(), directorie));
226       assertFalse(directory.getFile().exists());
227       directory.create();
228       assertTrue(directory.getFile().exists());
229     }
230 
231     final File file = new File(getDirectory(), "readonly");
232     assertTrue(file.createNewFile());
233     FileUtilities.setCanAccess(file, false);
234 
235     try {
236       new Directory(new File(getDirectory(), "readonly/foo")).create();
237       fail("Expected DirectoryException");
238     }
239     catch (final Directory.DirectoryException e) {
240     }
241   }
242 
243   @Test public void testDelete() throws Exception {
244     final Directory directory1 =
245       new Directory(new File(getDirectory(), "a/directory"));
246     directory1.create();
247     assertTrue(directory1.getFile().exists());
248     directory1.delete();
249     assertFalse(directory1.getFile().exists());
250 
251     final Directory directory2 =
252       new Directory(new File(getDirectory(), "another"));
253     directory2.create();
254     final File file2 = new File(getDirectory(), "another/file");
255     assertTrue(file2.createNewFile());
256 
257     try {
258       directory2.delete();
259       fail("Expected DirectoryException");
260     }
261     catch (final Directory.DirectoryException e) {
262     }
263   }
264 
265   @Test public void testRelativeFileDot() throws Exception {
266     final File result = new Directory().relativeFile(new File("."), false);
267     assertEquals(new File("."), result);
268   }
269 
270   @Test public void testRelativeFileWithAbsoluteFile() throws Exception {
271 
272     final Directory directory = new Directory(getDirectory());
273 
274     final File absoluteFile = new File("blah").getAbsoluteFile();
275 
276     assertNull(directory.relativeFile(absoluteFile, true));
277   }
278 
279   @Test public void relativeFileWithAbsoluteChild1() throws Exception {
280 
281     final File absoluteFile =
282         new File(getDirectory(), "blah").getAbsoluteFile();
283 
284     final Directory directory = new Directory(getDirectory());
285     final File result = directory.relativeFile(absoluteFile, false);
286     assertTrue(!result.isAbsolute());
287     assertEquals("blah", result.getPath());
288   }
289 
290   @Test public void testRelativeFileWithAbsouteChild2() throws Exception {
291 
292     final File absoluteFile =
293         new File(getDirectory(), "blah").getAbsoluteFile();
294 
295     final Directory directory = new Directory(getDirectory());
296     final File result = directory.relativeFile(absoluteFile, true);
297     assertTrue(!result.isAbsolute());
298     assertEquals("blah", result.getPath());
299   }
300 
301   @Test public void testRelativeFileWithRelativeChild() throws Exception {
302 
303     final File relaiveFile = new File("blah");
304 
305     final Directory directory = new Directory(getDirectory());
306     final File result = directory.relativeFile(relaiveFile, true);
307     assertTrue(!result.isAbsolute());
308     assertEquals("blah", result.getPath());
309   }
310 
311   @Test public void testRelativeFileWithRelativeNonChild1() throws Exception {
312 
313     final File relativeFile = new File("../blah");
314 
315     final Directory directory = new Directory(getDirectory());
316     assertNull(directory.relativeFile(relativeFile, true));
317   }
318 
319   @Test public void testRelativeFileWithRelativeNonChild2() throws Exception {
320 
321     final File relativeFile = new File("../blah");
322 
323     final Directory directory = new Directory(getDirectory());
324     final File result = directory.relativeFile(relativeFile, false);
325     assertSame(relativeFile, result);
326   }
327 
328   @Test public void testIsParentOf() throws Exception {
329     final File f1 = new File("xfoo");
330     final File f2 = new File("xfoo/bah");
331     final File f3 = new File("xfoo/bah/blah");
332     final File f4 = new File("xfoo/bah/dah");
333 
334     assertTrue(new Directory(f1).isParentOf(f2));
335     assertTrue(new Directory(f1).isParentOf(f3));
336 
337     assertFalse(new Directory(f2).isParentOf(f2));
338     assertFalse(new Directory(f2).isParentOf(f1));
339     assertFalse(new Directory(f3).isParentOf(f1));
340     assertFalse(new Directory(f3).isParentOf(f4));
341   }
342 
343   @Test public void testCopyTo() throws Exception {
344     final Set<File> files = new HashSet<File>() {{
345       add(new File("a file"));
346       add(new File("directory/.afile"));
347       add(new File("directory/b/c/d/e"));
348     }};
349 
350     for (final File relativeFile : files) {
351       final File absoluteFile =
352         new File(getDirectory(), relativeFile.getPath());
353 
354       createRandomFile(absoluteFile);
355     }
356 
357     final Directory sourceDirectory = new Directory(getDirectory());
358 
359     final File output = new File(getDirectory(), "output");
360     final Directory outputDirectory = new Directory(output);
361     outputDirectory.create();
362     final File overwritten = new File(output, "should be deleted");
363     createRandomFile(overwritten);
364 
365     assertTrue(overwritten.exists());
366 
367     sourceDirectory.copyTo(outputDirectory, false);
368 
369     assertFalse(overwritten.exists());
370 
371     final File[] contents =
372       outputDirectory.listContents(Directory.getMatchAllFilesFilter());
373 
374     for (final File content : contents) {
375       assertTrue("Original contains '" + content + "'",
376                  files.contains(content));
377     }
378 
379     assertEquals(files.size(), contents.length);
380 
381     sourceDirectory.copyTo(outputDirectory, true);
382 
383     final File[] contents2 =
384       outputDirectory.listContents(Directory.getMatchAllFilesFilter());
385 
386     for (int i = 0; i < contents2.length; ++i) {
387       if (!contents2[i].getPath().startsWith("output")) {
388         assertTrue("Original contains '" + contents2[i] + "'",
389                    files.contains(contents2[i]));
390       }
391     }
392 
393     final File[] contents3 =
394       new Directory(new File("output/output"))
395       .listContents(Directory.getMatchAllFilesFilter());
396 
397     for (final File element : contents3) {
398       assertTrue("Original contains '" + element + "'",
399                  files.contains(element));
400     }
401 
402     assertEquals(files.size() * 2, contents2.length);
403 
404     final Directory missingSourceDirectory =
405       new Directory(sourceDirectory.getFile(new File("missing")));
406 
407     final Directory missingOutputDirectory =
408       new Directory(outputDirectory.getFile(new File("notthere")));
409 
410     assertFalse(missingSourceDirectory.getFile().exists());
411     assertFalse(missingOutputDirectory.getFile().exists());
412 
413     try {
414       missingSourceDirectory.copyTo(missingOutputDirectory, false);
415       fail("Expected DirectoryException");
416     }
417     catch (final Directory.DirectoryException e) {
418     }
419 
420     assertFalse(missingSourceDirectory.getFile().exists());
421     assertFalse(missingOutputDirectory.getFile().exists());
422   }
423 
424   @Test public void testSerialization() throws Exception {
425     final Directory original = new Directory(getDirectory());
426 
427     assertEquals(original, Serializer.serialize(original));
428   }
429 
430   private static File fromPath(String... elements) {
431     File result = null;
432 
433     for (final String e : elements) {
434       result = new File(result, e);
435     }
436 
437     return result;
438   }
439 
440   private static void assertEqualPaths(String expected, String actual) {
441     final String[] expectedElements = expected.split("/");
442     final String[] actualElements = actual.split(File.separator);
443 
444     assertArraysEqual(actual + " equals " + expected,
445                       expectedElements,
446                       actualElements);
447   }
448 
449   @Test public void testRelativePathNotChild1() throws IOException {
450     final File f1 = fromPath("a", "b", "c");
451     final File f2 = fromPath("a", "b", "x", "y");
452 
453     assertEqualPaths("../x/y", Directory.relativePath(f1, f2, false).getPath());
454   }
455 
456   @Test public void testRelativePathNotChild2() throws IOException {
457     final File f1 = fromPath("a", "b", "c");
458     final File f2 = fromPath("a", "b", "x", "y");
459 
460     assertNull(Directory.relativePath(f1, f2, true));
461   }
462 
463   @Test public void testRelativePathDifferentFS1() throws IOException {
464     final File f1 = fromPath("/", "x", "y", "z");
465     final File f2 = fromPath("/", "a", "b");
466 
467     assertNull(Directory.relativePath(f1, f2, false));
468   }
469 
470   @Test public void testRelativePathDifferentFS2() throws IOException {
471     final File f1 = fromPath("/", "x", "y", "z");
472     final File f2 = fromPath("/", "a", "b");
473 
474     assertNull(Directory.relativePath(f1, f2, true));
475   }
476 
477   @Test public void testRelativePathDot1() throws IOException {
478     final File f1 = fromPath(".");
479     final File f2 = fromPath(".");
480 
481     assertEqualPaths(".", Directory.relativePath(f1, f2, false).getPath());
482   }
483 
484   @Test public void testRelativePathDot2() throws IOException {
485     final File f1 = fromPath(".");
486     final File f2 = fromPath(".");
487 
488     assertEqualPaths(".",  Directory.relativePath(f1, f2, true).getPath());
489   }
490 }