This is an automated email from the ASF dual-hosted git repository.
jt2594838 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new ddc65546ad6 Fix test clean directory deletion (#17860)
ddc65546ad6 is described below
commit ddc65546ad65e167214a01f10142ecbae3d5950d
Author: Caideyipi <[email protected]>
AuthorDate: Thu Jun 18 16:13:52 2026 +0800
Fix test clean directory deletion (#17860)
---
.../pipe/PipeTaskInfoConsensusPipeTest.java | 4 +-
.../agent/plugin/PipeDataNodePluginAgentTest.java | 9 ++-
.../compaction/repair/AbstractRepairDataTest.java | 11 +--
.../iotdb/db/utils/ConfigurationFileUtilsTest.java | 9 +--
.../apache/iotdb/db/utils/EnvironmentUtils.java | 88 ++++++++++++++++++----
.../iotdb/db/utils/EnvironmentUtilsTest.java | 52 +++++++++++++
.../apache/iotdb/commons/utils/FileUtilsTest.java | 8 +-
7 files changed, 140 insertions(+), 41 deletions(-)
diff --git
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/pipe/PipeTaskInfoConsensusPipeTest.java
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/pipe/PipeTaskInfoConsensusPipeTest.java
index 95f03683336..1511c76abbc 100644
---
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/pipe/PipeTaskInfoConsensusPipeTest.java
+++
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/pipe/PipeTaskInfoConsensusPipeTest.java
@@ -25,6 +25,7 @@ import
org.apache.iotdb.commons.pipe.agent.task.meta.PipeRuntimeMeta;
import org.apache.iotdb.commons.pipe.agent.task.meta.PipeStaticMeta;
import org.apache.iotdb.commons.pipe.agent.task.meta.PipeStatus;
import org.apache.iotdb.commons.pipe.agent.task.meta.PipeTaskMeta;
+import org.apache.iotdb.commons.utils.FileUtils;
import
org.apache.iotdb.confignode.consensus.request.write.pipe.task.CreatePipePlanV2;
import
org.apache.iotdb.confignode.consensus.request.write.pipe.task.SetPipeStatusPlanV2;
import
org.apache.iotdb.confignode.consensus.request.write.pipe.task.SetPipeStatusWithStoppedByRuntimeExceptionPlanV2;
@@ -203,8 +204,7 @@ public class PipeTaskInfoConsensusPipeTest {
.getStatus()
.get());
} finally {
- new File(snapshotDir, "pipe_task_info.bin").delete();
- snapshotDir.delete();
+ FileUtils.deleteFileOrDirectory(snapshotDir, true);
}
}
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/agent/plugin/PipeDataNodePluginAgentTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/agent/plugin/PipeDataNodePluginAgentTest.java
index 04c759935cd..ae4d595ee0c 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/agent/plugin/PipeDataNodePluginAgentTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/agent/plugin/PipeDataNodePluginAgentTest.java
@@ -31,6 +31,7 @@ import
org.apache.iotdb.db.pipe.sink.protocol.iotconsensusv2.IoTConsensusV2Async
import
org.apache.iotdb.db.pipe.sink.protocol.thrift.async.IoTDBDataRegionAsyncSink;
import
org.apache.iotdb.db.pipe.sink.protocol.thrift.sync.IoTDBDataRegionSyncSink;
import org.apache.iotdb.db.pipe.source.dataregion.IoTDBDataRegionSource;
+import org.apache.iotdb.db.utils.EnvironmentUtils;
import org.apache.iotdb.pipe.api.customizer.parameter.PipeParameters;
import org.junit.After;
@@ -74,10 +75,10 @@ public class PipeDataNodePluginAgentTest {
String pluginPath =
PipePluginExecutableManager.getInstance()
.getPluginsDirPath(PIPE_PLUGIN_META.getPluginName());
- Files.deleteIfExists(Paths.get(pluginPath));
-
Files.deleteIfExists(Paths.get(PipePluginExecutableManager.getInstance().getInstallDir()));
- Files.deleteIfExists(Paths.get(TMP_TEMP_LIB_ROOT_DIR));
- Files.deleteIfExists(Paths.get(TMP_LIB_ROOT_DIR));
+ EnvironmentUtils.cleanDir(pluginPath);
+
EnvironmentUtils.cleanDir(PipePluginExecutableManager.getInstance().getInstallDir());
+ EnvironmentUtils.cleanDir(TMP_TEMP_LIB_ROOT_DIR);
+ EnvironmentUtils.cleanDir(TMP_LIB_ROOT_DIR);
} catch (IOException e) {
Assert.fail();
}
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/repair/AbstractRepairDataTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/repair/AbstractRepairDataTest.java
index 673e7f88106..70e4859786b 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/repair/AbstractRepairDataTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/repair/AbstractRepairDataTest.java
@@ -22,6 +22,7 @@ package
org.apache.iotdb.db.storageengine.dataregion.compaction.repair;
import org.apache.iotdb.commons.exception.MetadataException;
import org.apache.iotdb.db.exception.StorageEngineException;
import
org.apache.iotdb.db.storageengine.dataregion.compaction.AbstractCompactionTest;
+import org.apache.iotdb.db.utils.EnvironmentUtils;
import org.apache.iotdb.db.utils.constant.TestConstant;
import org.apache.tsfile.exception.write.WriteProcessException;
@@ -54,14 +55,6 @@ public class AbstractRepairDataTest extends
AbstractCompactionTest {
}
private void deleteRepairDataLogDir() throws IOException {
- if (repairDataLogDir.exists()) {
- if (repairDataLogDir.isDirectory()) {
- File[] files = repairDataLogDir.listFiles();
- for (File file : files == null ? new File[] {} : files) {
- Files.deleteIfExists(file.toPath());
- }
- }
- Files.deleteIfExists(repairDataLogDir.toPath());
- }
+ EnvironmentUtils.cleanDir(repairDataLogDir.getPath());
}
}
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/ConfigurationFileUtilsTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/ConfigurationFileUtilsTest.java
index ae419c79ecd..a21b8fc58c2 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/ConfigurationFileUtilsTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/ConfigurationFileUtilsTest.java
@@ -36,7 +36,6 @@ import java.io.InputStreamReader;
import java.nio.file.Files;
import java.util.HashSet;
import java.util.Map;
-import java.util.Objects;
import java.util.Properties;
import java.util.Set;
@@ -47,13 +46,7 @@ public class ConfigurationFileUtilsTest {
@After
public void tearDown() throws IOException {
- if (!dir.exists()) {
- return;
- }
- for (File file : Objects.requireNonNull(dir.listFiles())) {
- Files.delete(file.toPath());
- }
- Files.delete(dir.toPath());
+ EnvironmentUtils.cleanDir(dir.getPath());
}
@Test
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/EnvironmentUtils.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/EnvironmentUtils.java
index 440e32df46e..4c2e1c9c95b 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/EnvironmentUtils.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/EnvironmentUtils.java
@@ -55,7 +55,6 @@ import
org.apache.iotdb.udf.api.exception.UDFManagementException;
import org.apache.thrift.TConfiguration;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
-import org.apache.tsfile.external.commons.io.FileUtils;
import org.apache.tsfile.fileSystem.FSFactoryProducer;
import org.apache.tsfile.utils.FilePathUtils;
import org.slf4j.Logger;
@@ -69,6 +68,12 @@ import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.fail;
@@ -83,6 +88,8 @@ public class EnvironmentUtils {
private static final DataNodeMemoryConfig memoryConfig =
IoTDBDescriptor.getInstance().getMemoryConfig();
private static final TierManager tierManager = TierManager.getInstance();
+ private static final int DELETE_RETRY_TIMES = 5;
+ private static final long DELETE_RETRY_INTERVAL_MS = 100;
public static long TEST_QUERY_JOB_ID = 1;
public static QueryContext TEST_QUERY_CONTEXT = new
QueryContext(TEST_QUERY_JOB_ID, false);
@@ -277,7 +284,69 @@ public class EnvironmentUtils {
}
public static void cleanDir(String dir) throws IOException {
- FSFactoryProducer.getFSFactory().deleteDirectory(dir);
+ Path path = FSFactoryProducer.getFSFactory().getFile(dir).toPath();
+ if (!Files.exists(path)) {
+ return;
+ }
+
+ IOException lastException = null;
+ for (int i = 0; i < DELETE_RETRY_TIMES; i++) {
+ try {
+ deleteRecursively(path);
+ return;
+ } catch (NoSuchFileException e) {
+ return;
+ } catch (IOException e) {
+ lastException = e;
+ if (i + 1 == DELETE_RETRY_TIMES) {
+ break;
+ }
+ try {
+ TimeUnit.MILLISECONDS.sleep(DELETE_RETRY_INTERVAL_MS);
+ } catch (InterruptedException interruptedException) {
+ Thread.currentThread().interrupt();
+ IOException ioException =
+ new IOException("Interrupted while deleting " + dir,
interruptedException);
+ ioException.addSuppressed(e);
+ throw ioException;
+ }
+ }
+ }
+ throw lastException;
+ }
+
+ private static void deleteRecursively(Path path) throws IOException {
+ if (!Files.exists(path)) {
+ return;
+ }
+
+ Files.walkFileTree(
+ path,
+ new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes
attrs)
+ throws IOException {
+ Files.deleteIfExists(file);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFileFailed(Path file, IOException exc)
throws IOException {
+ if (exc instanceof NoSuchFileException) {
+ return FileVisitResult.CONTINUE;
+ }
+ throw exc;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc)
throws IOException {
+ if (exc != null) {
+ throw exc;
+ }
+ Files.deleteIfExists(dir);
+ return FileVisitResult.CONTINUE;
+ }
+ });
}
/** disable memory control</br> this function should be called before all
code in the setup */
@@ -338,19 +407,6 @@ public class EnvironmentUtils {
}
public static void recursiveDeleteFolder(String path) throws IOException {
- File file = new File(path);
- if (file.isDirectory()) {
- File[] files = file.listFiles();
- if (files == null || files.length == 0) {
- FileUtils.deleteDirectory(file);
- } else {
- for (File f : files) {
- recursiveDeleteFolder(f.getAbsolutePath());
- }
- FileUtils.deleteDirectory(file);
- }
- } else {
- FileUtils.delete(file);
- }
+ cleanDir(path);
}
}
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/EnvironmentUtilsTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/EnvironmentUtilsTest.java
new file mode 100644
index 00000000000..36783d78dec
--- /dev/null
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/EnvironmentUtilsTest.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.utils;
+
+import org.apache.iotdb.db.utils.constant.TestConstant;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.Collections;
+
+public class EnvironmentUtilsTest {
+
+ private final File testDir = new File(TestConstant.BASE_OUTPUT_PATH,
"EnvironmentUtilsTest");
+
+ @After
+ public void tearDown() throws IOException {
+ EnvironmentUtils.cleanDir(testDir.getPath());
+ }
+
+ @Test
+ public void testCleanDirDeletesNestedDirectory() throws IOException {
+ File nestedDir = new File(testDir, "ext" + File.separator + "udf" +
File.separator + "tmp");
+ Assert.assertTrue(nestedDir.isDirectory() || nestedDir.mkdirs());
+ Files.write(new File(nestedDir, "plugin.txt").toPath(),
Collections.singletonList("plugin"));
+
+ EnvironmentUtils.cleanDir(testDir.getPath());
+
+ Assert.assertFalse(testDir.exists());
+ }
+}
diff --git
a/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/utils/FileUtilsTest.java
b/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/utils/FileUtilsTest.java
index cc1586f5f74..4c2210998b0 100644
---
a/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/utils/FileUtilsTest.java
+++
b/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/utils/FileUtilsTest.java
@@ -46,8 +46,12 @@ public class FileUtilsTest {
@After
public void tearDown() throws Exception {
- tmpDir.delete();
- targetDir.delete();
+ if (tmpDir != null) {
+ FileUtils.deleteFileOrDirectory(tmpDir, true);
+ }
+ if (targetDir != null) {
+ FileUtils.deleteFileOrDirectory(targetDir, true);
+ }
}
@Test