This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-io.git
The following commit(s) were added to refs/heads/master by this push: new 92c5e8cc7 [IO-856] Tests ListFiles should not fail on vanishing files 92c5e8cc7 is described below commit 92c5e8cc785d476a82322fbf5b23afa77ad88cb8 Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Sun Nov 10 07:36:56 2024 -0500 [IO-856] Tests ListFiles should not fail on vanishing files - Add org.apache.commons.io.FileUtilsListFilesTest.testListFilesWithDeletionThreaded() - Only enable on Windows - Hidden failures on GitHub CI on Ubuntu and macOS --- .../apache/commons/io/FileUtilsListFilesTest.java | 59 +++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java b/src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java index b50616483..43b13cc91 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java @@ -20,22 +20,32 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.apache.commons.io.file.PathUtils; import org.apache.commons.io.filefilter.FileFilterUtils; import org.apache.commons.io.filefilter.IOFileFilter; import org.apache.commons.io.function.Uncheck; import org.apache.commons.lang3.function.Consumers; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledOnOs; +import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.api.io.TempDir; /** @@ -211,7 +221,9 @@ public class FileUtilsListFilesTest { final String[] extensions = {"xml", "txt"}; final List<File> list; final File xFile = new File(temporaryFolder, "x.xml"); - xFile.createNewFile(); + if (!xFile.createNewFile()) { + fail("could not create test file: " + xFile); + } final Collection<File> files = FileUtils.listFiles(temporaryFolder, extensions, true); assertEquals(5, files.size()); try (Stream<File> stream = Uncheck.get(() -> FileUtils.streamFiles(temporaryFolder, true, extensions))) { @@ -222,4 +234,49 @@ public class FileUtilsListFilesTest { assertEquals(4, list.size()); } + /** + * Tests <a href="https://issues.apache.org/jira/browse/IO-856">IO-856</a> ListFiles should not fail on vanishing files. + */ + @Test + @EnabledOnOs(value = OS.WINDOWS) + public void testListFilesWithDeletionThreaded() throws ExecutionException, InterruptedException { + // test for IO-856 + // create random directory in tmp, create the directory if it does not exist + final Path tempPath = PathUtils.getTempDirectory().resolve("IO-856"); + final File tempDir = tempPath.toFile(); + if (!tempDir.exists() && !tempDir.mkdirs()) { + fail("Could not create file path: " + tempDir.getAbsolutePath()); + } + final int waitTime = 10_000; + final byte[] bytes = "TEST".getBytes(StandardCharsets.UTF_8); + final CompletableFuture<Void> c1 = CompletableFuture.runAsync(() -> { + final long endTime = System.currentTimeMillis() + waitTime; + while (System.currentTimeMillis() < endTime) { + final File file = new File(tempDir.getAbsolutePath(), UUID.randomUUID() + ".deletetester"); + file.deleteOnExit(); + try { + Files.write(file.toPath(), bytes); + } catch (final Exception e) { + fail("Could not create test file: " + file.getAbsolutePath(), e); + } + if (!file.delete()) { + fail("Could not delete test file: " + file.getAbsolutePath()); + } + } + }); + final CompletableFuture<Void> c2 = CompletableFuture.runAsync(() -> { + final long endTime = System.currentTimeMillis() + waitTime; + try { + while (System.currentTimeMillis() < endTime) { + FileUtils.listFiles(tempDir, new String[] { "\\.deletetester" }, false); + } + } catch (final Exception e) { + fail("Should not happen", e); + } + }); + // wait for the threads to finish + c1.get(); + c2.get(); + } + }