Skip to content

Commit d34e641

Browse files
authored
[IO-856] Try test on all OSs for GitHub CI (#699)
1 parent b59bc1d commit d34e641

2 files changed

Lines changed: 37 additions & 10 deletions

File tree

src/main/java/org/apache/commons/io/FileUtils.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.io.FileInputStream;
2424
import java.io.FileNotFoundException;
2525
import java.io.FileOutputStream;
26+
import java.io.FilenameFilter;
2627
import java.io.IOException;
2728
import java.io.InputStream;
2829
import java.io.InputStreamReader;
@@ -57,6 +58,7 @@
5758
import java.time.chrono.ChronoLocalDateTime;
5859
import java.time.chrono.ChronoZonedDateTime;
5960
import java.util.ArrayList;
61+
import java.util.Arrays;
6062
import java.util.Collection;
6163
import java.util.Collections;
6264
import java.util.Date;
@@ -2311,6 +2313,22 @@ public static Collection<File> listFiles(final File directory, final IOFileFilte
23112313
return toList(visitor.getFileList().stream().map(Path::toFile));
23122314
}
23132315

2316+
@SuppressWarnings("null")
2317+
private static void listFiles(final File directory, final List<File> files, final boolean recursive, final FilenameFilter filter) {
2318+
// Only allocate if you must.
2319+
final List<File> dirs = recursive ? new ArrayList<>() : null;
2320+
Arrays.stream(directory.listFiles()).forEach(f -> {
2321+
if (recursive && f.isDirectory()) {
2322+
dirs.add(f);
2323+
} else if (f.isFile() && filter.accept(directory, f.getName())) {
2324+
files.add(f);
2325+
}
2326+
});
2327+
if (recursive) {
2328+
dirs.forEach(d -> listFiles(d, files, true, filter));
2329+
}
2330+
}
2331+
23142332
/**
23152333
* Lists files within a given directory (and optionally its subdirectories)
23162334
* which match an array of extensions.
@@ -2322,9 +2340,11 @@ public static Collection<File> listFiles(final File directory, final IOFileFilte
23222340
* @return a collection of {@link File} with the matching files
23232341
*/
23242342
public static Collection<File> listFiles(final File directory, final String[] extensions, final boolean recursive) {
2325-
try (Stream<File> fileStream = Uncheck.get(() -> streamFiles(directory, recursive, extensions))) {
2326-
return toList(fileStream);
2327-
}
2343+
// IO-856: Don't use NIO to path walk, allocate as little as possible while traversing.
2344+
final List<File> files = new ArrayList<>();
2345+
final FilenameFilter filter = extensions != null ? new SuffixFileFilter(extensions) : TrueFileFilter.INSTANCE;
2346+
listFiles(directory, files, recursive, filter);
2347+
return files;
23282348
}
23292349

23302350
/**

src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import static org.junit.jupiter.api.Assertions.assertEquals;
2020
import static org.junit.jupiter.api.Assertions.assertFalse;
21+
import static org.junit.jupiter.api.Assertions.assertNotNull;
2122
import static org.junit.jupiter.api.Assertions.assertThrows;
2223
import static org.junit.jupiter.api.Assertions.assertTrue;
2324
import static org.junit.jupiter.api.Assertions.fail;
@@ -44,8 +45,6 @@
4445
import org.apache.commons.lang3.function.Consumers;
4546
import org.junit.jupiter.api.BeforeEach;
4647
import org.junit.jupiter.api.Test;
47-
import org.junit.jupiter.api.condition.EnabledOnOs;
48-
import org.junit.jupiter.api.condition.OS;
4948
import org.junit.jupiter.api.io.TempDir;
5049

5150
/**
@@ -204,12 +203,12 @@ public void testListFilesByExtension() {
204203

205204
files = FileUtils.listFiles(temporaryFolder, extensions, true);
206205
fileNames = filesToFilenames(files);
207-
assertEquals(4, fileNames.size());
206+
assertEquals(4, fileNames.size(), fileNames::toString);
208207
assertTrue(fileNames.contains("dummy-file.txt"));
209208
assertFalse(fileNames.contains("dummy-index.html"));
210209

211210
files = FileUtils.listFiles(temporaryFolder, null, false);
212-
assertEquals(2, files.size());
211+
assertEquals(2, files.size(), files::toString);
213212
fileNames = filesToFilenames(files);
214213
assertTrue(fileNames.contains("dummy-build.xml"));
215214
assertTrue(fileNames.contains("README"));
@@ -238,7 +237,6 @@ public void testListFilesWithDeletion() throws IOException {
238237
* Tests <a href="https://issues.apache.org/jira/browse/IO-856">IO-856</a> ListFiles should not fail on vanishing files.
239238
*/
240239
@Test
241-
@EnabledOnOs(value = OS.WINDOWS)
242240
public void testListFilesWithDeletionThreaded() throws ExecutionException, InterruptedException {
243241
// test for IO-856
244242
// create random directory in tmp, create the directory if it does not exist
@@ -248,33 +246,42 @@ public void testListFilesWithDeletionThreaded() throws ExecutionException, Inter
248246
fail("Could not create file path: " + tempDir.getAbsolutePath());
249247
}
250248
final int waitTime = 10_000;
249+
final int maxFiles = 500;
251250
final byte[] bytes = "TEST".getBytes(StandardCharsets.UTF_8);
252251
final CompletableFuture<Void> c1 = CompletableFuture.runAsync(() -> {
253252
final long endTime = System.currentTimeMillis() + waitTime;
254-
while (System.currentTimeMillis() < endTime) {
253+
int count = 0;
254+
while (System.currentTimeMillis() < endTime && count < maxFiles) {
255255
final File file = new File(tempDir.getAbsolutePath(), UUID.randomUUID() + ".deletetester");
256256
file.deleteOnExit();
257257
try {
258258
Files.write(file.toPath(), bytes);
259+
count++;
259260
} catch (final Exception e) {
260261
fail("Could not create test file: '" + file.getAbsolutePath() + "': " + e, e);
261262
}
262263
if (!file.delete()) {
263264
fail("Could not delete test file: '" + file.getAbsolutePath() + "'");
264265
}
265266
}
267+
// System.out.printf("Created %,d%n", count);
266268
});
267269
final CompletableFuture<Void> c2 = CompletableFuture.runAsync(() -> {
268270
final long endTime = System.currentTimeMillis() + waitTime;
271+
int max = 0;
269272
try {
270273
while (System.currentTimeMillis() < endTime) {
271-
FileUtils.listFiles(tempDir, new String[] { "\\.deletetester" }, false);
274+
final Collection<File> files = FileUtils.listFiles(tempDir, new String[] { "\\.deletetester" }, false);
275+
assertNotNull(files);
276+
max = Math.max(max, files.size());
272277
}
273278
} catch (final Exception e) {
279+
System.out.printf("List size max %,d%n", max);
274280
fail("IO-856 test failure: " + e, e);
275281
// The exception can be hidden.
276282
e.printStackTrace();
277283
}
284+
// System.out.printf("List size max %,d%n", max);
278285
});
279286
// wait for the threads to finish
280287
c1.get();

0 commit comments

Comments
 (0)