From 226e0b9e49f1c715671e0eeb84353297e7aab32b Mon Sep 17 00:00:00 2001 From: Thomas Hartwig Date: Tue, 5 Nov 2024 14:34:22 +0100 Subject: [PATCH 1/3] [IO-856] test for background deletion --- .../commons/io/FileUtilsListFilesTest.java | 63 +++++++++++++++---- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java b/src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java index b50616483e5..de7287d2ca0 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java @@ -16,10 +16,13 @@ */ package org.apache.commons.io; -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 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.io.TempDir; import java.io.File; import java.io.IOException; @@ -30,13 +33,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -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.io.TempDir; +import static org.junit.jupiter.api.Assertions.*; /** * Tests FileUtils.listFiles() methods. @@ -222,4 +219,48 @@ public void testListFilesWithDeletion() throws IOException { assertEquals(4, list.size()); } + @Test + public void testListFilesWithDeletionThreaded() throws java.util.concurrent.ExecutionException, InterruptedException { + // test for IO-856 + // create random directory in tmp, create the directory if it does not exist + final File dir = FileUtils.getTempDirectory(); + if (!dir.exists()) { + if (!dir.mkdirs()) { + throw new RuntimeException("could not create image file path: " + dir.getAbsolutePath()); + } + } + final int waitTime = 10000; + final java.util.concurrent.CompletableFuture c1 = java.util.concurrent.CompletableFuture.runAsync(() -> { + long endTime = System.currentTimeMillis() + waitTime; + while (System.currentTimeMillis() < endTime) { + final File file = new File(dir.getAbsolutePath(), java.util.UUID.randomUUID() + ".deletetester"); + file.deleteOnExit(); + try { + new java.io.BufferedOutputStream(java.nio.file.Files.newOutputStream(file.toPath())).write("TEST".getBytes(java.nio.charset.StandardCharsets.UTF_8)); + } catch (Exception e) { + throw new RuntimeException("could not create test file: " + file.getAbsolutePath(), e); + } + if (!file.delete()) { + throw new RuntimeException("could not delete test file: " + file.getAbsolutePath()); + } + } + }); + + final java.util.concurrent.CompletableFuture c2 = java.util.concurrent.CompletableFuture.runAsync(() -> { + long endTime = System.currentTimeMillis() + waitTime; + try { + while (System.currentTimeMillis() < endTime) { + final Collection files = FileUtils.listFiles(dir, new String[]{"\\.deletetester"}, false); + files.size(); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + + // wait for the threads to finish + c1.get(); + c2.get(); + } + } From ad4414696dcc2e1f12eca4b2ee51d91094374973 Mon Sep 17 00:00:00 2001 From: Thomas Hartwig Date: Tue, 5 Nov 2024 14:34:22 +0100 Subject: [PATCH 2/3] [IO-856] test for background deletion --- .../commons/io/FileUtilsListFilesTest.java | 64 +++++++++++++++---- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java b/src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java index b50616483e5..4111711e529 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java @@ -16,27 +16,26 @@ */ package org.apache.commons.io; -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 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.io.TempDir; +import java.io.BufferedOutputStream; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import java.util.stream.Stream; -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.io.TempDir; +import static org.junit.jupiter.api.Assertions.*; /** * Tests FileUtils.listFiles() methods. @@ -222,4 +221,47 @@ public void testListFilesWithDeletion() throws IOException { assertEquals(4, list.size()); } + @Test + public void testListFilesWithDeletionThreaded() throws java.util.concurrent.ExecutionException, InterruptedException { + // test for IO-856 + // create random directory in tmp, create the directory if it does not exist + final File dir = FileUtils.getTempDirectory(); + if (!dir.exists()) { + if (!dir.mkdirs()) { + throw new RuntimeException("could not create image file path: " + dir.getAbsolutePath()); + } + } + final int waitTime = 10000; + final CompletableFuture c1 = java.util.concurrent.CompletableFuture.runAsync(() -> { + long endTime = System.currentTimeMillis() + waitTime; + while (System.currentTimeMillis() < endTime) { + final File file = new File(dir.getAbsolutePath(), java.util.UUID.randomUUID() + ".deletetester"); + file.deleteOnExit(); + try { + new BufferedOutputStream(java.nio.file.Files.newOutputStream(file.toPath())).write("TEST".getBytes(java.nio.charset.StandardCharsets.UTF_8)); + } catch (Exception e) { + fail("could not create test file: " + file.getAbsolutePath(), e); + } + if (!file.delete()) { + fail("could not delete test file: " + file.getAbsolutePath()); + } + } + }); + + final CompletableFuture c2 = java.util.concurrent.CompletableFuture.runAsync(() -> { + long endTime = System.currentTimeMillis() + waitTime; + try { + while (System.currentTimeMillis() < endTime) { + FileUtils.listFiles(dir, new String[]{"\\.deletetester"}, false); + } + } catch (Exception e) { + fail("this should not happen", e); + } + }); + + // wait for the threads to finish + c1.get(); + c2.get(); + } + } From ea5fce8fce941d968893aabd1cc112bb28dfdf85 Mon Sep 17 00:00:00 2001 From: Thomas Hartwig Date: Mon, 11 Nov 2024 10:31:57 +0100 Subject: [PATCH 3/3] fix for test pattern list --- src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java | 2 +- 1 file changed, 1 insertion(+), 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 2c26f301205..8907bd1fe2c 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsListFilesTest.java @@ -271,7 +271,7 @@ public void testListFilesWithDeletionThreaded() throws ExecutionException, Inter int max = 0; try { while (System.currentTimeMillis() < endTime) { - final Collection files = FileUtils.listFiles(tempDir, new String[] { "\\.deletetester" }, false); + final Collection files = FileUtils.listFiles(tempDir, new String[] { ".deletetester" }, false); assertNotNull(files); max = Math.max(max, files.size()); }