View Javadoc
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    *      https://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 static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertThrows;
21  
22  import java.io.BufferedOutputStream;
23  import java.io.File;
24  import java.io.IOException;
25  import java.nio.file.Files;
26  import java.nio.file.attribute.FileTime;
27  import java.util.Date;
28  
29  import org.apache.commons.io.file.attribute.FileTimes;
30  import org.apache.commons.io.test.TestUtils;
31  import org.junit.jupiter.api.BeforeEach;
32  import org.junit.jupiter.api.Test;
33  import org.junit.jupiter.api.io.TempDir;
34  
35  /**
36   * Tests {@link FileUtils}.
37   */
38  class FileUtilsFileNewerTest {
39  
40      // Test data
41      private static final int FILE1_SIZE = 1;
42  
43      private static final int FILE2_SIZE = 1024 * 4 + 1;
44      @TempDir
45      public File temporaryFolder;
46  
47      private File testFile1;
48      private File testFile2;
49  
50      @BeforeEach
51      public void setUp() throws Exception {
52          testFile1 = new File(temporaryFolder, "file1-test.txt");
53          testFile2 = new File(temporaryFolder, "file2-test.txt");
54          if (!testFile1.getParentFile().exists()) {
55              throw new IOException("Cannot create file " + testFile1 + " as the parent directory does not exist");
56          }
57          try (BufferedOutputStream output1 = new BufferedOutputStream(Files.newOutputStream(testFile1.toPath()))) {
58              TestUtils.generateTestData(output1, FILE1_SIZE);
59          }
60          if (!testFile2.getParentFile().exists()) {
61              throw new IOException("Cannot create file " + testFile2 + " as the parent directory does not exist");
62          }
63          try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(testFile2.toPath()))) {
64              TestUtils.generateTestData(output, FILE2_SIZE);
65          }
66      }
67  
68      /**
69       * Tests the {@code isFileNewer(File, *)} methods which a "normal" file.
70       *
71       * @throws IOException
72       * @see FileUtils#isFileNewer(File, long)
73       * @see FileUtils#isFileNewer(File, Date)
74       * @see FileUtils#isFileNewer(File, File)
75       */
76      @Test
77      void testIsFileNewer() throws IOException {
78          if (!testFile1.exists()) {
79              throw new IllegalStateException("The testFile1 should exist");
80          }
81  
82          final FileTime fileLastModified = Files.getLastModifiedTime(testFile1.toPath());
83          final long TWO_SECOND = 2;
84  
85          testIsFileNewer("two second earlier is not newer", testFile1, FileTimes.plusSeconds(fileLastModified, TWO_SECOND), false);
86          testIsFileNewer("same time is not newer", testFile1, fileLastModified, false);
87          testIsFileNewer("two second later is newer", testFile1, FileTimes.minusSeconds(fileLastModified, TWO_SECOND), true);
88      }
89  
90      /**
91       * Tests the {@code isFileNewer(File, *)} methods which the specified conditions.
92       *
93       * Creates :
94       * <ul>
95       * <li>a {@code Date} which represents the time reference</li>
96       * <li>a temporary file with the same last modification date as the time reference</li>
97       * </ul>
98       * Then compares (with the needed {@code isFileNewer} method) the last modification date of the specified file with the
99       * specified time reference, the created {@code Date} and the temporary file.
100      * <p>
101      * The test is successful if the three comparisons return the specified wanted result.
102      *
103      * @param description describes the tested situation
104      * @param file the file of which the last modification date is compared
105      * @param fileTime the time reference measured in milliseconds since the epoch
106      * @param wantedResult the expected result
107      * @throws IOException if an I/O error occurs.
108      */
109     protected void testIsFileNewer(final String description, final File file, final FileTime fileTime, final boolean wantedResult) throws IOException {
110         assertEquals(wantedResult, FileUtils.isFileNewer(file, fileTime), () -> description + " - FileTime");
111         assertEquals(wantedResult, FileUtils.isFileNewer(file, fileTime.toInstant()), () -> description + " - Instant");
112 
113         final File temporaryFile = testFile2;
114         Files.setLastModifiedTime(temporaryFile.toPath(), fileTime);
115         assertEquals(fileTime, Files.getLastModifiedTime(temporaryFile.toPath()), "The temporary file hasn't the right last modification date");
116         assertEquals(wantedResult, FileUtils.isFileNewer(file, temporaryFile), () -> description + " - file");
117     }
118 
119     /**
120      * Tests the {@code isFileNewer(File, *)} methods which a not existing file.
121      *
122      * @throws IOException if an I/O error occurs.
123      * @see FileUtils#isFileNewer(File, long)
124      * @see FileUtils#isFileNewer(File, Date)
125      * @see FileUtils#isFileNewer(File, File)
126      */
127     @Test
128     void testIsFileNewerImaginaryFile() throws IOException {
129         final File imaginaryFile = new File(temporaryFolder, "imaginaryFile");
130         if (imaginaryFile.exists()) {
131             throw new IllegalStateException("The imaginary File exists");
132         }
133 
134         testIsFileNewer("imaginary file can be newer", imaginaryFile, FileUtils.lastModifiedFileTime(testFile2), false);
135     }
136 
137     /**
138      * Tests the {@code isFileNewer(File, Date)} method without specifying a {@code Date}.
139      * <p>
140      * The test is successful if the method throws an {@code IllegalArgumentException}.
141      * </p>
142      */
143     @Test
144     void testIsFileNewerNoDate() {
145         assertThrows(NullPointerException.class, () -> FileUtils.isFileNewer(testFile1, (Date) null), "date");
146     }
147 
148     /**
149      * Tests the {@code isFileNewer(File, long)} method without specifying a {@code File}.
150      * <p>
151      * The test is successful if the method throws an {@code IllegalArgumentException}.
152      * </p>
153      */
154     @Test
155     void testIsFileNewerNoFile() {
156         assertThrows(NullPointerException.class, () -> FileUtils.isFileNewer(null, 0), "file");
157     }
158 
159     /**
160      * Tests the {@code isFileNewer(File, File)} method without specifying a reference {@code File}.
161      * <p>
162      * The test is successful if the method throws an {@code IllegalArgumentException}.
163      * </p>
164      */
165     @Test
166     void testIsFileNewerNoFileReference() {
167         assertThrows(NullPointerException.class, () -> FileUtils.isFileNewer(testFile1, (File) null), "reference");
168     }
169 }