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();
+    }
+
 }

Reply via email to