1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.io;
18  
19  import java.io.File;
20  import java.io.FileInputStream;
21  import java.io.FileNotFoundException;
22  import java.io.FileOutputStream;
23  import java.io.IOException;
24  import java.io.OutputStream;
25  import java.net.URL;
26  import java.util.ArrayList;
27  import java.util.Arrays;
28  import java.util.Collection;
29  import java.util.Date;
30  import java.util.GregorianCalendar;
31  import java.util.HashMap;
32  import java.util.Iterator;
33  import java.util.List;
34  import java.util.Map;
35  import java.util.zip.CRC32;
36  import java.util.zip.Checksum;
37  
38  import junit.framework.Test;
39  import junit.framework.TestSuite;
40  import junit.textui.TestRunner;
41  
42  import org.apache.commons.io.filefilter.NameFileFilter;
43  import org.apache.commons.io.filefilter.WildcardFileFilter;
44  import org.apache.commons.io.testtools.FileBasedTestCase;
45  
46  /**
47   * This is used to test FileUtils for correctness.
48   *
49   * @author Peter Donald
50   * @author Matthew Hawthorne
51   * @author Stephen Colebourne
52   * @author Jim Harrington
53   * @version $Id: FileUtilsTestCase.java 619188 2008-02-06 22:33:04Z niallp $
54   * @see FileUtils
55   */
56  public class FileUtilsTestCase extends FileBasedTestCase {
57  
58      // Test data
59  
60      /**
61       * Size of test directory.
62       */
63      private static final int TEST_DIRECTORY_SIZE = 0;
64      
65      /**
66       * List files recursively
67       */
68      private static final ListDirectoryWalker LIST_WALKER = new ListDirectoryWalker();
69  
70      /** Delay in milliseconds to make sure test for "last modified date" are accurate */
71      //private static final int LAST_MODIFIED_DELAY = 600;
72  
73      private File testFile1;
74      private File testFile2;
75  
76      private static int testFile1Size;
77      private static int testFile2Size;
78  
79      public static void main(String[] args) {
80          TestRunner.run(suite());
81      }
82  
83      public static Test suite() {
84          return new TestSuite(FileUtilsTestCase.class);
85      }
86  
87      public FileUtilsTestCase(String name) throws IOException {
88          super(name);
89  
90          testFile1 = new File(getTestDirectory(), "file1-test.txt");
91          testFile2 = new File(getTestDirectory(), "file1a-test.txt");
92  
93          testFile1Size = (int)testFile1.length();
94          testFile2Size = (int)testFile2.length();
95      }
96  
97      /** @see junit.framework.TestCase#setUp() */
98      protected void setUp() throws Exception {
99          getTestDirectory().mkdirs();
100         createFile(testFile1, testFile1Size);
101         createFile(testFile2, testFile2Size);
102         FileUtils.deleteDirectory(getTestDirectory());
103         getTestDirectory().mkdirs();
104         createFile(testFile1, testFile1Size);
105         createFile(testFile2, testFile2Size);
106     }
107 
108     /** @see junit.framework.TestCase#tearDown() */
109     protected void tearDown() throws Exception {
110         FileUtils.deleteDirectory(getTestDirectory());
111     }
112 
113     //-----------------------------------------------------------------------
114     public void test_openInputStream_exists() throws Exception {
115         File file = new File(getTestDirectory(), "test.txt");
116         createLineBasedFile(file, new String[] {"Hello"});
117         FileInputStream in = null;
118         try {
119             in = FileUtils.openInputStream(file);
120             assertEquals('H', in.read());
121         } finally {
122             IOUtils.closeQuietly(in);
123         }
124     }
125 
126     public void test_openInputStream_existsButIsDirectory() throws Exception {
127         File directory = new File(getTestDirectory(), "subdir");
128         directory.mkdirs();
129         FileInputStream in = null;
130         try {
131             in = FileUtils.openInputStream(directory);
132             fail();
133         } catch (IOException ioe) {
134             // expected
135         } finally {
136             IOUtils.closeQuietly(in);
137         }
138     }
139 
140     public void test_openInputStream_notExists() throws Exception {
141         File directory = new File(getTestDirectory(), "test.txt");
142         FileInputStream in = null;
143         try {
144             in = FileUtils.openInputStream(directory);
145             fail();
146         } catch (IOException ioe) {
147             // expected
148         } finally {
149             IOUtils.closeQuietly(in);
150         }
151     }
152 
153     //-----------------------------------------------------------------------
154     void openOutputStream_noParent(boolean createFile) throws Exception {
155         File file = new File("test.txt");
156         assertNull(file.getParentFile());
157         try {
158             if (createFile) {
159             createLineBasedFile(file, new String[]{"Hello"});}
160             FileOutputStream out = null;
161             try {
162                 out = FileUtils.openOutputStream(file);
163                 out.write(0);
164             } finally {
165                 IOUtils.closeQuietly(out);
166             }
167             assertEquals(true, file.exists());
168         } finally {
169             if (file.delete() == false) {
170                 file.deleteOnExit();
171             }
172         }
173     }
174 
175     public void test_openOutputStream_noParentCreateFile() throws Exception {
176         openOutputStream_noParent(true);
177     }
178 
179     public void test_openOutputStream_noParentNoFile() throws Exception {
180         openOutputStream_noParent(false);
181     }
182 
183 
184     public void test_openOutputStream_exists() throws Exception {
185         File file = new File(getTestDirectory(), "test.txt");
186         createLineBasedFile(file, new String[] {"Hello"});
187         FileOutputStream out = null;
188         try {
189             out = FileUtils.openOutputStream(file);
190             out.write(0);
191         } finally {
192             IOUtils.closeQuietly(out);
193         }
194         assertEquals(true, file.exists());
195     }
196 
197     public void test_openOutputStream_existsButIsDirectory() throws Exception {
198         File directory = new File(getTestDirectory(), "subdir");
199         directory.mkdirs();
200         FileOutputStream out = null;
201         try {
202             out = FileUtils.openOutputStream(directory);
203             fail();
204         } catch (IOException ioe) {
205             // expected
206         } finally {
207             IOUtils.closeQuietly(out);
208         }
209     }
210 
211     public void test_openOutputStream_notExists() throws Exception {
212         File file = new File(getTestDirectory(), "a/test.txt");
213         FileOutputStream out = null;
214         try {
215             out = FileUtils.openOutputStream(file);
216             out.write(0);
217         } finally {
218             IOUtils.closeQuietly(out);
219         }
220         assertEquals(true, file.exists());
221     }
222 
223     public void test_openOutputStream_notExistsCannotCreate() throws Exception {
224         // according to Wikipedia, most filing systems have a 256 limit on filename
225         String longStr =
226             "abcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyz" +
227             "abcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyz" +
228             "abcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyz" +
229             "abcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyz" +
230             "abcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyz" +
231             "abcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyz";  // 300 chars
232         File file = new File(getTestDirectory(), "a/" + longStr + "/test.txt");
233         FileOutputStream out = null;
234         try {
235             out = FileUtils.openOutputStream(file);
236             fail();
237         } catch (IOException ioe) {
238             // expected
239         } finally {
240             IOUtils.closeQuietly(out);
241         }
242     }
243 
244     //-----------------------------------------------------------------------
245     // byteCountToDisplaySize
246     public void testByteCountToDisplaySize() {
247         assertEquals(FileUtils.byteCountToDisplaySize(0), "0 bytes");
248         assertEquals(FileUtils.byteCountToDisplaySize(1024), "1 KB");
249         assertEquals(FileUtils.byteCountToDisplaySize(1024 * 1024), "1 MB");
250         assertEquals(
251             FileUtils.byteCountToDisplaySize(1024 * 1024 * 1024),
252             "1 GB");
253     }
254 
255     //-----------------------------------------------------------------------
256     public void testToFile1() throws Exception {
257         URL url = new URL("file", null, "a/b/c/file.txt");
258         File file = FileUtils.toFile(url);
259         assertEquals(true, file.toString().indexOf("file.txt") >= 0);
260     }
261 
262     public void testToFile2() throws Exception {
263         URL url = new URL("file", null, "a/b/c/file%20n%61me.tx%74");
264         File file = FileUtils.toFile(url);
265         assertEquals(true, file.toString().indexOf("file name.txt") >= 0);
266     }
267 
268     public void testToFile3() throws Exception {
269         assertEquals(null, FileUtils.toFile((URL) null));
270         assertEquals(null, FileUtils.toFile(new URL("http://jakarta.apache.org")));
271     }
272 
273     public void testToFile4() throws Exception {
274         URL url = new URL("file", null, "a/b/c/file%2Xn%61me.txt");
275         try {
276             FileUtils.toFile(url);
277             fail();
278         }  catch (IllegalArgumentException ex) {}
279     }
280 
281     // toFiles
282 
283     public void testToFiles1() throws Exception {
284         URL[] urls = new URL[] {
285             new URL("file", null, "file1.txt"),
286             new URL("file", null, "file2.txt"),
287         };
288         File[] files = FileUtils.toFiles(urls);
289         
290         assertEquals(urls.length, files.length);
291         assertEquals("File: " + files[0], true, files[0].toString().indexOf("file1.txt") >= 0);
292         assertEquals("File: " + files[1], true, files[1].toString().indexOf("file2.txt") >= 0);
293     }
294 
295     public void testToFiles2() throws Exception {
296         URL[] urls = new URL[] {
297             new URL("file", null, "file1.txt"),
298             null,
299         };
300         File[] files = FileUtils.toFiles(urls);
301         
302         assertEquals(urls.length, files.length);
303         assertEquals("File: " + files[0], true, files[0].toString().indexOf("file1.txt") >= 0);
304         assertEquals("File: " + files[1], null, files[1]);
305     }
306 
307     public void testToFiles3() throws Exception {
308         URL[] urls = null;
309         File[] files = FileUtils.toFiles(urls);
310         
311         assertEquals(0, files.length);
312     }
313 
314     public void testToFiles4() throws Exception {
315         URL[] urls = new URL[] {
316             new URL("file", null, "file1.txt"),
317             new URL("http", "jakarta.apache.org", "file1.txt"),
318         };
319         try {
320             FileUtils.toFiles(urls);
321             fail();
322         } catch (IllegalArgumentException ex) {}
323     }
324 
325     // toURLs
326 
327     public void testToURLs1() throws Exception {
328         File[] files = new File[] {
329             new File(getTestDirectory(), "file1.txt"),
330             new File(getTestDirectory(), "file2.txt"),
331         };
332         URL[] urls = FileUtils.toURLs(files);
333         
334         assertEquals(files.length, urls.length);
335         assertEquals(true, urls[0].toExternalForm().startsWith("file:"));
336         assertEquals(true, urls[0].toExternalForm().indexOf("file1.txt") >= 0);
337         assertEquals(true, urls[1].toExternalForm().startsWith("file:"));
338         assertEquals(true, urls[1].toExternalForm().indexOf("file2.txt") >= 0);
339     }
340 
341 //    public void testToURLs2() throws Exception {
342 //        File[] files = new File[] {
343 //            new File(getTestDirectory(), "file1.txt"),
344 //            null,
345 //        };
346 //        URL[] urls = FileUtils.toURLs(files);
347 //        
348 //        assertEquals(files.length, urls.length);
349 //        assertEquals(true, urls[0].toExternalForm().startsWith("file:"));
350 //        assertEquals(true, urls[0].toExternalForm().indexOf("file1.txt") > 0);
351 //        assertEquals(null, urls[1]);
352 //    }
353 //
354 //    public void testToURLs3() throws Exception {
355 //        File[] files = null;
356 //        URL[] urls = FileUtils.toURLs(files);
357 //        
358 //        assertEquals(0, urls.length);
359 //    }
360 
361     // contentEquals
362 
363     public void testContentEquals() throws Exception {
364         // Non-existent files
365         File file = new File(getTestDirectory(), getName());
366         File file2 = new File(getTestDirectory(), getName() + "2");
367         // both don't  exist
368         assertTrue(FileUtils.contentEquals(file, file));
369         assertTrue(FileUtils.contentEquals(file, file2));
370         assertTrue(FileUtils.contentEquals(file2, file2));
371         assertTrue(FileUtils.contentEquals(file2, file));
372 
373         // Directories
374         try {
375             FileUtils.contentEquals(getTestDirectory(), getTestDirectory());
376             fail("Comparing directories should fail with an IOException");
377         } catch (IOException ioe) {
378             //expected
379         }
380 
381         // Different files
382         File objFile1 =
383             new File(getTestDirectory(), getName() + ".object");
384         objFile1.deleteOnExit();
385         FileUtils.copyURLToFile(
386             getClass().getResource("/java/lang/Object.class"),
387             objFile1);
388 
389         File objFile1b =
390             new File(getTestDirectory(), getName() + ".object2");
391         objFile1.deleteOnExit();
392         FileUtils.copyURLToFile(
393             getClass().getResource("/java/lang/Object.class"),
394             objFile1b);
395 
396         File objFile2 =
397             new File(getTestDirectory(), getName() + ".collection");
398         objFile2.deleteOnExit();
399         FileUtils.copyURLToFile(
400             getClass().getResource("/java/util/Collection.class"),
401             objFile2);
402 
403         assertEquals(false, FileUtils.contentEquals(objFile1, objFile2));
404         assertEquals(false, FileUtils.contentEquals(objFile1b, objFile2));
405         assertEquals(true, FileUtils.contentEquals(objFile1, objFile1b));
406 
407         assertEquals(true, FileUtils.contentEquals(objFile1, objFile1));
408         assertEquals(true, FileUtils.contentEquals(objFile1b, objFile1b));
409         assertEquals(true, FileUtils.contentEquals(objFile2, objFile2));
410 
411         // Equal files
412         file.createNewFile();
413         file2.createNewFile();
414         assertEquals(true, FileUtils.contentEquals(file, file));
415         assertEquals(true, FileUtils.contentEquals(file, file2));
416     }
417 
418     // copyURLToFile
419 
420     public void testCopyURLToFile() throws Exception {
421         // Creates file
422         File file = new File(getTestDirectory(), getName());
423         file.deleteOnExit();
424 
425         // Loads resource
426         String resourceName = "/java/lang/Object.class";
427         FileUtils.copyURLToFile(getClass().getResource(resourceName), file);
428 
429         // Tests that resuorce was copied correctly
430         FileInputStream fis = new FileInputStream(file);
431         try {
432             assertTrue(
433                 "Content is not equal.",
434                 IOUtils.contentEquals(
435                     getClass().getResourceAsStream(resourceName),
436                     fis));
437         } finally {
438             fis.close();
439         }
440         //TODO Maybe test copy to itself like for copyFile()
441     }
442 
443     // forceMkdir
444 
445     public void testForceMkdir() throws Exception {
446         // Tests with existing directory
447         FileUtils.forceMkdir(getTestDirectory());
448 
449         // Creates test file
450         File testFile = new File(getTestDirectory(), getName());
451         testFile.deleteOnExit();
452         testFile.createNewFile();
453         assertTrue("Test file does not exist.", testFile.exists());
454 
455         // Tests with existing file
456         try {
457             FileUtils.forceMkdir(testFile);
458             fail("Exception expected.");
459         } catch (IOException ex) {}
460 
461         testFile.delete();
462 
463         // Tests with non-existent directory
464         FileUtils.forceMkdir(testFile);
465         assertTrue("Directory was not created.", testFile.exists());
466     }
467 
468     // sizeOfDirectory
469 
470     public void testSizeOfDirectory() throws Exception {
471         File file = new File(getTestDirectory(), getName());
472 
473         // Non-existent file
474         try {
475             FileUtils.sizeOfDirectory(file);
476             fail("Exception expected.");
477         } catch (IllegalArgumentException ex) {}
478 
479         // Creates file
480         file.createNewFile();
481         file.deleteOnExit();
482 
483         // Existing file
484         try {
485             FileUtils.sizeOfDirectory(file);
486             fail("Exception expected.");
487         } catch (IllegalArgumentException ex) {}
488 
489         // Existing directory
490         file.delete();
491         file.mkdir();
492 
493         assertEquals(
494             "Unexpected directory size",
495             TEST_DIRECTORY_SIZE,
496             FileUtils.sizeOfDirectory(file));
497     }
498 
499     // isFileNewer / isFileOlder
500     public void testIsFileNewerOlder() throws Exception {
501         File reference   = new File(getTestDirectory(), "FileUtils-reference.txt");
502         File oldFile     = new File(getTestDirectory(), "FileUtils-old.txt");
503         File newFile     = new File(getTestDirectory(), "FileUtils-new.txt");
504         File invalidFile = new File(getTestDirectory(), "FileUtils-invalid-file.txt");
505 
506         // Create Files
507         createFile(oldFile, 0);
508 
509         do {
510             try {
511                 Thread.sleep(1000);
512             } catch(InterruptedException ie) {
513                 // ignore
514             }
515             createFile(reference, 0);
516         } while( oldFile.lastModified() == reference.lastModified() );
517 
518         Date date = new Date();
519         long now = date.getTime();
520 
521         do {
522             try {
523                 Thread.sleep(1000);
524             } catch(InterruptedException ie) {
525                 // ignore
526             }
527             createFile(newFile, 0);
528         } while( reference.lastModified() == newFile.lastModified() );
529 
530         // Test isFileNewer()
531         assertFalse("Old File - Newer - File", FileUtils.isFileNewer(oldFile, reference));
532         assertFalse("Old File - Newer - Date", FileUtils.isFileNewer(oldFile, date));
533         assertFalse("Old File - Newer - Mili", FileUtils.isFileNewer(oldFile, now));
534         assertTrue("New File - Newer - File", FileUtils.isFileNewer(newFile, reference));
535         assertTrue("New File - Newer - Date", FileUtils.isFileNewer(newFile, date));
536         assertTrue("New File - Newer - Mili", FileUtils.isFileNewer(newFile, now));
537         assertFalse("Invalid - Newer - File", FileUtils.isFileNewer(invalidFile, reference));
538         
539         // Test isFileOlder()
540         assertTrue("Old File - Older - File", FileUtils.isFileOlder(oldFile, reference));
541         assertTrue("Old File - Older - Date", FileUtils.isFileOlder(oldFile, date));
542         assertTrue("Old File - Older - Mili", FileUtils.isFileOlder(oldFile, now));
543         assertFalse("New File - Older - File", FileUtils.isFileOlder(newFile, reference));
544         assertFalse("New File - Older - Date", FileUtils.isFileOlder(newFile, date));
545         assertFalse("New File - Older - Mili", FileUtils.isFileOlder(newFile, now));
546         assertFalse("Invalid - Older - File", FileUtils.isFileOlder(invalidFile, reference));
547         
548         
549         // ----- Test isFileNewer() exceptions -----
550         // Null File
551         try {
552             FileUtils.isFileNewer(null, now);
553             fail("Newer Null, expected IllegalArgumentExcepion");
554         } catch (IllegalArgumentException expected) {
555             // expected result
556         }
557         
558         // Null reference File
559         try {
560             FileUtils.isFileNewer(oldFile, (File)null);
561             fail("Newer Null reference, expected IllegalArgumentExcepion");
562         } catch (IllegalArgumentException expected) {
563             // expected result
564         }
565         
566         // Invalid reference File
567         try {
568             FileUtils.isFileNewer(oldFile, invalidFile);
569             fail("Newer invalid reference, expected IllegalArgumentExcepion");
570         } catch (IllegalArgumentException expected) {
571             // expected result
572         }
573         
574         // Null reference Date
575         try {
576             FileUtils.isFileNewer(oldFile, (Date)null);
577             fail("Newer Null date, expected IllegalArgumentExcepion");
578         } catch (IllegalArgumentException expected) {
579             // expected result
580         }
581 
582 
583         // ----- Test isFileOlder() exceptions -----
584         // Null File
585         try {
586             FileUtils.isFileOlder(null, now);
587             fail("Older Null, expected IllegalArgumentExcepion");
588         } catch (IllegalArgumentException expected) {
589             // expected result
590         }
591         
592         // Null reference File
593         try {
594             FileUtils.isFileOlder(oldFile, (File)null);
595             fail("Older Null reference, expected IllegalArgumentExcepion");
596         } catch (IllegalArgumentException expected) {
597             // expected result
598         }
599         
600         // Invalid reference File
601         try {
602             FileUtils.isFileOlder(oldFile, invalidFile);
603             fail("Older invalid reference, expected IllegalArgumentExcepion");
604         } catch (IllegalArgumentException expected) {
605             // expected result
606         }
607         
608         // Null reference Date
609         try {
610             FileUtils.isFileOlder(oldFile, (Date)null);
611             fail("Older Null date, expected IllegalArgumentExcepion");
612         } catch (IllegalArgumentException expected) {
613             // expected result
614         }
615 
616     }
617 
618 //    // TODO Remove after debugging
619 //    private void log(Object obj) {
620 //        System.out.println(
621 //            FileUtilsTestCase.class +" " + getName() + " " + obj);
622 //    }
623 
624     // copyFile
625 
626     public void testCopyFile1() throws Exception {
627         File destination = new File(getTestDirectory(), "copy1.txt");
628         
629         //Thread.sleep(LAST_MODIFIED_DELAY);
630         //This is to slow things down so we can catch if 
631         //the lastModified date is not ok
632         
633         FileUtils.copyFile(testFile1, destination);
634         assertTrue("Check Exist", destination.exists());
635         assertTrue("Check Full copy", destination.length() == testFile1Size);
636         /* disabled: Thread.sleep doesn't work reliantly for this case
637         assertTrue("Check last modified date preserved", 
638             testFile1.lastModified() == destination.lastModified());*/  
639     }
640 
641     public void testCopyFile2() throws Exception {
642         File destination = new File(getTestDirectory(), "copy2.txt");
643         
644         //Thread.sleep(LAST_MODIFIED_DELAY);
645         //This is to slow things down so we can catch if 
646         //the lastModified date is not ok
647         
648         FileUtils.copyFile(testFile1, destination);
649         assertTrue("Check Exist", destination.exists());
650         assertTrue("Check Full copy", destination.length() == testFile2Size);
651         /* disabled: Thread.sleep doesn't work reliably for this case
652         assertTrue("Check last modified date preserved", 
653             testFile1.lastModified() == destination.lastModified());*/
654     }
655     
656     public void testCopyToSelf() throws Exception {
657         File destination = new File(getTestDirectory(), "copy3.txt");
658         //Prepare a test file
659         FileUtils.copyFile(testFile1, destination);
660         
661         try {
662             FileUtils.copyFile(destination, destination);
663             fail("file copy to self should not be possible");
664         } catch (IOException ioe) {
665             //we want the exception, copy to self should be illegal
666         }
667     }
668 
669     public void testCopyFile2WithoutFileDatePreservation() throws Exception {
670         File destination = new File(getTestDirectory(), "copy2.txt");
671         
672         //Thread.sleep(LAST_MODIFIED_DELAY);
673         //This is to slow things down so we can catch if 
674         //the lastModified date is not ok
675         
676         FileUtils.copyFile(testFile1, destination, false);
677         assertTrue("Check Exist", destination.exists());
678         assertTrue("Check Full copy", destination.length() == testFile2Size);
679         /* disabled: Thread.sleep doesn't work reliantly for this case
680         assertTrue("Check last modified date modified", 
681             testFile1.lastModified() != destination.lastModified());*/    
682     }
683 
684     public void testCopyDirectoryToDirectory_NonExistingDest() throws Exception {
685         createFile(testFile1, 1234);
686         createFile(testFile2, 4321);
687         File srcDir = getTestDirectory();
688         File subDir = new File(srcDir, "sub");
689         subDir.mkdir();
690         File subFile = new File(subDir, "A.txt");
691         FileUtils.writeStringToFile(subFile, "HELLO WORLD", "UTF8");
692         File destDir = new File(System.getProperty("java.io.tmpdir"), "tmp-FileUtilsTestCase");
693         FileUtils.deleteDirectory(destDir);
694         File actualDestDir = new File(destDir, srcDir.getName());
695         
696         FileUtils.copyDirectoryToDirectory(srcDir, destDir);
697         
698         assertTrue("Check exists", destDir.exists());
699         assertTrue("Check exists", actualDestDir.exists());
700         assertEquals("Check size", FileUtils.sizeOfDirectory(srcDir), FileUtils.sizeOfDirectory(actualDestDir));
701         assertEquals(true, new File(actualDestDir, "sub/A.txt").exists());
702         FileUtils.deleteDirectory(destDir);
703     }
704 
705     public void testCopyDirectoryToNonExistingDest() throws Exception {
706         createFile(testFile1, 1234);
707         createFile(testFile2, 4321);
708         File srcDir = getTestDirectory();
709         File subDir = new File(srcDir, "sub");
710         subDir.mkdir();
711         File subFile = new File(subDir, "A.txt");
712         FileUtils.writeStringToFile(subFile, "HELLO WORLD", "UTF8");
713         File destDir = new File(System.getProperty("java.io.tmpdir"), "tmp-FileUtilsTestCase");
714         FileUtils.deleteDirectory(destDir);
715         
716         FileUtils.copyDirectory(srcDir, destDir);
717         
718         assertTrue("Check exists", destDir.exists());
719         assertEquals("Check size", FileUtils.sizeOfDirectory(srcDir), FileUtils.sizeOfDirectory(destDir));
720         assertEquals(true, new File(destDir, "sub/A.txt").exists());
721         FileUtils.deleteDirectory(destDir);
722     }
723 
724     public void testCopyDirectoryToExistingDest() throws Exception {
725         createFile(testFile1, 1234);
726         createFile(testFile2, 4321);
727         File srcDir = getTestDirectory();
728         File subDir = new File(srcDir, "sub");
729         subDir.mkdir();
730         File subFile = new File(subDir, "A.txt");
731         FileUtils.writeStringToFile(subFile, "HELLO WORLD", "UTF8");
732         File destDir = new File(System.getProperty("java.io.tmpdir"), "tmp-FileUtilsTestCase");
733         FileUtils.deleteDirectory(destDir);
734         destDir.mkdirs();
735         
736         FileUtils.copyDirectory(srcDir, destDir);
737         
738         assertEquals(FileUtils.sizeOfDirectory(srcDir), FileUtils.sizeOfDirectory(destDir));
739         assertEquals(true, new File(destDir, "sub/A.txt").exists());
740     }
741 
742     public void testCopyDirectoryFiltered() throws Exception {
743         File grandParentDir = new File(getTestDirectory(), "grandparent");
744         File parentDir      = new File(grandParentDir, "parent");
745         File childDir       = new File(parentDir, "child");
746         createFilesForTestCopyDirectory(grandParentDir, parentDir, childDir);
747 
748         NameFileFilter filter = new NameFileFilter(new String[] {"parent", "child", "file3.txt"});
749         File destDir       = new File(getTestDirectory(), "copydest");
750 
751         FileUtils.copyDirectory(grandParentDir, destDir, filter);
752         List files  = LIST_WALKER.list(destDir);
753         assertEquals(3, files.size());
754         assertEquals("parent", ((File)files.get(0)).getName());
755         assertEquals("child", ((File)files.get(1)).getName());
756         assertEquals("file3.txt", ((File)files.get(2)).getName());
757    }
758 
759     /** Test for IO-141 */
760     public void testCopyDirectoryToChild() throws Exception {
761         File grandParentDir = new File(getTestDirectory(), "grandparent");
762         File parentDir      = new File(grandParentDir, "parent");
763         File childDir       = new File(parentDir, "child");
764         createFilesForTestCopyDirectory(grandParentDir, parentDir, childDir);
765 
766         long expectedCount = LIST_WALKER.list(grandParentDir).size() +
767                              LIST_WALKER.list(parentDir).size();
768         long expectedSize =  FileUtils.sizeOfDirectory(grandParentDir) +
769                              FileUtils.sizeOfDirectory(parentDir);
770         FileUtils.copyDirectory(parentDir, childDir);
771         assertEquals(expectedCount, LIST_WALKER.list(grandParentDir).size());
772         assertEquals(expectedSize, FileUtils.sizeOfDirectory(grandParentDir));
773     }
774 
775     /** Test for IO-141 */
776     public void testCopyDirectoryToGrandChild() throws Exception {
777         File grandParentDir = new File(getTestDirectory(), "grandparent");
778         File parentDir      = new File(grandParentDir, "parent");
779         File childDir       = new File(parentDir, "child");
780         createFilesForTestCopyDirectory(grandParentDir, parentDir, childDir);
781 
782         long expectedCount = (LIST_WALKER.list(grandParentDir).size() * 2);
783         long expectedSize =  (FileUtils.sizeOfDirectory(grandParentDir) * 2);
784         FileUtils.copyDirectory(grandParentDir, childDir);
785         assertEquals(expectedCount, LIST_WALKER.list(grandParentDir).size());
786         assertEquals(expectedSize, FileUtils.sizeOfDirectory(grandParentDir));
787     }
788 
789     private void createFilesForTestCopyDirectory(File grandParentDir, File parentDir, File childDir) throws Exception {
790         File childDir2 = new File(parentDir, "child2");
791         File grandChildDir = new File(childDir, "grandChild");
792         File grandChild2Dir = new File(childDir2, "grandChild2");
793         File file1 = new File(grandParentDir, "file1.txt");
794         File file2 = new File(parentDir, "file2.txt");
795         File file3 = new File(childDir, "file3.txt");
796         File file4 = new File(childDir2, "file4.txt");
797         File file5 = new File(grandChildDir, "file5.txt");
798         File file6 = new File(grandChild2Dir, "file6.txt");
799         FileUtils.deleteDirectory(grandParentDir);
800         grandChildDir.mkdirs();
801         grandChild2Dir.mkdirs();
802         FileUtils.writeStringToFile(file1, "File 1 in grandparent", "UTF8");
803         FileUtils.writeStringToFile(file2, "File 2 in parent", "UTF8");
804         FileUtils.writeStringToFile(file3, "File 3 in child", "UTF8");
805         FileUtils.writeStringToFile(file4, "File 4 in child2", "UTF8");
806         FileUtils.writeStringToFile(file5, "File 5 in grandChild", "UTF8");
807         FileUtils.writeStringToFile(file6, "File 6 in grandChild2", "UTF8");
808     }
809 
810     public void testCopyDirectoryErrors() throws Exception {
811         try {
812             FileUtils.copyDirectory(null, null);
813             fail();
814         } catch (NullPointerException ex) {}
815         try {
816             FileUtils.copyDirectory(new File("a"), null);
817             fail();
818         } catch (NullPointerException ex) {}
819         try {
820             FileUtils.copyDirectory(null, new File("a"));
821             fail();
822         } catch (NullPointerException ex) {}
823         try {
824             FileUtils.copyDirectory(new File("doesnt-exist"), new File("a"));
825             fail();
826         } catch (IOException ex) {}
827         try {
828             FileUtils.copyDirectory(testFile1, new File("a"));
829             fail();
830         } catch (IOException ex) {}
831         try {
832             FileUtils.copyDirectory(getTestDirectory(), testFile1);
833             fail();
834         } catch (IOException ex) {}
835         try {
836             FileUtils.copyDirectory(getTestDirectory(), getTestDirectory());
837             fail();
838         } catch (IOException ex) {}
839     }
840 
841     // forceDelete
842 
843     public void testForceDeleteAFile1() throws Exception {
844         File destination = new File(getTestDirectory(), "copy1.txt");
845         destination.createNewFile();
846         assertTrue("Copy1.txt doesn't exist to delete", destination.exists());
847         FileUtils.forceDelete(destination);
848         assertTrue("Check No Exist", !destination.exists());
849     }
850 
851     public void testForceDeleteAFile2() throws Exception {
852         File destination = new File(getTestDirectory(), "copy2.txt");
853         destination.createNewFile();
854         assertTrue("Copy2.txt doesn't exist to delete", destination.exists());
855         FileUtils.forceDelete(destination);
856         assertTrue("Check No Exist", !destination.exists());
857     }
858 
859     public void testForceDeleteAFile3() throws Exception {
860         File destination = new File(getTestDirectory(), "no_such_file");
861         assertTrue("Check No Exist", !destination.exists());
862         try {
863             FileUtils.forceDelete(destination);
864             fail("Should generate FileNotFoundException");
865         } catch (FileNotFoundException ignored){
866         }
867     }
868 
869     // copyFileToDirectory
870 
871     public void testCopyFile1ToDir() throws Exception {
872         File directory = new File(getTestDirectory(), "subdir");
873         if (!directory.exists())
874             directory.mkdirs();
875         File destination = new File(directory, testFile1.getName());
876         
877         //Thread.sleep(LAST_MODIFIED_DELAY);
878         //This is to slow things down so we can catch if 
879         //the lastModified date is not ok
880         
881         FileUtils.copyFileToDirectory(testFile1, directory);
882         assertTrue("Check Exist", destination.exists());
883         assertTrue("Check Full copy", destination.length() == testFile1Size);
884         /* disabled: Thread.sleep doesn't work reliantly for this case
885         assertTrue("Check last modified date preserved", 
886             testFile1.lastModified() == destination.lastModified());*/
887             
888         try {
889             FileUtils.copyFileToDirectory(destination, directory);
890             fail("Should not be able to copy a file into the same directory as itself");    
891         } catch (IOException ioe) {
892             //we want that, cannot copy to the same directory as the original file
893         }
894     }
895 
896     public void testCopyFile2ToDir() throws Exception {
897         File directory = new File(getTestDirectory(), "subdir");
898         if (!directory.exists())
899             directory.mkdirs();
900         File destination = new File(directory, testFile1.getName());
901         
902         //Thread.sleep(LAST_MODIFIED_DELAY);
903         //This is to slow things down so we can catch if 
904         //the lastModified date is not ok
905         
906         FileUtils.copyFileToDirectory(testFile1, directory);
907         assertTrue("Check Exist", destination.exists());
908         assertTrue("Check Full copy", destination.length() == testFile2Size);
909         /* disabled: Thread.sleep doesn't work reliantly for this case
910         assertTrue("Check last modified date preserved", 
911             testFile1.lastModified() == destination.lastModified());*/    
912     }
913 
914     // forceDelete
915 
916     public void testForceDeleteDir() throws Exception {
917         File testDirectory = getTestDirectory();
918         FileUtils.forceDelete(testDirectory.getParentFile());
919         assertTrue(
920             "Check No Exist",
921             !testDirectory.getParentFile().exists());
922     }
923 
924     /**
925      *  Test the FileUtils implementation.
926      */
927     public void testFileUtils() throws Exception {
928         // Loads file from classpath
929         File file1 = new File(getTestDirectory(), "test.txt");
930         String filename = file1.getAbsolutePath();
931         
932         //Create test file on-the-fly (used to be in CVS)
933         OutputStream out = new java.io.FileOutputStream(file1);
934         try {
935             out.write("This is a test".getBytes("UTF-8"));
936         } finally {
937             out.close();
938         }
939         
940         File file2 = new File(getTestDirectory(), "test2.txt");
941 
942         FileUtils.writeStringToFile(file2, filename, "UTF-8");
943         assertTrue(file2.exists());
944         assertTrue(file2.length() > 0);
945 
946         String file2contents = FileUtils.readFileToString(file2, "UTF-8");
947         assertTrue(
948             "Second file's contents correct",
949             filename.equals(file2contents));
950 
951         assertTrue(file2.delete());
952         
953         String contents = FileUtils.readFileToString(new File(filename), "UTF-8");
954         assertTrue("FileUtils.fileRead()", contents.equals("This is a test"));
955 
956     }
957 
958     public void testTouch() throws IOException {
959         File file = new File(getTestDirectory(), "touch.txt") ;
960         if (file.exists()) {
961             file.delete();
962         }
963         assertTrue("Bad test: test file still exists", !file.exists());
964         FileUtils.touch(file);
965         assertTrue("FileUtils.touch() created file", file.exists());
966         FileOutputStream out = new FileOutputStream(file) ;
967         assertEquals("Created empty file.", 0, file.length());
968         out.write(0) ;
969         out.close();
970         assertEquals("Wrote one byte to file", 1, file.length());
971         long y2k = new GregorianCalendar(2000, 0, 1).getTime().getTime();
972         boolean res = file.setLastModified(y2k);  // 0L fails on Win98
973         assertEquals("Bad test: set lastModified failed", true, res);
974         assertEquals("Bad test: set lastModified set incorrect value", y2k, file.lastModified());
975         long now = System.currentTimeMillis();
976         FileUtils.touch(file) ;
977         assertEquals("FileUtils.touch() didn't empty the file.", 1, file.length());
978         assertEquals("FileUtils.touch() changed lastModified", false, y2k == file.lastModified());
979         assertEquals("FileUtils.touch() changed lastModified to more than now-3s", true, file.lastModified() >= (now - 3000));
980         assertEquals("FileUtils.touch() changed lastModified to less than now+3s", true, file.lastModified() <= (now + 3000));
981     }
982 
983     public void testListFiles() throws Exception {
984         File srcDir = getTestDirectory();
985         File subDir = new File(srcDir, "list_test" );
986         subDir.mkdir();
987 
988         String[] fileNames = {"a.txt", "b.txt", "c.txt", "d.txt", "e.txt", "f.txt"};
989         int[] fileSizes = {123, 234, 345, 456, 678, 789};
990 
991         for (int i = 0; i < fileNames.length; ++i) {
992             File theFile = new File(subDir, fileNames[i]);
993             createFile(theFile, fileSizes[i]);
994         }
995 
996         Collection files = FileUtils.listFiles(subDir,
997                                                new WildcardFileFilter("*.*"),
998                                                new WildcardFileFilter("*"));
999 
1000         int count = files.size();
1001         Object[] fileObjs = files.toArray();
1002 
1003         assertEquals(files.size(), fileNames.length);
1004 
1005         Map foundFileNames = new HashMap();
1006 
1007         for (int i = 0; i < count; ++i) {
1008             boolean found = false;
1009             for(int j = 0; (( !found ) && (j < fileNames.length)); ++j) {
1010                 if ( fileNames[j].equals(((File) fileObjs[i]).getName())) {
1011                     foundFileNames.put(fileNames[j], fileNames[j]);
1012                     found = true;
1013                 }
1014             }
1015         }
1016 
1017         assertEquals(foundFileNames.size(), fileNames.length);
1018 
1019         subDir.delete();
1020     }
1021 
1022     public void testIterateFiles() throws Exception {
1023         File srcDir = getTestDirectory();
1024         File subDir = new File(srcDir, "list_test" );
1025         subDir.mkdir();
1026 
1027         String[] fileNames = {"a.txt", "b.txt", "c.txt", "d.txt", "e.txt", "f.txt"};
1028         int[] fileSizes = {123, 234, 345, 456, 678, 789};
1029 
1030         for (int i = 0; i < fileNames.length; ++i) {
1031             File theFile = new File(subDir, fileNames[i]);
1032             createFile(theFile, fileSizes[i]);
1033         }
1034 
1035         Iterator files = FileUtils.iterateFiles(subDir,
1036                                                 new WildcardFileFilter("*.*"),
1037                                                 new WildcardFileFilter("*"));
1038 
1039         Map foundFileNames = new HashMap();
1040 
1041         while (files.hasNext()) {
1042             boolean found = false;
1043             String fileName = ((File) files.next()).getName();
1044 
1045             for (int j = 0; (( !found ) && (j < fileNames.length)); ++j) {
1046                 if ( fileNames[j].equals(fileName)) {
1047                     foundFileNames.put(fileNames[j], fileNames[j]);
1048                     found = true;
1049                 }
1050             }
1051         }
1052 
1053         assertEquals(foundFileNames.size(), fileNames.length);
1054 
1055         subDir.delete();
1056     }
1057 
1058     public void testReadFileToString() throws Exception {
1059         File file = new File(getTestDirectory(), "read.obj");
1060         FileOutputStream out = new FileOutputStream(file);
1061         byte[] text = "Hello /u1234".getBytes("UTF8");
1062         out.write(text);
1063         out.close();
1064         
1065         String data = FileUtils.readFileToString(file, "UTF8");
1066         assertEquals("Hello /u1234", data);
1067     }
1068 
1069     public void testReadFileToByteArray() throws Exception {
1070         File file = new File(getTestDirectory(), "read.txt");
1071         FileOutputStream out = new FileOutputStream(file);
1072         out.write(11);
1073         out.write(21);
1074         out.write(31);
1075         out.close();
1076         
1077         byte[] data = FileUtils.readFileToByteArray(file);
1078         assertEquals(3, data.length);
1079         assertEquals(11, data[0]);
1080         assertEquals(21, data[1]);
1081         assertEquals(31, data[2]);
1082     }
1083 
1084     public void testReadLines() throws Exception {
1085         File file = newFile("lines.txt");
1086         try {
1087             String[] data = new String[] {"hello", "/u1234", "", "this is", "some text"};
1088             createLineBasedFile(file, data);
1089             
1090             List lines = FileUtils.readLines(file, "UTF-8");
1091             assertEquals(Arrays.asList(data), lines);
1092         } finally {
1093             deleteFile(file);
1094         }
1095     }
1096 
1097     public void testWriteStringToFile1() throws Exception {
1098         File file = new File(getTestDirectory(), "write.txt");
1099         FileUtils.writeStringToFile(file, "Hello /u1234", "UTF8");
1100         byte[] text = "Hello /u1234".getBytes("UTF8");
1101         assertEqualContent(text, file);
1102     }
1103 
1104     public void testWriteStringToFile2() throws Exception {
1105         File file = new File(getTestDirectory(), "write.txt");
1106         FileUtils.writeStringToFile(file, "Hello /u1234", null);
1107         byte[] text = "Hello /u1234".getBytes();
1108         assertEqualContent(text, file);
1109     }
1110 
1111     public void testWriteCharSequence1() throws Exception {
1112         File file = new File(getTestDirectory(), "write.txt");
1113         FileUtils.write(file, "Hello /u1234", "UTF8");
1114         byte[] text = "Hello /u1234".getBytes("UTF8");
1115         assertEqualContent(text, file);
1116     }
1117 
1118     public void testWriteCharSequence2() throws Exception {
1119         File file = new File(getTestDirectory(), "write.txt");
1120         FileUtils.write(file, "Hello /u1234", null);
1121         byte[] text = "Hello /u1234".getBytes();
1122         assertEqualContent(text, file);
1123     }
1124 
1125     public void testWriteByteArrayToFile() throws Exception {
1126         File file = new File(getTestDirectory(), "write.obj");
1127         byte[] data = new byte[] {11, 21, 31};
1128         FileUtils.writeByteArrayToFile(file, data);
1129         assertEqualContent(data, file);
1130     }
1131 
1132     public void testWriteLines_4arg() throws Exception {
1133         Object[] data = new Object[] {
1134             "hello", new StringBuffer("world"), "", "this is", null, "some text"};
1135         List list = Arrays.asList(data);
1136         
1137         File file = newFile("lines.txt");
1138         FileUtils.writeLines(file, "US-ASCII", list, "*");
1139         
1140         String expected = "hello*world**this is**some text*";
1141         String actual = FileUtils.readFileToString(file, "US-ASCII");
1142         assertEquals(expected, actual);
1143     }
1144 
1145     public void testWriteLines_4arg_Writer_nullData() throws Exception {
1146         File file = newFile("lines.txt");
1147         FileUtils.writeLines(file, "US-ASCII", (List) null, "*");
1148         
1149         assertEquals("Sizes differ", 0, file.length());
1150     }
1151 
1152     public void testWriteLines_4arg_nullSeparator() throws Exception {
1153         Object[] data = new Object[] {
1154             "hello", new StringBuffer("world"), "", "this is", null, "some text"};
1155         List list = Arrays.asList(data);
1156         
1157         File file = newFile("lines.txt");
1158         FileUtils.writeLines(file, "US-ASCII", list, null);
1159         
1160         String expected = "hello" + IOUtils.LINE_SEPARATOR + "world" + IOUtils.LINE_SEPARATOR +
1161             IOUtils.LINE_SEPARATOR + "this is" + IOUtils.LINE_SEPARATOR +
1162             IOUtils.LINE_SEPARATOR + "some text" + IOUtils.LINE_SEPARATOR;
1163         String actual = FileUtils.readFileToString(file, "US-ASCII");
1164         assertEquals(expected, actual);
1165     }
1166 
1167     public void testWriteLines_3arg_nullSeparator() throws Exception {
1168         Object[] data = new Object[] {
1169             "hello", new StringBuffer("world"), "", "this is", null, "some text"};
1170         List list = Arrays.asList(data);
1171         
1172         File file = newFile("lines.txt");
1173         FileUtils.writeLines(file, "US-ASCII", list);
1174         
1175         String expected = "hello" + IOUtils.LINE_SEPARATOR + "world" + IOUtils.LINE_SEPARATOR +
1176             IOUtils.LINE_SEPARATOR + "this is" + IOUtils.LINE_SEPARATOR +
1177             IOUtils.LINE_SEPARATOR + "some text" + IOUtils.LINE_SEPARATOR;
1178         String actual = FileUtils.readFileToString(file, "US-ASCII");
1179         assertEquals(expected, actual);
1180     }
1181 
1182     //-----------------------------------------------------------------------
1183     public void testChecksumCRC32() throws Exception {
1184         // create a test file
1185         String text = "Imagination is more important than knowledge - Einstein";
1186         File file = new File(getTestDirectory(), "checksum-test.txt");
1187         FileUtils.writeStringToFile(file, text, "US-ASCII");
1188         
1189         // compute the expected checksum
1190         Checksum expectedChecksum = new CRC32();
1191         expectedChecksum.update(text.getBytes("US-ASCII"), 0, text.length());
1192         long expectedValue = expectedChecksum.getValue();
1193         
1194         // compute the checksum of the file
1195         long resultValue = FileUtils.checksumCRC32(file);
1196         
1197         assertEquals(expectedValue, resultValue);
1198     }
1199 
1200     public void testChecksum() throws Exception {
1201         // create a test file
1202         String text = "Imagination is more important than knowledge - Einstein";
1203         File file = new File(getTestDirectory(), "checksum-test.txt");
1204         FileUtils.writeStringToFile(file, text, "US-ASCII");
1205         
1206         // compute the expected checksum
1207         Checksum expectedChecksum = new CRC32();
1208         expectedChecksum.update(text.getBytes("US-ASCII"), 0, text.length());
1209         long expectedValue = expectedChecksum.getValue();
1210         
1211         // compute the checksum of the file
1212         Checksum testChecksum = new CRC32();
1213         Checksum resultChecksum = FileUtils.checksum(file, testChecksum);
1214         long resultValue = resultChecksum.getValue();
1215         
1216         assertSame(testChecksum, resultChecksum);
1217         assertEquals(expectedValue, resultValue);
1218     }
1219 
1220     public void testChecksumOnNullFile() throws Exception {
1221         try {
1222             FileUtils.checksum((File) null, new CRC32());
1223             fail();
1224         } catch (NullPointerException ex) {
1225             // expected
1226         }
1227     }
1228 
1229     public void testChecksumOnNullChecksum() throws Exception {
1230         // create a test file
1231         String text = "Imagination is more important than knowledge - Einstein";
1232         File file = new File(getTestDirectory(), "checksum-test.txt");
1233         FileUtils.writeStringToFile(file, text, "US-ASCII");
1234         try {
1235             FileUtils.checksum(file, (Checksum) null);
1236             fail();
1237         } catch (NullPointerException ex) {
1238             // expected
1239         }
1240     }
1241 
1242     public void testChecksumOnDirectory() throws Exception {
1243         try {
1244             FileUtils.checksum(new File("."), new CRC32());
1245             fail();
1246         } catch (IllegalArgumentException ex) {
1247             // expected
1248         }
1249     }
1250 
1251     public void testChecksumDouble() throws Exception {
1252         // create a test file
1253         String text1 = "Imagination is more important than knowledge - Einstein";
1254         File file1 = new File(getTestDirectory(), "checksum-test.txt");
1255         FileUtils.writeStringToFile(file1, text1, "US-ASCII");
1256         
1257         // create a second test file