This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/dev/pr-12653-fc1448c48ff93a046292b495590124813838786c in repository https://gitbox.apache.org/repos/asf/seatunnel.git
commit 704b3fec9de38dcb95732616ab258d76ada89f1f Author: Jast <[email protected]> AuthorDate: Thu Oct 8 13:23:30 2026 +0000 [Test][Connector-V2] Poll for storage readiness instead of fixed sleeps in e2e tests (#12653) Co-authored-by: root <[email protected]> --- .../e2e/connector/databend/DatabendCDCSinkIT.java | 15 +++++++------- .../e2e/connector/databend/DatabendIT.java | 15 +++++++------- .../e2e/connector/file/hdfs/HdfsFileIT.java | 14 ++++++++++++- .../e2e/connector/file/hdfs/HdfsFileViewFsIT.java | 23 +++++++++++++++++++++- .../file/local/LocalFileWithMetadataIT.java | 23 ++++++++++++++++++++-- 5 files changed, 72 insertions(+), 18 deletions(-) diff --git a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-databend-e2e/src/test/java/org/apache/seatunnel/e2e/connector/databend/DatabendCDCSinkIT.java b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-databend-e2e/src/test/java/org/apache/seatunnel/e2e/connector/databend/DatabendCDCSinkIT.java index 4d8a43f560..72c66871ae 100644 --- a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-databend-e2e/src/test/java/org/apache/seatunnel/e2e/connector/databend/DatabendCDCSinkIT.java +++ b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-databend-e2e/src/test/java/org/apache/seatunnel/e2e/connector/databend/DatabendCDCSinkIT.java @@ -226,13 +226,14 @@ public class DatabendCDCSinkIT extends TestSuiteBase implements TestResource { this.minioContainer.start(); - LOG.info("MinIO container starting,wait 5 secs ..."); - Thread.sleep(5000); - - boolean bucketCreated = createMinIOBucketWithAWSSDK("databend"); - if (!bucketCreated) { - LOG.warn("can't make sure MinIO bucket create success,continue to start Databend"); - } + // The bucket must exist before Databend boots against it; retry the + // creation until it succeeds instead of a fixed sleep followed by a + // single attempt that can silently miss a slow MinIO startup. + Awaitility.given() + .ignoreExceptions() + .atMost(60, TimeUnit.SECONDS) + .pollInterval(2, TimeUnit.SECONDS) + .until(() -> createMinIOBucketWithAWSSDK("databend")); this.container = new DatabendContainer(DATABEND_DOCKER_IMAGE) .withNetwork(NETWORK) diff --git a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-databend-e2e/src/test/java/org/apache/seatunnel/e2e/connector/databend/DatabendIT.java b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-databend-e2e/src/test/java/org/apache/seatunnel/e2e/connector/databend/DatabendIT.java index e84b6c4523..af149c537b 100644 --- a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-databend-e2e/src/test/java/org/apache/seatunnel/e2e/connector/databend/DatabendIT.java +++ b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-databend-e2e/src/test/java/org/apache/seatunnel/e2e/connector/databend/DatabendIT.java @@ -254,13 +254,14 @@ public class DatabendIT extends TestSuiteBase implements TestResource { this.minioContainer.start(); - LOG.info("MinIO container starting,wait 5 secs ..."); - Thread.sleep(5000); - - boolean bucketCreated = createMinIOBucketWithAWSSDK("databend"); - if (!bucketCreated) { - LOG.warn("can't make sure MinIO bucket create success,continue to start Databend"); - } + // The bucket must exist before Databend boots against it; retry the + // creation until it succeeds instead of a fixed sleep followed by a + // single attempt that can silently miss a slow MinIO startup. + Awaitility.given() + .ignoreExceptions() + .atMost(60, java.util.concurrent.TimeUnit.SECONDS) + .pollInterval(2, java.util.concurrent.TimeUnit.SECONDS) + .until(() -> createMinIOBucketWithAWSSDK("databend")); this.container = new DatabendContainer(DATABEND_DOCKER_IMAGE) .withNetwork(NETWORK) diff --git a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-file-hadoop-e2e/src/test/java/org/apache/seatunnel/e2e/connector/file/hdfs/HdfsFileIT.java b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-file-hadoop-e2e/src/test/java/org/apache/seatunnel/e2e/connector/file/hdfs/HdfsFileIT.java index 095dde01e5..4b3cdc11f1 100644 --- a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-file-hadoop-e2e/src/test/java/org/apache/seatunnel/e2e/connector/file/hdfs/HdfsFileIT.java +++ b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-file-hadoop-e2e/src/test/java/org/apache/seatunnel/e2e/connector/file/hdfs/HdfsFileIT.java @@ -100,7 +100,19 @@ public class HdfsFileIT extends TestSuiteBase implements TestResource { DockerLoggerFactory.getLogger(HADOOP_IMAGE + ":datanode"))); Startables.deepStart(Stream.of(nameNode, dataNode)).join(); - Thread.sleep(5000); + // The DataNode has no wait strategy of its own; poll until it has registered + // with the NameNode instead of a fixed sleep, so a slow registration does + // not fail the first HDFS operation. + Awaitility.await() + .atMost(2, TimeUnit.MINUTES) + .pollInterval(2, TimeUnit.SECONDS) + .ignoreExceptions() + .untilAsserted( + () -> + Assertions.assertTrue( + nameNode.execInContainer("hdfs", "dfsadmin", "-report") + .getStdout() + .contains("Live datanodes (1)"))); } @AfterAll diff --git a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-file-hadoop-e2e/src/test/java/org/apache/seatunnel/e2e/connector/file/hdfs/HdfsFileViewFsIT.java b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-file-hadoop-e2e/src/test/java/org/apache/seatunnel/e2e/connector/file/hdfs/HdfsFileViewFsIT.java index 2832526794..78d74d87aa 100644 --- a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-file-hadoop-e2e/src/test/java/org/apache/seatunnel/e2e/connector/file/hdfs/HdfsFileViewFsIT.java +++ b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-file-hadoop-e2e/src/test/java/org/apache/seatunnel/e2e/connector/file/hdfs/HdfsFileViewFsIT.java @@ -23,6 +23,7 @@ import org.apache.seatunnel.e2e.common.container.ContainerExtendedFactory; import org.apache.seatunnel.e2e.common.container.TestContainer; import org.apache.seatunnel.e2e.common.junit.TestContainerExtension; +import org.awaitility.Awaitility; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; @@ -39,6 +40,7 @@ import lombok.extern.slf4j.Slf4j; import java.io.IOException; import java.time.Duration; +import java.util.concurrent.TimeUnit; import java.util.stream.Stream; @Slf4j @@ -138,7 +140,26 @@ public class HdfsFileViewFsIT extends TestSuiteBase implements TestResource { DockerLoggerFactory.getLogger(HADOOP_IMAGE + ":datanode2"))) .dependsOn(nameNode2); Startables.deepStart(Stream.of(nameNode1, dataNode1, nameNode2, dataNode2)).join(); - Thread.sleep(5000); + // The DataNodes have no wait strategy of their own; poll until each has + // registered with its NameNode instead of a fixed sleep, so a slow + // registration does not fail the first HDFS operation. + Awaitility.await() + .atMost(2, TimeUnit.MINUTES) + .pollInterval(2, TimeUnit.SECONDS) + .ignoreExceptions() + .untilAsserted( + () -> { + Assertions.assertTrue( + nameNode1 + .execInContainer("hdfs", "dfsadmin", "-report") + .getStdout() + .contains("Live datanodes (1)")); + Assertions.assertTrue( + nameNode2 + .execInContainer("hdfs", "dfsadmin", "-report") + .getStdout() + .contains("Live datanodes (1)")); + }); } @AfterAll diff --git a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-file-local-e2e/src/test/java/org/apache/seatunnel/e2e/connector/file/local/LocalFileWithMetadataIT.java b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-file-local-e2e/src/test/java/org/apache/seatunnel/e2e/connector/file/local/LocalFileWithMetadataIT.java index 1687d5ee2f..0105f25531 100644 --- a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-file-local-e2e/src/test/java/org/apache/seatunnel/e2e/connector/file/local/LocalFileWithMetadataIT.java +++ b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-file-local-e2e/src/test/java/org/apache/seatunnel/e2e/connector/file/local/LocalFileWithMetadataIT.java @@ -23,6 +23,7 @@ import org.apache.seatunnel.e2e.common.junit.TestContainerExtension; import org.apache.seatunnel.e2e.common.util.ContainerUtil; import org.apache.seatunnel.e2e.common.util.MavenJarUtil; +import org.awaitility.Awaitility; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -39,6 +40,7 @@ import org.testcontainers.utility.MountableFile; import lombok.extern.slf4j.Slf4j; import java.nio.file.Paths; +import java.util.concurrent.TimeUnit; import static org.apache.seatunnel.e2e.common.util.ContainerUtil.PROJECT_ROOT_PATH; @@ -151,8 +153,25 @@ public class LocalFileWithMetadataIT extends SeaTunnelContainer { new Slf4jLogConsumer(DockerLoggerFactory.getLogger(MYSQL_IMAGE))); mysqlContainer.start(); log.info("MySQL container started at {}", mysqlContainer.getHost()); - // Wait for MySQL to be fully ready - Thread.sleep(10000); + // The healthcheck only covers the server process; poll until the root + // account is actually usable, because Gravitino's catalog creation + // connects to MySQL right after this and fails on a slow init. + Awaitility.await() + .atMost(2, TimeUnit.MINUTES) + .pollInterval(2, TimeUnit.SECONDS) + .ignoreExceptions() + .untilAsserted( + () -> + Assertions.assertEquals( + 0, + mysqlContainer + .execInContainer( + "mysql", + "-u" + MYSQL_USERNAME, + "-p" + MYSQL_PASSWORD, + "-e", + "SELECT 1") + .getExitCode())); } private void startGravitinoServer() throws Exception {
