This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/seatunnel.git


The following commit(s) were added to refs/heads/dev by this push:
     new 372d3cd7b4 [Test][E2E] Isolate the RocketMqIT sink topics and wait for 
row visibility before reading (#12701)
372d3cd7b4 is described below

commit 372d3cd7b4d7715eb6fc811c1b43e23cb6309c4d
Author: Sepuri Sai Krishna <[email protected]>
AuthorDate: Sun Oct 11 13:02:01 2026 +0000

    [Test][E2E] Isolate the RocketMqIT sink topics and wait for row visibility 
before reading (#12701)
---
 .../e2e/connector/rocketmq/RocketMqIT.java         | 70 ++++++++++++++++++----
 .../resources/rocketmq-sink_fake_to_rocketmq.conf  |  2 +-
 ...rocketmq-sink_fake_to_rocketmq_message_tag.conf |  2 +-
 .../rocketmq-text-sink_fake_to_rocketmq.conf       |  2 +-
 4 files changed, 61 insertions(+), 15 deletions(-)

diff --git 
a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/java/org/apache/seatunnel/e2e/connector/rocketmq/RocketMqIT.java
 
b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/java/org/apache/seatunnel/e2e/connector/rocketmq/RocketMqIT.java
index 7fc989a005..f987f9bc2d 100644
--- 
a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/java/org/apache/seatunnel/e2e/connector/rocketmq/RocketMqIT.java
+++ 
b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/java/org/apache/seatunnel/e2e/connector/rocketmq/RocketMqIT.java
@@ -92,6 +92,16 @@ import java.util.concurrent.atomic.AtomicLong;
 @Slf4j
 public class RocketMqIT extends TestSuiteBase implements TestResource {
 
+    /**
+     * Rows each of the three fake-source sink jobs writes, asserted after the 
sink completes.
+     *
+     * <p>Must stay in sync with {@code row.num = 10} in 
rocketmq-sink_fake_to_rocketmq.conf,
+     * rocketmq-text-sink_fake_to_rocketmq.conf and 
rocketmq-sink_fake_to_rocketmq_message_tag.conf.
+     * The visibility wait and the count assertion both read it, so changing 
one without the other
+     * would make the wait pass early or never finish.
+     */
+    private static final int EXPECTED_SINK_ROWS = 10;
+
     private static final String IMAGE = "apache/rocketmq:4.9.4";
     private static final String ROCKETMQ_GROUP = "SeaTunnel-rocketmq-group";
     private static final String HOST = "rocketmq-e2e";
@@ -185,33 +195,42 @@ public class RocketMqIT extends TestSuiteBase implements 
TestResource {
 
     @TestTemplate
     public void testSinkRocketMq(TestContainer container) throws IOException, 
InterruptedException {
-        waitForTopicRoute("test_topic");
+        final String topicName = "test_topic_" + uniqueTestSuffix();
+        waitForTopicRoute(topicName);
 
         Container.ExecResult execResult =
-                container.executeJob("/rocketmq-sink_fake_to_rocketmq.conf");
+                container.executeJob(
+                        "/rocketmq-sink_fake_to_rocketmq.conf",
+                        Arrays.asList("sinkTopic=" + topicName));
         Assertions.assertEquals(0, execResult.getExitCode(), 
execResult.getStderr());
 
-        String topicName = "test_topic";
+        awaitSinkRowsVisible(topicName);
+
         Map<String, RocketMqConsumerMessage> data = 
getRocketMqConsumerData(topicName);
         ObjectMapper objectMapper = new ObjectMapper();
         String key = data.keySet().iterator().next();
         ObjectNode objectNode = objectMapper.readValue(key, ObjectNode.class);
         Assertions.assertTrue(objectNode.has("c_map"));
         Assertions.assertTrue(objectNode.has("c_string"));
-        Assertions.assertEquals(10, data.size());
+        Assertions.assertEquals(EXPECTED_SINK_ROWS, data.size());
     }
 
     @TestTemplate
     public void testTextFormatSinkRocketMq(TestContainer container)
             throws IOException, InterruptedException {
-        waitForTopicRoute("test_text_topic");
+        final String topicName = "test_text_topic_" + uniqueTestSuffix();
+        waitForTopicRoute(topicName);
 
         Container.ExecResult execResult =
-                
container.executeJob("/rocketmq-text-sink_fake_to_rocketmq.conf");
+                container.executeJob(
+                        "/rocketmq-text-sink_fake_to_rocketmq.conf",
+                        Arrays.asList("sinkTopic=" + topicName));
         Assertions.assertEquals(0, execResult.getExitCode(), 
execResult.getStderr());
-        String topicName = "test_text_topic";
+
+        awaitSinkRowsVisible(topicName);
+
         Map<String, RocketMqConsumerMessage> data = 
getRocketMqConsumerData(topicName);
-        Assertions.assertEquals(10, data.size());
+        Assertions.assertEquals(EXPECTED_SINK_ROWS, data.size());
     }
 
     @TestTemplate
@@ -410,20 +429,31 @@ public class RocketMqIT extends TestSuiteBase implements 
TestResource {
     @TestTemplate
     public void testSinkRocketMqMessageTag(TestContainer container)
             throws IOException, InterruptedException {
+        final String topicName = "test_topic_message_tag_" + 
uniqueTestSuffix();
+        // Warm the route before the job, not after. With the previous fixed 
topic a later
+        // template invocation always found the topic already created; a 
per-invocation topic
+        // does not exist yet, so the sink would otherwise depend on broker 
auto-creation
+        // racing the name server, which is the "No topic route info in name 
server" failure
+        // this file has hit before.
+        waitForTopicRoute(topicName);
+
         Container.ExecResult execResult =
-                
container.executeJob("/rocketmq-sink_fake_to_rocketmq_message_tag.conf");
+                container.executeJob(
+                        "/rocketmq-sink_fake_to_rocketmq_message_tag.conf",
+                        Arrays.asList("sinkTopic=" + topicName));
         Assertions.assertEquals(0, execResult.getExitCode(), 
execResult.getStderr());
 
-        String topicName = "test_topic_message_tag";
         String tag = "test_tag";
-        waitForTopicRoute(topicName);
+
+        awaitSinkRowsVisible(topicName);
+
         Map<String, RocketMqConsumerMessage> data = 
getRocketMqConsumerData(topicName);
         ObjectMapper objectMapper = new ObjectMapper();
         String key = data.keySet().iterator().next();
         ObjectNode objectNode = objectMapper.readValue(key, ObjectNode.class);
         Assertions.assertTrue(objectNode.has("c_map"));
         Assertions.assertTrue(objectNode.has("c_string"));
-        Assertions.assertEquals(10, data.size());
+        Assertions.assertEquals(EXPECTED_SINK_ROWS, data.size());
         Assertions.assertEquals(tag, data.get(key).getTag());
     }
 
@@ -921,6 +951,22 @@ public class RocketMqIT extends TestSuiteBase implements 
TestResource {
         return new ArrayList<>(bodyByPosition.values());
     }
 
+    /**
+     * Waits until every row a sink job wrote is visible to an admin offset 
read, before the single
+     * consuming read that follows.
+     *
+     * <p>Each sink test uses a topic of its own, so every queue starts at 
offset 0 and the summed
+     * max offset is exactly the number of rows stored. Without this wait the 
read can poll before
+     * the last rows are readable and the count assertion fails low. Retrying 
the read instead is
+     * not an option, because {@link #getRocketMqConsumerData(String)} commits 
offsets as it reads,
+     * so a second call would resume past what the first consumed.
+     *
+     * @param topicName the per-invocation topic the job just wrote to
+     */
+    private void awaitSinkRowsVisible(String topicName) {
+        awaitTopicMaxOffset(topicName, EXPECTED_SINK_ROWS, 
Duration.ofMinutes(1));
+    }
+
     /**
      * Waits for RocketMQ admin offset visibility and returns the successful 
observed offset.
      *
diff --git 
a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/resources/rocketmq-sink_fake_to_rocketmq.conf
 
b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/resources/rocketmq-sink_fake_to_rocketmq.conf
index 91addf77e3..0850e3bcc5 100644
--- 
a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/resources/rocketmq-sink_fake_to_rocketmq.conf
+++ 
b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/resources/rocketmq-sink_fake_to_rocketmq.conf
@@ -62,7 +62,7 @@ transform {
 sink {
   Rocketmq {
     name.srv.addr = "rocketmq-e2e:9876"
-    topic = "test_topic"
+    topic = "${sinkTopic:test_topic}"
     partition.key.fields = ["c_map", "c_string"]
     producer.send.sync = true
   }
diff --git 
a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/resources/rocketmq-sink_fake_to_rocketmq_message_tag.conf
 
b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/resources/rocketmq-sink_fake_to_rocketmq_message_tag.conf
index 0badca6bf7..9904d21a3e 100644
--- 
a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/resources/rocketmq-sink_fake_to_rocketmq_message_tag.conf
+++ 
b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/resources/rocketmq-sink_fake_to_rocketmq_message_tag.conf
@@ -62,7 +62,7 @@ transform {
 sink {
   Rocketmq {
     name.srv.addr = "rocketmq-e2e:9876"
-    topic = "test_topic_message_tag"
+    topic = "${sinkTopic:test_topic_message_tag}"
     partition.key.fields = ["c_map", "c_string"]
     producer.send.sync = true
     tag = "test_tag"
diff --git 
a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/resources/rocketmq-text-sink_fake_to_rocketmq.conf
 
b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/resources/rocketmq-text-sink_fake_to_rocketmq.conf
index ef8b325db8..bffdf9b158 100644
--- 
a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/resources/rocketmq-text-sink_fake_to_rocketmq.conf
+++ 
b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-rocketmq-e2e/src/test/resources/rocketmq-text-sink_fake_to_rocketmq.conf
@@ -62,7 +62,7 @@ transform {
 sink {
   Rocketmq {
     name.srv.addr = "rocketmq-e2e:9876"
-    topic = "test_text_topic"
+    topic = "${sinkTopic:test_text_topic}"
     format = text
     partition.key.fields = ["c_map", "c_string"]
     producer.send.sync = true

Reply via email to