View Javadoc
1   package org.codehaus.plexus.util;
2   
3   /*
4    * Copyright The Codehaus Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.File;
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.OutputStream;
24  import java.io.OutputStreamWriter;
25  import java.io.Reader;
26  import java.io.Writer;
27  import java.net.URL;
28  import java.nio.file.Files;
29  import java.nio.file.Paths;
30  import java.util.Properties;
31  
32  import org.junit.jupiter.api.BeforeEach;
33  import org.junit.jupiter.api.Test;
34  
35  import static org.junit.jupiter.api.Assertions.assertEquals;
36  import static org.junit.jupiter.api.Assertions.assertFalse;
37  import static org.junit.jupiter.api.Assertions.assertNotNull;
38  import static org.junit.jupiter.api.Assertions.assertNull;
39  import static org.junit.jupiter.api.Assertions.assertTrue;
40  import static org.junit.jupiter.api.Assertions.fail;
41  
42  /**
43   * This is used to test FileUtils for correctness.
44   *
45   * @author Peter Donald
46   * @author Matthew Hawthorne
47   * @see FileUtils
48   * @version $Id: $Id
49   * @since 3.4.0
50   */
51  public final class FileUtilsTest extends FileBasedTestCase {
52      // Test data
53  
54      /**
55       * Size of test directory.
56       */
57      private static final int TEST_DIRECTORY_SIZE = 0;
58  
59      private final File testFile1;
60  
61      private final File testFile2;
62  
63      private static int testFile1Size;
64  
65      private static int testFile2Size;
66  
67      /**
68       * <p>Constructor for FileUtilsTest.</p>
69       *
70       * @throws java.lang.Exception if any.
71       */
72      public FileUtilsTest() throws Exception {
73          testFile1 = new File(getTestDirectory(), "file1-test.txt");
74          testFile2 = new File(getTestDirectory(), "file1a-test.txt");
75  
76          testFile1Size = (int) testFile1.length();
77          testFile2Size = (int) testFile2.length();
78      }
79  
80      /**
81       * <p>setUp.</p>
82       *
83       * @throws java.lang.Exception if any.
84       */
85      @BeforeEach
86      public void setUp() throws Exception {
87          getTestDirectory().mkdirs();
88          createFile(testFile1, testFile1Size);
89          createFile(testFile2, testFile2Size);
90          FileUtils.deleteDirectory(getTestDirectory());
91          getTestDirectory().mkdirs();
92          createFile(testFile1, testFile1Size);
93          createFile(testFile2, testFile2Size);
94      }
95  
96      // byteCountToDisplaySize
97  
98      /**
99       * <p>testByteCountToDisplaySize.</p>
100      */
101     @Test
102     public void testByteCountToDisplaySize() {
103         assertEquals(FileUtils.byteCountToDisplaySize(0), "0 bytes");
104         assertEquals(FileUtils.byteCountToDisplaySize(1024), "1 KB");
105         assertEquals(FileUtils.byteCountToDisplaySize(1024 * 1024), "1 MB");
106         assertEquals(FileUtils.byteCountToDisplaySize(1024 * 1024 * 1024), "1 GB");
107     }
108 
109     // waitFor
110 
111     /**
112      * <p>testWaitFor.</p>
113      */
114     @Test
115     public void testWaitFor() {
116         FileUtils.waitFor("", -1);
117 
118         FileUtils.waitFor("", 2);
119     }
120 
121     /**
122      * <p>testToFile.</p>
123      *
124      * @throws java.lang.Exception if any.
125      */
126     @Test
127     public void testToFile() throws Exception {
128         URL url = getClass().getResource("/test.txt");
129         url = new URL(url.toString() + "/name%20%23%2520%3F%7B%7D%5B%5D%3C%3E.txt");
130         File file = FileUtils.toFile(url);
131         assertEquals("name #%20?{}[]<>.txt", file.getName());
132     }
133 
134     /**
135      * <p>testToFileBadProtocol.</p>
136      *
137      * @throws java.lang.Exception if any.
138      */
139     @Test
140     public void testToFileBadProtocol() throws Exception {
141         URL url = new URL("http://maven.apache.org/");
142         File file = FileUtils.toFile(url);
143         assertNull(file);
144     }
145 
146     /**
147      * <p>testToFileNull.</p>
148      *
149      * @throws java.lang.Exception if any.
150      */
151     @Test
152     public void testToFileNull() throws Exception {
153         File file = FileUtils.toFile(null);
154         assertNull(file);
155     }
156 
157     // Hacked to sanity by Trygve
158     /**
159      * <p>testToURLs.</p>
160      *
161      * @throws java.lang.Exception if any.
162      */
163     @Test
164     public void testToURLs() throws Exception {
165         File[] files = new File[] {
166             new File("file1"), new File("file2"),
167         };
168 
169         URL[] urls = FileUtils.toURLs(files);
170 
171         assertEquals(
172                 files.length,
173                 urls.length,
174                 "The length of the generated URL's is not equals to the length of files. " + "Was " + files.length
175                         + ", expected " + urls.length);
176 
177         for (int i = 0; i < urls.length; i++) {
178             assertEquals(files[i].toURI().toURL(), urls[i]);
179         }
180     }
181 
182     /**
183      * <p>testGetFilesFromExtension.</p>
184      */
185     @Test
186     public void testGetFilesFromExtension() {
187         // TODO I'm not sure what is supposed to happen here
188         FileUtils.getFilesFromExtension("dir", null);
189 
190         // Non-existent files
191         final String[] emptyFileNames =
192                 FileUtils.getFilesFromExtension(getTestDirectory().getAbsolutePath(), new String[] {"java"});
193         assertTrue(emptyFileNames.length == 0);
194 
195         // Existing files
196         // TODO Figure out how to test this
197         /*
198          * final String[] fileNames = FileUtils.getFilesFromExtension( getClass().getResource("/java/util/").getFile(),
199          * new String[] { "class" }); assertTrue(fileNames.length > 0);
200          */
201     }
202 
203     // mkdir
204 
205     /**
206      * <p>testMkdir.</p>
207      */
208     @Test
209     public void testMkdir() {
210         final File dir = new File(getTestDirectory(), "testdir");
211         FileUtils.mkdir(dir.getAbsolutePath());
212         dir.deleteOnExit();
213 
214         if (Os.isFamily(Os.FAMILY_WINDOWS)) {
215             try {
216                 File winFile = new File(getTestDirectory(), "bla*bla");
217                 winFile.deleteOnExit();
218                 FileUtils.mkdir(winFile.getAbsolutePath());
219                 assertTrue(false);
220             } catch (IllegalArgumentException e) {
221                 assertTrue(true);
222             }
223         }
224     }
225 
226     // contentEquals
227 
228     /**
229      * <p>testContentEquals.</p>
230      *
231      * @throws java.lang.Exception if any.
232      */
233     @Test
234     public void testContentEquals() throws Exception {
235         // Non-existent files
236         final File file = new File(getTestDirectory(), getTestMethodName());
237         assertTrue(FileUtils.contentEquals(file, file));
238 
239         // TODO Should comparing 2 directories throw an Exception instead of returning false?
240         // Directories
241         assertTrue(!FileUtils.contentEquals(getTestDirectory(), getTestDirectory()));
242 
243         // Different files
244         final File objFile1 = new File(getTestDirectory(), getTestMethodName() + ".object");
245         objFile1.deleteOnExit();
246         FileUtils.copyURLToFile(getClass().getResource("/java/lang/Object.class"), objFile1);
247 
248         final File objFile2 = new File(getTestDirectory(), getTestMethodName() + ".collection");
249         objFile2.deleteOnExit();
250         FileUtils.copyURLToFile(getClass().getResource("/java/util/Collection.class"), objFile2);
251 
252         assertTrue(!FileUtils.contentEquals(objFile1, objFile2), "Files should not be equal.");
253 
254         // Equal files
255         file.createNewFile();
256         assertTrue(FileUtils.contentEquals(file, file));
257     }
258 
259     // removePath
260 
261     /**
262      * <p>testRemovePath.</p>
263      */
264     @Test
265     public void testRemovePath() {
266         final String fileName =
267                 FileUtils.removePath(new File(getTestDirectory(), getTestMethodName()).getAbsolutePath());
268         assertEquals(getTestMethodName(), fileName);
269     }
270 
271     // getPath
272 
273     /**
274      * <p>testGetPath.</p>
275      */
276     @Test
277     public void testGetPath() {
278         final String fileName = FileUtils.getPath(new File(getTestDirectory(), getTestMethodName()).getAbsolutePath());
279         assertEquals(getTestDirectory().getAbsolutePath(), fileName);
280     }
281 
282     // copyURLToFile
283 
284     /**
285      * <p>testCopyURLToFile.</p>
286      *
287      * @throws java.lang.Exception if any.
288      */
289     @Test
290     public void testCopyURLToFile() throws Exception {
291         // Creates file
292         final File file = new File(getTestDirectory(), getTestMethodName());
293         file.deleteOnExit();
294 
295         // Loads resource
296         final String resourceName = "/java/lang/Object.class";
297         FileUtils.copyURLToFile(getClass().getResource(resourceName), file);
298 
299         // Tests that resource was copied correctly
300         final InputStream fis = Files.newInputStream(file.toPath());
301         try {
302             assertTrue(
303                     IOUtil.contentEquals(getClass().getResourceAsStream(resourceName), fis), "Content is not equal.");
304         } finally {
305             fis.close();
306         }
307     }
308 
309     // catPath
310 
311     /**
312      * <p>testCatPath.</p>
313      */
314     @Test
315     public void testCatPath() {
316         // TODO StringIndexOutOfBoundsException thrown if file doesn't contain slash.
317         // Is this acceptable?
318         // assertEquals("", FileUtils.catPath("a", "b"));
319 
320         assertEquals("/a/c", FileUtils.catPath("/a/b", "c"));
321         assertEquals("/a/d", FileUtils.catPath("/a/b/c", "../d"));
322     }
323 
324     // forceMkdir
325 
326     /**
327      * <p>testForceMkdir.</p>
328      *
329      * @throws java.lang.Exception if any.
330      */
331     @Test
332     public void testForceMkdir() throws Exception {
333         // Tests with existing directory
334         FileUtils.forceMkdir(getTestDirectory());
335 
336         // Creates test file
337         final File testFile = new File(getTestDirectory(), getTestMethodName());
338         testFile.deleteOnExit();
339         testFile.createNewFile();
340         assertTrue(testFile.exists(), "Test file does not exist.");
341 
342         // Tests with existing file
343         try {
344             FileUtils.forceMkdir(testFile);
345             fail("Exception expected.");
346         } catch (IOException ex) {
347         }
348 
349         testFile.delete();
350 
351         // Tests with non-existent directory
352         FileUtils.forceMkdir(testFile);
353         assertTrue(testFile.exists(), "Directory was not created.");
354 
355         if (Os.isFamily(Os.FAMILY_WINDOWS)) {
356             try {
357                 File winFile = new File(getTestDirectory(), "bla*bla");
358                 winFile.deleteOnExit();
359                 FileUtils.forceMkdir(winFile);
360                 assertTrue(false);
361             } catch (IllegalArgumentException e) {
362                 assertTrue(true);
363             }
364         }
365     }
366 
367     // sizeOfDirectory
368 
369     /**
370      * <p>testSizeOfDirectory.</p>
371      *
372      * @throws java.lang.Exception if any.
373      */
374     @Test
375     public void testSizeOfDirectory() throws Exception {
376         final File file = new File(getTestDirectory(), getTestMethodName());
377 
378         // Non-existent file
379         try {
380             FileUtils.sizeOfDirectory(file);
381             fail("Exception expected.");
382         } catch (IllegalArgumentException ex) {
383         }
384 
385         // Creates file
386         file.createNewFile();
387         file.deleteOnExit();
388 
389         // Existing file
390         try {
391             FileUtils.sizeOfDirectory(file);
392             fail("Exception expected.");
393         } catch (IllegalArgumentException ex) {
394         }
395 
396         // Existing directory
397         file.delete();
398         file.mkdir();
399 
400         assertEquals(TEST_DIRECTORY_SIZE, FileUtils.sizeOfDirectory(file), "Unexpected directory size");
401     }
402 
403     // isFileNewer
404 
405     // TODO Finish test
406 
407     /**
408      * <p>XtestIsFileNewer.</p>
409      */
410     public void XtestIsFileNewer() {}
411 
412     // copyFile
413     /**
414      * <p>testCopyFile1.</p>
415      *
416      * @throws java.lang.Exception if any.
417      */
418     @Test
419     public void testCopyFile1() throws Exception {
420         final File destination = new File(getTestDirectory(), "copy1.txt");
421         FileUtils.copyFile(testFile1, destination);
422         assertTrue(destination.exists(), "Check Exist");
423         assertTrue(destination.length() == testFile1Size, "Check Full copy");
424     }
425 
426     /**
427      * <p>testCopyFile2.</p>
428      *
429      * @throws java.lang.Exception if any.
430      */
431     @Test
432     public void testCopyFile2() throws Exception {
433         final File destination = new File(getTestDirectory(), "copy2.txt");
434         FileUtils.copyFile(testFile1, destination);
435         assertTrue(destination.exists(), "Check Exist");
436         assertTrue(destination.length() == testFile2Size, "Check Full copy");
437     }
438 
439     /**
440      * ensure we create directory tree for destination
441      *
442      * @throws java.lang.Exception
443      */
444     @Test
445     public void testCopyFile3() throws Exception {
446         File destDirectory = new File(getTestDirectory(), "foo/bar/testcopy");
447         if (destDirectory.exists()) {
448             destDirectory.delete();
449         }
450         final File destination = new File(destDirectory, "copy2.txt");
451         FileUtils.copyFile(testFile1, destination);
452         assertTrue(destination.exists(), "Check Exist");
453         assertTrue(destination.length() == testFile2Size, "Check Full copy");
454     }
455 
456     // linkFile
457     /**
458      * <p>testLinkFile1.</p>
459      *
460      * @throws java.lang.Exception if any.
461      */
462     @Test
463     public void testLinkFile1() throws Exception {
464         final File destination = new File(getTestDirectory(), "link1.txt");
465         FileUtils.linkFile(testFile1, destination);
466         assertTrue(destination.exists(), "Check Exist");
467         assertTrue(destination.length() == testFile1Size, "Check File length");
468         assertTrue(Files.isSymbolicLink(destination.toPath()), "Check is link");
469     }
470 
471     /**
472      * <p>testLinkFile2.</p>
473      *
474      * @throws java.lang.Exception if any.
475      */
476     @Test
477     public void testLinkFile2() throws Exception {
478         final File destination = new File(getTestDirectory(), "link2.txt");
479         FileUtils.linkFile(testFile1, destination);
480         assertTrue(destination.exists(), "Check Exist");
481         assertTrue(destination.length() == testFile2Size, "Check File length");
482         assertTrue(Files.isSymbolicLink(destination.toPath()), "Check is link");
483     }
484 
485     /**
486      * ensure we create directory tree for destination
487      *
488      * @throws java.lang.Exception
489      */
490     @Test
491     public void testLinkFile3() throws Exception {
492         File destDirectory = new File(getTestDirectory(), "foo/bar/testlink");
493         if (destDirectory.exists()) {
494             destDirectory.delete();
495         }
496         final File destination = new File(destDirectory, "link2.txt");
497         FileUtils.linkFile(testFile1, destination);
498         assertTrue(destination.exists(), "Check Exist");
499         assertTrue(destination.length() == testFile2Size, "Check File length");
500         assertTrue(Files.isSymbolicLink(destination.toPath()), "Check is link");
501     }
502 
503     // copyFileIfModified
504 
505     /**
506      * <p>testCopyIfModifiedWhenSourceIsNewer.</p>
507      *
508      * @throws java.lang.Exception if any.
509      */
510     @Test
511     public void testCopyIfModifiedWhenSourceIsNewer() throws Exception {
512         FileUtils.forceMkdir(new File(getTestDirectory() + "/temp"));
513 
514         // Place destination
515         File destination = new File(getTestDirectory() + "/temp/copy1.txt");
516         FileUtils.copyFile(testFile1, destination);
517 
518         // Make sure source is newer
519         reallySleep(1000);
520 
521         // Place source
522         File source = new File(getTestDirectory(), "copy1.txt");
523         FileUtils.copyFile(testFile1, source);
524         source.setLastModified(System.currentTimeMillis());
525 
526         // Copy will occur when source is newer
527         assertTrue(
528                 FileUtils.copyFileIfModified(source, destination),
529                 "Failed copy. Target file should have been updated.");
530     }
531 
532     /**
533      * <p>testCopyIfModifiedWhenSourceIsOlder.</p>
534      *
535      * @throws java.lang.Exception if any.
536      */
537     @Test
538     public void testCopyIfModifiedWhenSourceIsOlder() throws Exception {
539         FileUtils.forceMkdir(new File(getTestDirectory() + "/temp"));
540 
541         // Place source
542         File source = new File(getTestDirectory() + "copy1.txt");
543         FileUtils.copyFile(testFile1, source);
544 
545         // Make sure destination is newer
546         reallySleep(1000);
547 
548         // Place destination
549         File destination = new File(getTestDirectory(), "/temp/copy1.txt");
550         FileUtils.copyFile(testFile1, destination);
551 
552         // Copy will occur when destination is newer
553         assertFalse(FileUtils.copyFileIfModified(source, destination), "Source file should not have been copied.");
554     }
555 
556     /**
557      * <p>testCopyIfModifiedWhenSourceHasZeroDate.</p>
558      *
559      * @throws java.lang.Exception if any.
560      */
561     @Test
562     public void testCopyIfModifiedWhenSourceHasZeroDate() throws Exception {
563         FileUtils.forceMkdir(new File(getTestDirectory(), "temp"));
564 
565         // Source modified on 1970-01-01T00:00Z
566         File source = new File(getTestDirectory(), "copy1.txt");
567         FileUtils.copyFile(testFile1, source);
568         source.setLastModified(0L);
569 
570         // A non existing destination
571         File destination = new File(getTestDirectory(), "temp/copy1.txt");
572 
573         // Should copy the source to the non existing destination.
574         assertTrue(FileUtils.copyFileIfModified(source, destination), "Source file should have been copied.");
575     }
576 
577     // forceDelete
578 
579     /**
580      * <p>testForceDeleteAFile1.</p>
581      *
582      * @throws java.lang.Exception if any.
583      */
584     @Test
585     public void testForceDeleteAFile1() throws Exception {
586         final File destination = new File(getTestDirectory(), "copy1.txt");
587         destination.createNewFile();
588         assertTrue(destination.exists(), "Copy1.txt doesn't exist to delete");
589         FileUtils.forceDelete(destination);
590         assertTrue(!destination.exists(), "Check No Exist");
591     }
592 
593     /**
594      * <p>testForceDeleteAFile2.</p>
595      *
596      * @throws java.lang.Exception if any.
597      */
598     @Test
599     public void testForceDeleteAFile2() throws Exception {
600         final File destination = new File(getTestDirectory(), "copy2.txt");
601         destination.createNewFile();
602         assertTrue(destination.exists(), "Copy2.txt doesn't exist to delete");
603         FileUtils.forceDelete(destination);
604         assertTrue(!destination.exists(), "Check No Exist");
605     }
606 
607     // copyFileToDirectory
608 
609     /**
610      * <p>testCopyFile1ToDir.</p>
611      *
612      * @throws java.lang.Exception if any.
613      */
614     @Test
615     public void testCopyFile1ToDir() throws Exception {
616         final File directory = new File(getTestDirectory(), "subdir");
617         if (!directory.exists()) {
618             directory.mkdirs();
619         }
620         final File destination = new File(directory, testFile1.getName());
621         FileUtils.copyFileToDirectory(testFile1, directory);
622         assertTrue(destination.exists(), "Check Exist");
623         assertTrue(destination.length() == testFile1Size, "Check Full copy");
624     }
625 
626     /**
627      * <p>testCopyFile2ToDir.</p>
628      *
629      * @throws java.lang.Exception if any.
630      */
631     @Test
632     public void testCopyFile2ToDir() throws Exception {
633         final File directory = new File(getTestDirectory(), "subdir");
634         if (!directory.exists()) {
635             directory.mkdirs();
636         }
637         final File destination = new File(directory, testFile1.getName());
638         FileUtils.copyFileToDirectory(testFile1, directory);
639         assertTrue(destination.exists(), "Check Exist");
640         assertTrue(destination.length() == testFile2Size, "Check Full copy");
641     }
642 
643     // copyFileToDirectoryIfModified
644 
645     /**
646      * <p>testCopyFile1ToDirIfModified.</p>
647      *
648      * @throws java.lang.Exception if any.
649      */
650     @Test
651     public void testCopyFile1ToDirIfModified() throws Exception {
652         final File directory = new File(getTestDirectory(), "subdir");
653         if (directory.exists()) {
654             FileUtils.forceDelete(directory);
655         }
656         directory.mkdirs();
657 
658         final File destination = new File(directory, testFile1.getName());
659 
660         FileUtils.copyFileToDirectoryIfModified(testFile1, directory);
661 
662         final File target = new File(getTestDirectory() + "/subdir", testFile1.getName());
663         long timestamp = target.lastModified();
664 
665         assertTrue(destination.exists(), "Check Exist");
666         assertTrue(destination.length() == testFile1Size, "Check Full copy");
667 
668         FileUtils.copyFileToDirectoryIfModified(testFile1, directory);
669 
670         assertTrue(timestamp == target.lastModified(), "Timestamp was changed");
671     }
672 
673     /**
674      * <p>testCopyFile2ToDirIfModified.</p>
675      *
676      * @throws java.lang.Exception if any.
677      */
678     @Test
679     public void testCopyFile2ToDirIfModified() throws Exception {
680         final File directory = new File(getTestDirectory(), "subdir");
681         if (directory.exists()) {
682             FileUtils.forceDelete(directory);
683         }
684         directory.mkdirs();
685 
686         final File destination = new File(directory, testFile2.getName());
687 
688         FileUtils.copyFileToDirectoryIfModified(testFile2, directory);
689 
690         final File target = new File(getTestDirectory() + "/subdir", testFile2.getName());
691         long timestamp = target.lastModified();
692 
693         assertTrue(destination.exists(), "Check Exist");
694         assertTrue(destination.length() == testFile2Size, "Check Full copy");
695 
696         FileUtils.copyFileToDirectoryIfModified(testFile2, directory);
697 
698         assertTrue(timestamp == target.lastModified(), "Timestamp was changed");
699     }
700 
701     // forceDelete
702 
703     /**
704      * <p>testForceDeleteDir.</p>
705      *
706      * @throws java.lang.Exception if any.
707      */
708     @org.junit.jupiter.api.Test
709     public void testForceDeleteDir() throws Exception {
710         FileUtils.forceDelete(getTestDirectory().getParentFile());
711         assertTrue(!getTestDirectory().getParentFile().exists(), "Check No Exist");
712     }
713 
714     // resolveFile
715 
716     /**
717      * <p>testResolveFileDotDot.</p>
718      *
719      * @throws java.lang.Exception if any.
720      */
721     @Test
722     public void testResolveFileDotDot() throws Exception {
723         final File file = FileUtils.resolveFile(getTestDirectory(), "..");
724         assertEquals(file, getTestDirectory().getParentFile(), "Check .. operator");
725     }
726 
727     /**
728      * <p>testResolveFileDot.</p>
729      *
730      * @throws java.lang.Exception if any.
731      */
732     @Test
733     public void testResolveFileDot() throws Exception {
734         final File file = FileUtils.resolveFile(getTestDirectory(), ".");
735         assertEquals(file, getTestDirectory(), "Check . operator");
736     }
737 
738     // normalize
739 
740     /**
741      * <p>testNormalize.</p>
742      *
743      * @throws java.lang.Exception if any.
744      */
745     @Test
746     public void testNormalize() throws Exception {
747         final String[] src = {
748             "",
749             "/",
750             "///",
751             "/foo",
752             "/foo//",
753             "/./",
754             "/foo/./",
755             "/foo/./bar",
756             "/foo/../bar",
757             "/foo/../bar/../baz",
758             "/foo/bar/../../baz",
759             "/././",
760             "/foo/./../bar",
761             "/foo/.././bar/",
762             "//foo//./bar",
763             "/../",
764             "/foo/../../"
765         };
766 
767         final String[] dest = {
768             "",
769             "/",
770             "/",
771             "/foo",
772             "/foo/",
773             "/",
774             "/foo/",
775             "/foo/bar",
776             "/bar",
777             "/baz",
778             "/baz",
779             "/",
780             "/bar",
781             "/bar/",
782             "/foo/bar",
783             null,
784             null
785         };
786 
787         assertEquals(src.length, dest.length, "Oops, test writer goofed");
788 
789         for (int i = 0; i < src.length; i++) {
790             assertEquals(
791                     dest[i], FileUtils.normalize(src[i]), "Check if '" + src[i] + "' normalized to '" + dest[i] + "'");
792         }
793     }
794 
795     private String replaceAll(String text, String lookFor, String replaceWith) {
796         StringBuilder sb = new StringBuilder(text);
797         while (true) {
798             int idx = sb.indexOf(lookFor);
799             if (idx < 0) {
800                 break;
801             }
802             sb.replace(idx, idx + lookFor.length(), replaceWith);
803         }
804         return sb.toString();
805     }
806 
807     /**
808      * Test the FileUtils implementation.
809      *
810      * @throws java.lang.Exception if any.
811      */
812     // Used to exist as IOTestCase class
813     @Test
814     public void testFileUtils() throws Exception {
815         // Loads file from classpath
816         final String path = "/test.txt";
817         final URL url = this.getClass().getResource(path);
818         assertNotNull(url, path + " was not found.");
819 
820         final String filename = Paths.get(url.toURI()).toString();
821         final String filename2 = "test2.txt";
822 
823         assertTrue(FileUtils.getExtension(filename).equals("txt"), "test.txt extension == \"txt\"");
824 
825         assertTrue(FileUtils.fileExists(filename), "Test file does exist: " + filename);
826 
827         assertTrue(!FileUtils.fileExists(filename2), "Second test file does not exist");
828 
829         FileUtils.fileWrite(filename2, filename);
830         assertTrue(FileUtils.fileExists(filename2), "Second file was written");
831 
832         final String file2contents = FileUtils.fileRead(filename2);
833         assertTrue(FileUtils.fileRead(filename2).equals(file2contents), "Second file's contents correct");
834 
835         FileUtils.fileAppend(filename2, filename);
836         assertTrue(
837                 FileUtils.fileRead(filename2).equals(file2contents + file2contents), "Second file's contents correct");
838 
839         FileUtils.fileDelete(filename2);
840         assertTrue(!FileUtils.fileExists(filename2), "Second test file does not exist");
841 
842         final String contents = FileUtils.fileRead(filename);
843         assertTrue(contents.equals("This is a test"), "FileUtils.fileRead()");
844     }
845 
846     /**
847      * <p>testGetExtension.</p>
848      */
849     @Test
850     public void testGetExtension() {
851         final String[][] tests = {
852             {"filename.ext", "ext"},
853             {"README", ""},
854             {"domain.dot.com", "com"},
855             {"image.jpeg", "jpeg"},
856             {"folder" + File.separator + "image.jpeg", "jpeg"},
857             {"folder" + File.separator + "README", ""}
858         };
859 
860         for (String[] test : tests) {
861             assertEquals(test[1], FileUtils.getExtension(test[0]));
862             // assertEquals(tests[i][1], FileUtils.extension(tests[i][0]));
863         }
864     }
865 
866     /**
867      * <p>testGetExtensionWithPaths.</p>
868      */
869     @org.junit.jupiter.api.Test
870     public void testGetExtensionWithPaths() {
871         // Since the utilities are based on the separator for the platform
872         // running the test, ensure we are using the right separator
873         final String sep = File.separator;
874         final String[][] testsWithPaths = {
875             {sep + "tmp" + sep + "foo" + sep + "filename.ext", "ext"},
876             {"C:" + sep + "temp" + sep + "foo" + sep + "filename.ext", "ext"},
877             {"" + sep + "tmp" + sep + "foo.bar" + sep + "filename.ext", "ext"},
878             {"C:" + sep + "temp" + sep + "foo.bar" + sep + "filename.ext", "ext"},
879             {"" + sep + "tmp" + sep + "foo.bar" + sep + "README", ""},
880             {"C:" + sep + "temp" + sep + "foo.bar" + sep + "README", ""},
881             {".." + sep + "filename.ext", "ext"},
882             {"blabla", ""}
883         };
884         for (String[] testsWithPath : testsWithPaths) {
885             assertEquals(testsWithPath[1], FileUtils.getExtension(testsWithPath[0]));
886             // assertEquals(testsWithPaths[i][1], FileUtils.extension(testsWithPaths[i][0]));
887         }
888     }
889 
890     /**
891      * <p>testRemoveExtension.</p>
892      */
893     @Test
894     public void testRemoveExtension() {
895         final String[][] tests = {
896             {"filename.ext", "filename"},
897             {"first.second.third.ext", "first.second.third"},
898             {"README", "README"},
899             {"domain.dot.com", "domain.dot"},
900             {"image.jpeg", "image"}
901         };
902 
903         for (String[] test : tests) {
904             assertEquals(test[1], FileUtils.removeExtension(test[0]));
905             // assertEquals(tests[i][1], FileUtils.basename(tests[i][0]));
906         }
907     }
908 
909     /* TODO: Reenable this test */
910     /**
911      * <p>testRemoveExtensionWithPaths.</p>
912      */
913     @Test
914     public void testRemoveExtensionWithPaths() {
915         // Since the utilities are based on the separator for the platform
916         // running the test, ensure we are using the right separator
917         final String sep = File.separator;
918         final String[][] testsWithPaths = {
919             {sep + "tmp" + sep + "foo" + sep + "filename.ext", sep + "tmp" + sep + "foo" + sep + "filename"},
920             {
921                 "C:" + sep + "temp" + sep + "foo" + sep + "filename.ext",
922                 "C:" + sep + "temp" + sep + "foo" + sep + "filename"
923             },
924             {sep + "tmp" + sep + "foo.bar" + sep + "filename.ext", sep + "tmp" + sep + "foo.bar" + sep + "filename"},
925             {
926                 "C:" + sep + "temp" + sep + "foo.bar" + sep + "filename.ext",
927                 "C:" + sep + "temp" + sep + "foo.bar" + sep + "filename"
928             },
929             {sep + "tmp" + sep + "foo.bar" + sep + "README", sep + "tmp" + sep + "foo.bar" + sep + "README"},
930             {
931                 "C:" + sep + "temp" + sep + "foo.bar" + sep + "README",
932                 "C:" + sep + "temp" + sep + "foo.bar" + sep + "README"
933             },
934             {".." + sep + "filename.ext", ".." + sep + "filename"}
935         };
936 
937         for (String[] testsWithPath : testsWithPaths) {
938             assertEquals(testsWithPath[1], FileUtils.removeExtension(testsWithPath[0]));
939             // assertEquals(testsWithPaths[i][1], FileUtils.basename(testsWithPaths[i][0]));
940         }
941     }
942 
943     /**
944      * <p>testCopyDirectoryStructureWithAEmptyDirectoryStructure.</p>
945      *
946      * @throws java.lang.Exception if any.
947      */
948     @Test
949     public void testCopyDirectoryStructureWithAEmptyDirectoryStructure() throws Exception {
950         File from = new File(getTestDirectory(), "from");
951 
952         FileUtils.deleteDirectory(from);
953 
954         assertTrue(from.mkdirs());
955 
956         File to = new File(getTestDirectory(), "to");
957 
958         assertTrue(to.mkdirs());
959 
960         FileUtils.copyDirectoryStructure(from, to);
961     }
962 
963     /**
964      * <p>testCopyDirectoryStructureWithAPopulatedStructure.</p>
965      *
966      * @throws java.lang.Exception if any.
967      */
968     @Test
969     public void testCopyDirectoryStructureWithAPopulatedStructure() throws Exception {
970         // Make a structure to copy
971         File from = new File(getTestDirectory(), "from");
972 
973         FileUtils.deleteDirectory(from);
974 
975         File fRoot = new File(from, "root.txt");
976 
977         File d1 = new File(from, "1");
978 
979         File d1_1 = new File(d1, "1_1");
980 
981         File d2 = new File(from, "2");
982 
983         File f2 = new File(d2, "2.txt");
984 
985         File d2_1 = new File(d2, "2_1");
986 
987         File f2_1 = new File(d2_1, "2_1.txt");
988 
989         assertTrue(from.mkdir());
990 
991         assertTrue(d1.mkdir());
992 
993         assertTrue(d1_1.mkdir());
994 
995         assertTrue(d2.mkdir());
996 
997         assertTrue(d2_1.mkdir());
998 
999         createFile(fRoot, 100);
1000 
1001         createFile(f2, 100);
1002 
1003         createFile(f2_1, 100);
1004 
1005         File to = new File(getTestDirectory(), "to");
1006 
1007         assertTrue(to.mkdirs());
1008 
1009         FileUtils.copyDirectoryStructure(from, to);
1010 
1011         checkFile(fRoot, new File(to, "root.txt"));
1012 
1013         assertIsDirectory(new File(to, "1"));
1014 
1015         assertIsDirectory(new File(to, "1/1_1"));
1016 
1017         assertIsDirectory(new File(to, "2"));
1018 
1019         assertIsDirectory(new File(to, "2/2_1"));
1020 
1021         checkFile(f2, new File(to, "2/2.txt"));
1022 
1023         checkFile(f2_1, new File(to, "2/2_1/2_1.txt"));
1024     }
1025 
1026     /**
1027      * <p>testCopyDirectoryStructureIfModified.</p>
1028      *
1029      * @throws java.lang.Exception if any.
1030      */
1031     @Test
1032     public void testCopyDirectoryStructureIfModified() throws Exception {
1033         // Make a structure to copy
1034         File from = new File(getTestDirectory(), "from");
1035 
1036         FileUtils.deleteDirectory(from);
1037 
1038         File fRoot = new File(from, "root.txt");
1039 
1040         File d1 = new File(from, "1");
1041 
1042         File d1_1 = new File(d1, "1_1");
1043 
1044         File d2 = new File(from, "2");
1045 
1046         File f2 = new File(d2, "2.txt");
1047 
1048         File d2_1 = new File(d2, "2_1");
1049 
1050         File f2_1 = new File(d2_1, "2_1.txt");
1051 
1052         assertTrue(from.mkdir());
1053 
1054         assertTrue(d1.mkdir());
1055 
1056         assertTrue(d1_1.mkdir());
1057 
1058         assertTrue(d2.mkdir());
1059 
1060         assertTrue(d2_1.mkdir());
1061 
1062         createFile(fRoot, 100);
1063 
1064         createFile(f2, 100);
1065 
1066         createFile(f2_1, 100);
1067 
1068         File to = new File(getTestDirectory(), "to");
1069 
1070         assertTrue(to.mkdirs());
1071 
1072         FileUtils.copyDirectoryStructureIfModified(from, to);
1073 
1074         File files[] = {new File(to, "root.txt"), new File(to, "2/2.txt"), new File(to, "2/2_1/2_1.txt")};
1075 
1076         long timestamps[] = {files[0].lastModified(), files[1].lastModified(), files[2].lastModified()};
1077 
1078         checkFile(fRoot, files[0]);
1079 
1080         assertIsDirectory(new File(to, "1"));
1081 
1082         assertIsDirectory(new File(to, "1/1_1"));
1083 
1084         assertIsDirectory(new File(to, "2"));
1085 
1086         assertIsDirectory(new File(to, "2/2_1"));
1087 
1088         checkFile(f2, files[1]);
1089 
1090         checkFile(f2_1, files[2]);
1091 
1092         FileUtils.copyDirectoryStructureIfModified(from, to);
1093 
1094         assertTrue(timestamps[0] == files[0].lastModified(), "Unmodified file was overwritten");
1095         assertTrue(timestamps[1] == files[1].lastModified(), "Unmodified file was overwritten");
1096         assertTrue(timestamps[2] == files[2].lastModified(), "Unmodified file was overwritten");
1097 
1098         files[1].setLastModified(f2.lastModified() - 5000L);
1099         timestamps[1] = files[1].lastModified();
1100 
1101         FileUtils.copyDirectoryStructureIfModified(from, to);
1102 
1103         assertTrue(timestamps[0] == files[0].lastModified(), "Unmodified file was overwritten");
1104         assertTrue(timestamps[1] < files[1].lastModified(), "Outdated file was not overwritten");
1105         assertTrue(timestamps[2] == files[2].lastModified(), "Unmodified file was overwritten");
1106     }
1107 
1108     /**
1109      * <p>testCopyDirectoryStructureToSelf.</p>
1110      *
1111      * @throws java.lang.Exception if any.
1112      */
1113     @Test
1114     public void testCopyDirectoryStructureToSelf() throws Exception {
1115         // Make a structure to copy
1116         File toFrom = new File(getTestDirectory(), "tofrom");
1117 
1118         FileUtils.deleteDirectory(toFrom);
1119 
1120         File fRoot = new File(toFrom, "root.txt");
1121 
1122         File dSub = new File(toFrom, "subdir");
1123 
1124         File f1 = new File(dSub, "notempty.txt");
1125 
1126         File dSubSub = new File(dSub, "subsubdir");
1127 
1128         File f2 = new File(dSubSub, "notemptytoo.txt");
1129 
1130         assertTrue(toFrom.mkdir());
1131 
1132         assertTrue(dSub.mkdir());
1133 
1134         assertTrue(dSubSub.mkdir());
1135 
1136         createFile(fRoot, 100);
1137 
1138         createFile(f1, 100);
1139 
1140         createFile(f2, 100);
1141 
1142         try {
1143             FileUtils.copyDirectoryStructure(toFrom, toFrom);
1144             fail("An exception must be thrown.");
1145         } catch (IOException e) {
1146             // expected
1147         }
1148     }
1149 
1150     /**
1151      * <p>testFilteredFileCopy.</p>
1152      *
1153      * @throws java.lang.Exception if any.
1154      */
1155     @Test
1156     public void testFilteredFileCopy() throws Exception {
1157         File compareFile = new File(getTestDirectory(), "compare.txt");
1158         FileUtils.fileWrite(compareFile.getAbsolutePath(), "UTF-8", "This is a test.  Test sample text\n");
1159 
1160         File destFile = new File(getTestDirectory(), "target.txt");
1161 
1162         final Properties filterProperties = new Properties();
1163         filterProperties.setProperty("s", "sample text");
1164 
1165         // test ${token}
1166         FileUtils.FilterWrapper[] wrappers1 = new FileUtils.FilterWrapper[] {
1167             new FileUtils.FilterWrapper() {
1168                 public Reader getReader(Reader reader) {
1169                     return new InterpolationFilterReader(reader, filterProperties, "${", "}");
1170                 }
1171             }
1172         };
1173 
1174         File srcFile = new File(getTestDirectory(), "root.txt");
1175         FileUtils.fileWrite(srcFile.getAbsolutePath(), "UTF-8", "This is a test.  Test ${s}\n");
1176 
1177         FileUtils.copyFile(srcFile, destFile, "UTF-8", wrappers1);
1178         assertTrue(FileUtils.contentEquals(compareFile, destFile), "Files should be equal.");
1179 
1180         srcFile.delete();
1181         destFile.delete();
1182         compareFile.delete();
1183     }
1184 
1185     /**
1186      * <p>testFilteredWithoutFilterAndOlderFile.</p>
1187      *
1188      * @throws java.lang.Exception if any.
1189      */
1190     @Test
1191     public void testFilteredWithoutFilterAndOlderFile() throws Exception {
1192         String content = "This is a test.";
1193         File sourceFile = new File(getTestDirectory(), "source.txt");
1194         FileUtils.fileWrite(sourceFile.getAbsolutePath(), "UTF-8", content);
1195 
1196         File destFile = new File(getTestDirectory(), "target.txt");
1197         if (destFile.exists()) {
1198             destFile.delete();
1199         }
1200         FileUtils.copyFile(sourceFile, destFile, null, null);
1201         assertEqualContent(content.getBytes("UTF-8"), destFile);
1202 
1203         String newercontent = "oldercontent";
1204         File olderFile = new File(getTestDirectory(), "oldersource.txt");
1205 
1206         FileUtils.fileWrite(olderFile.getAbsolutePath(), "UTF-8", newercontent);
1207 
1208         // very old file ;-)
1209         olderFile.setLastModified(1);
1210         destFile = new File(getTestDirectory(), "target.txt");
1211         FileUtils.copyFile(olderFile, destFile, null, null);
1212         String destFileContent = FileUtils.fileRead(destFile, "UTF-8");
1213         assertEquals(content, destFileContent);
1214     }
1215 
1216     /**
1217      * <p>testFilteredWithoutFilterAndOlderFileAndOverwrite.</p>
1218      *
1219      * @throws java.lang.Exception if any.
1220      */
1221     @Test
1222     public void testFilteredWithoutFilterAndOlderFileAndOverwrite() throws Exception {
1223         String content = "This is a test.";
1224         File sourceFile = new File(getTestDirectory(), "source.txt");
1225         FileUtils.fileWrite(sourceFile.getAbsolutePath(), "UTF-8", content);
1226 
1227         File destFile = new File(getTestDirectory(), "target.txt");
1228         if (destFile.exists()) {
1229             destFile.delete();
1230         }
1231         FileUtils.copyFile(sourceFile, destFile, null, null);
1232         assertEqualContent(content.getBytes("UTF-8"), destFile);
1233 
1234         String newercontent = "oldercontent";
1235         File olderFile = new File(getTestDirectory(), "oldersource.txt");
1236 
1237         FileUtils.fileWrite(olderFile.getAbsolutePath(), "UTF-8", newercontent);
1238 
1239         // very old file ;-)
1240         olderFile.setLastModified(1);
1241         destFile = new File(getTestDirectory(), "target.txt");
1242         FileUtils.copyFile(olderFile, destFile, null, null, true);
1243         String destFileContent = FileUtils.fileRead(destFile, "UTF-8");
1244         assertEquals(newercontent, destFileContent);
1245     }
1246 
1247     /**
1248      * <p>testFileRead.</p>
1249      *
1250      * @throws java.io.IOException if any.
1251      */
1252     @Test
1253     public void testFileRead() throws IOException {
1254         File testFile = new File(getTestDirectory(), "testFileRead.txt");
1255         String testFileName = testFile.getAbsolutePath();
1256         /*
1257          * NOTE: The method under test uses the JVM's default encoding which by its nature varies from machine to
1258          * machine. As a consequence, we cannot know in advance which characters are supported by the effective encoding
1259          * of the test runner. Therefore this test must be restricted to ASCII characters which are reasonably safe to
1260          * survive the roundtrip test.
1261          */
1262         String testString = "Only US-ASCII characters here, see comment above!";
1263         Writer writer = null;
1264         try {
1265             writer = new OutputStreamWriter(Files.newOutputStream(testFile.toPath()));
1266             writer.write(testString);
1267             writer.flush();
1268         } finally {
1269             IOUtil.close(writer);
1270         }
1271         assertEquals(testString, FileUtils.fileRead(testFile), "testString should be equal");
1272         assertEquals(testString, FileUtils.fileRead(testFileName), "testString should be equal");
1273         testFile.delete();
1274     }
1275 
1276     /**
1277      * <p>testFileReadWithEncoding.</p>
1278      *
1279      * @throws java.io.IOException if any.
1280      */
1281     @Test
1282     public void testFileReadWithEncoding() throws IOException {
1283         String encoding = "UTF-8";
1284         File testFile = new File(getTestDirectory(), "testFileRead.txt");
1285         String testFileName = testFile.getAbsolutePath();
1286         // unicode escaped Japanese hiragana, "aiueo" + Umlaut a
1287         String testString = "\u3042\u3044\u3046\u3048\u304a\u00e4";
1288         Writer writer = null;
1289         try {
1290             writer = new OutputStreamWriter(Files.newOutputStream(testFile.toPath()), encoding);
1291             writer.write(testString);
1292             writer.flush();
1293         } finally {
1294             IOUtil.close(writer);
1295         }
1296         assertEquals(testString, FileUtils.fileRead(testFile, "UTF-8"), "testString should be equal");
1297         assertEquals(testString, FileUtils.fileRead(testFileName, "UTF-8"), "testString should be equal");
1298         testFile.delete();
1299     }
1300 
1301     /**
1302      * <p>testFileAppend.</p>
1303      *
1304      * @throws java.io.IOException if any.
1305      */
1306     @Test
1307     public void testFileAppend() throws IOException {
1308         String baseString = "abc";
1309         File testFile = new File(getTestDirectory(), "testFileAppend.txt");
1310         String testFileName = testFile.getAbsolutePath();
1311         Writer writer = null;
1312         try {
1313             writer = new OutputStreamWriter(Files.newOutputStream(testFile.toPath()));
1314             writer.write(baseString);
1315             writer.flush();
1316         } finally {
1317             IOUtil.close(writer);
1318         }
1319         // unicode escaped Japanese hiragana, "aiueo" + Umlaut a
1320         String testString = "\u3042\u3044\u3046\u3048\u304a\u00e4";
1321         FileUtils.fileAppend(testFileName, testString);
1322         assertEqualContent((baseString + testString).getBytes(), testFile);
1323         testFile.delete();
1324     }
1325 
1326     /**
1327      * <p>testFileAppendWithEncoding.</p>
1328      *
1329      * @throws java.io.IOException if any.
1330      */
1331     @Test
1332     public void testFileAppendWithEncoding() throws IOException {
1333         String baseString = "abc";
1334         String encoding = "UTF-8";
1335         File testFile = new File(getTestDirectory(), "testFileAppend.txt");
1336         String testFileName = testFile.getAbsolutePath();
1337         Writer writer = null;
1338         try {
1339             writer = new OutputStreamWriter(Files.newOutputStream(testFile.toPath()), encoding);
1340             writer.write(baseString);
1341             writer.flush();
1342         } finally {
1343             IOUtil.close(writer);
1344         }
1345         // unicode escaped Japanese hiragana, "aiueo" + Umlaut a
1346         String testString = "\u3042\u3044\u3046\u3048\u304a\u00e4";
1347         FileUtils.fileAppend(testFileName, encoding, testString);
1348         assertEqualContent((baseString + testString).getBytes(encoding), testFile);
1349         testFile.delete();
1350     }
1351 
1352     /**
1353      * <p>testFileWrite.</p>
1354      *
1355      * @throws java.io.IOException if any.
1356      */
1357     @Test
1358     public void testFileWrite() throws IOException {
1359         File testFile = new File(getTestDirectory(), "testFileWrite.txt");
1360         String testFileName = testFile.getAbsolutePath();
1361         // unicode escaped Japanese hiragana, "aiueo" + Umlaut a
1362         String testString = "\u3042\u3044\u3046\u3048\u304a\u00e4";
1363         FileUtils.fileWrite(testFileName, testString);
1364         assertEqualContent(testString.getBytes(), testFile);
1365         testFile.delete();
1366     }
1367 
1368     /**
1369      * <p>testFileWriteWithEncoding.</p>
1370      *
1371      * @throws java.io.IOException if any.
1372      */
1373     @Test
1374     public void testFileWriteWithEncoding() throws IOException {
1375         String encoding = "UTF-8";
1376         File testFile = new File(getTestDirectory(), "testFileWrite.txt");
1377         String testFileName = testFile.getAbsolutePath();
1378         // unicode escaped Japanese hiragana, "aiueo" + Umlaut a
1379         String testString = "\u3042\u3044\u3046\u3048\u304a\u00e4";
1380         FileUtils.fileWrite(testFileName, encoding, testString);
1381         assertEqualContent(testString.getBytes(encoding), testFile);
1382         testFile.delete();
1383     }
1384 
1385     /**
1386      * Workaround for the following Sun bugs. They are fixed in JDK 6u1 and JDK 5u11.
1387      *
1388      * @throws java.lang.Exception
1389      * @see <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4403166">Sun bug id=4403166</a>
1390      * @see <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6182812">Sun bug id=6182812</a>
1391      * @see <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6481955">Sun bug id=6481955</a>
1392      */
1393     @Test
1394     public void testDeleteLongPathOnWindows() throws Exception {
1395         if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
1396             return;
1397         }
1398 
1399         File a = new File(getTestDirectory(), "longpath");
1400         a.mkdir();
1401         File a1 = new File(a, "a");
1402         a1.mkdir();
1403 
1404         StringBuilder path = new StringBuilder("");
1405         for (int i = 0; i < 100; i++) {
1406             path.append("../a/");
1407         }
1408 
1409         File f = new File(a1, path.toString() + "test.txt");
1410 
1411         InputStream is = new ByteArrayInputStream("Blabla".getBytes("UTF-8"));
1412         OutputStream os = Files.newOutputStream(f.getCanonicalFile().toPath());
1413         IOUtil.copy(is, os);
1414         IOUtil.close(is);
1415         IOUtil.close(os);
1416 
1417         FileUtils.forceDelete(f);
1418 
1419         File f1 = new File(a1, "test.txt");
1420         if (f1.exists()) {
1421             throw new Exception("Unable to delete the file :" + f1.getAbsolutePath());
1422         }
1423     }
1424 
1425     // Test for bug PLXUTILS-10
1426     /**
1427      * <p>testCopyFileOnSameFile.</p>
1428      *
1429      * @throws java.io.IOException if any.
1430      */
1431     @Test
1432     public void testCopyFileOnSameFile() throws IOException {
1433         String content = "ggrgreeeeeeeeeeeeeeeeeeeeeeeoierjgioejrgiojregioejrgufcdxivbsdibgfizgerfyaezgv!zeez";
1434         final File theFile = File.createTempFile("test", ".txt");
1435         theFile.deleteOnExit();
1436         FileUtils.fileAppend(theFile.getAbsolutePath(), content);
1437 
1438         assertTrue(theFile.length() > 0);
1439         // Now copy file over itself
1440         FileUtils.copyFile(theFile, theFile);
1441 
1442         // This should not fail
1443         assertTrue(theFile.length() > 0);
1444     }
1445 
1446     /**
1447      * <p>testExtensions.</p>
1448      *
1449      * @throws java.lang.Exception if any.
1450      */
1451     @Test
1452     public void testExtensions() throws Exception {
1453 
1454         String[][] values = {
1455             {"fry.frozen", "frozen"},
1456             {"fry", ""},
1457             {"fry.", ""},
1458             {"/turanga/leela/meets.fry", "fry"},
1459             {"/3000/turanga.leela.fry/zoidberg.helps", "helps"},
1460             {"/3000/turanga.leela.fry/zoidberg.", ""},
1461             {"/3000/turanga.leela.fry/zoidberg", ""},
1462             {"/3000/leela.fry.bender/", ""},
1463             {"/3000/leela.fry.bdner/.", ""},
1464             {"/3000/leela.fry.bdner/foo.bar.txt", "txt"}
1465         };
1466 
1467         for (int i = 0; i < values.length; i++) {
1468             String fileName = values[i][0].replace('/', File.separatorChar);
1469             String ext = values[i][1];
1470             String computed = FileUtils.extension(fileName);
1471             assertEquals(ext, computed, "case [" + i + "]:" + fileName + " -> " + ext + ", computed : " + computed);
1472         }
1473     }
1474 
1475     /**
1476      * <p>testIsValidWindowsFileName.</p>
1477      *
1478      * @throws java.lang.Exception if any.
1479      */
1480     @Test
1481     public void testIsValidWindowsFileName() throws Exception {
1482         File f = new File("c:\test");
1483         assertTrue(FileUtils.isValidWindowsFileName(f));
1484 
1485         if (Os.isFamily(Os.FAMILY_WINDOWS)) {
1486             f = new File("c:\test\bla:bla");
1487             assertFalse(FileUtils.isValidWindowsFileName(f));
1488             f = new File("c:\test\bla*bla");
1489             assertFalse(FileUtils.isValidWindowsFileName(f));
1490             f = new File("c:\test\bla\"bla");
1491             assertFalse(FileUtils.isValidWindowsFileName(f));
1492             f = new File("c:\test\bla<bla");
1493             assertFalse(FileUtils.isValidWindowsFileName(f));
1494             f = new File("c:\test\bla>bla");
1495             assertFalse(FileUtils.isValidWindowsFileName(f));
1496             f = new File("c:\test\bla|bla");
1497             assertFalse(FileUtils.isValidWindowsFileName(f));
1498             f = new File("c:\test\bla*bla");
1499             assertFalse(FileUtils.isValidWindowsFileName(f));
1500         }
1501     }
1502 
1503     /**
1504      * <p>testDeleteDirectoryWithValidFileSymlink.</p>
1505      *
1506      * @throws java.lang.Exception if any.
1507      */
1508     @Test
1509     public void testDeleteDirectoryWithValidFileSymlink() throws Exception {
1510         File symlinkTarget = new File(getTestDirectory(), "fileSymlinkTarget");
1511         createFile(symlinkTarget, 1);
1512         File symlink = new File(getTestDirectory(), "fileSymlink");
1513         createSymlink(symlink, symlinkTarget);
1514         try {
1515             FileUtils.deleteDirectory(getTestDirectory());
1516         } finally {
1517             /*
1518              * Ensure to cleanup problematic symlink or "mvn clean" will fail
1519              */
1520             symlink.delete();
1521         }
1522         assertTrue(!getTestDirectory().exists(), "Failed to delete test directory");
1523     }
1524 
1525     /**
1526      * <p>testDeleteDirectoryWithValidDirSymlink.</p>
1527      *
1528      * @throws java.lang.Exception if any.
1529      */
1530     @Test
1531     public void testDeleteDirectoryWithValidDirSymlink() throws Exception {
1532         File symlinkTarget = new File(getTestDirectory(), "dirSymlinkTarget");
1533         symlinkTarget.mkdir();
1534         File symlink = new File(getTestDirectory(), "dirSymlink");
1535         createSymlink(symlink, symlinkTarget);
1536         try {
1537             FileUtils.deleteDirectory(getTestDirectory());
1538         } finally {
1539             /*
1540              * Ensure to cleanup problematic symlink or "mvn clean" will fail
1541              */
1542             symlink.delete();
1543         }
1544         assertTrue(!getTestDirectory().exists(), "Failed to delete test directory");
1545     }
1546 
1547     /**
1548      * <p>testDeleteDirectoryWithDanglingSymlink.</p>
1549      *
1550      * @throws java.lang.Exception if any.
1551      */
1552     @Test
1553     public void testDeleteDirectoryWithDanglingSymlink() throws Exception {
1554         File symlinkTarget = new File(getTestDirectory(), "missingSymlinkTarget");
1555         File symlink = new File(getTestDirectory(), "danglingSymlink");
1556         createSymlink(symlink, symlinkTarget);
1557         try {
1558             FileUtils.deleteDirectory(getTestDirectory());
1559         } finally {
1560             /*
1561              * Ensure to cleanup problematic symlink or "mvn clean" will fail
1562              */
1563             symlink.delete();
1564         }
1565         assertTrue(!getTestDirectory().exists(), "Failed to delete test directory");
1566     }
1567 
1568     /**
1569      * <p>testcopyDirectoryLayoutWithExcludesIncludes.</p>
1570      *
1571      * @throws java.lang.Exception if any.
1572      */
1573     @Test
1574     public void testcopyDirectoryLayoutWithExcludesIncludes() throws Exception {
1575         File destination = new File("target", "copyDirectoryStructureWithExcludesIncludes");
1576         if (!destination.exists()) {
1577             destination.mkdirs();
1578         }
1579         FileUtils.cleanDirectory(destination);
1580 
1581         File source = new File("src/test/resources/dir-layout-copy");
1582 
1583         FileUtils.copyDirectoryLayout(source, destination, null, null);
1584 
1585         assertTrue(destination.exists());
1586 
1587         File[] childs = destination.listFiles();
1588         assertEquals(2, childs.length);
1589 
1590         for (File current : childs) {
1591             if (current.getName().endsWith("empty-dir") || current.getName().endsWith("dir1")) {
1592                 if (current.getName().endsWith("dir1")) {
1593                     assertEquals(1, current.listFiles().length);
1594                     assertTrue(current.listFiles()[0].getName().endsWith("dir2"));
1595                 }
1596             } else {
1597                 fail("not empty-dir or dir1");
1598             }
1599         }
1600     }
1601 
1602     /**
1603      * Be sure that {@link org.codehaus.plexus.util.FileUtils#createTempFile(String, String, File)} is always unique.
1604      *
1605      * @throws java.lang.Exception if any
1606      */
1607     @Test
1608     public void testCreateTempFile() throws Exception {
1609         File last = FileUtils.createTempFile("unique", ".tmp", null);
1610         for (int i = 0; i < 10; i++) {
1611             File current = FileUtils.createTempFile("unique", ".tmp", null);
1612             assertTrue(!current.getName().equals(last.getName()), "No unique name: " + current.getName());
1613             last = current;
1614         }
1615     }
1616 
1617     /**
1618      * Because windows(tm) quite frequently sleeps less than the advertised time
1619      *
1620      * @param time The amount of time to sleep
1621      * @throws InterruptedException
1622      */
1623     private void reallySleep(int time) throws InterruptedException {
1624         long until = System.currentTimeMillis() + time;
1625         Thread.sleep(time);
1626         while (System.currentTimeMillis() < until) {
1627             Thread.sleep(time / 10);
1628             Thread.yield();
1629         }
1630     }
1631 }