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-11834-36b0c9fe8e89223b45e8a313d4e5a2ee59274575 in repository https://gitbox.apache.org/repos/asf/seatunnel.git
commit 0e1d7f09c5e51fc4909281cfaa081cf71b970715 Author: Daniel <[email protected]> AuthorDate: Tue Sep 1 07:30:25 2026 +0000 [Test][Zeta] Use loopback IP in engine server tests (#11834) --- .../engine/server/AbstractSeaTunnelServerTest.java | 3 +- .../server/TestStallThreadDumpExtension.java | 186 +++++++++++++++++++++ .../resourcemanager/FakeResourceManager.java | 2 +- ...akeResourceManagerForExternalExceptionTest.java | 2 +- ...FakeResourceManagerForRequestSlotRetryTest.java | 2 +- .../resourcemanager/ResourceManagerTest.java | 4 +- .../server/resourcemanager/WorkerTagTest.java | 2 +- .../engine/server/rest/OptionRulesApiTest.java | 2 +- .../RestApiSubmitJobConfigShadeDecryptTest.java | 2 +- .../RestApiSubmitJobStartWithSavePointTest.java | 2 +- .../org.junit.jupiter.api.extension.Extension} | 25 +-- .../src/test/resources/batch_fake_to_inmemory.conf | 4 +- .../src/test/resources/hazelcast-client.yaml | 30 ++-- .../src/test/resources/hazelcast.yaml | 4 +- .../src/test/resources/junit-platform.properties | 24 +++ .../src/test/resources/log4j2-test.properties | 19 +++ 16 files changed, 261 insertions(+), 52 deletions(-) diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/AbstractSeaTunnelServerTest.java b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/AbstractSeaTunnelServerTest.java index 194e172e65..d95e7278ac 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/AbstractSeaTunnelServerTest.java +++ b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/AbstractSeaTunnelServerTest.java @@ -74,6 +74,7 @@ public abstract class AbstractSeaTunnelServerTest<T extends AbstractSeaTunnelSer } protected String getHazelcastConfig() { + // Use the IPv4 loopback address to avoid dual-stack localhost resolution on Windows CI. return "hazelcast:\n" + " cluster-name: seatunnel\n" + " network:\n" @@ -86,7 +87,7 @@ public abstract class AbstractSeaTunnelServerTest<T extends AbstractSeaTunnelSer + " tcp-ip:\n" + " enabled: true\n" + " member-list:\n" - + " - localhost\n" + + " - 127.0.0.1\n" + " port:\n" + " auto-increment: true\n" + " port-count: 100\n" diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/TestStallThreadDumpExtension.java b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/TestStallThreadDumpExtension.java new file mode 100644 index 0000000000..580b6ba464 --- /dev/null +++ b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/TestStallThreadDumpExtension.java @@ -0,0 +1,186 @@ +/* + * 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.seatunnel.engine.server; + +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; + +import lombok.extern.slf4j.Slf4j; + +import java.lang.management.ManagementFactory; +import java.lang.management.MonitorInfo; +import java.lang.management.ThreadInfo; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Logs a full JVM thread dump when a test class's bootstrap stalls, so hangs like the recurring + * Windows-only {@code IllegalStateException: Node failed to start!} become diagnosable from CI + * logs. + * + * <p>That failure surfaces after ~311 seconds (Hazelcast's 300-second default {@code + * hazelcast.max.join.seconds} plus shutdown overhead) with no engine log line between the config + * load and the exception, so the blocked frame never reaches CI output and each occurrence has been + * untraceable. The stall always happens inside {@code @BeforeAll} while {@code + * SeaTunnelServerStarter.createHazelcastInstance} boots the local member, which is why this + * extension only monitors the window between the {@code beforeAll} callback and the first {@code + * beforeEach} (or {@code afterAll} for classes whose tests never run): legitimate long-running test + * methods must not trigger spurious dumps. + * + * <p>The dump threshold is intentionally below Hazelcast's 300-second join ceiling so the dump is + * taken while the startup thread is still parked in the blocked frame, not after the node has + * already given up and torn itself down. + * + * <p>Registered via {@code META-INF/services/org.junit.jupiter.api.extension.Extension} with {@code + * junit.jupiter.extensions.autodetection.enabled=true} rather than a launcher {@code + * TestExecutionListener}, because the module's test classpath only provides junit-jupiter-api and + * adding junit-platform-launcher would require a pom change. + */ +@Slf4j +public class TestStallThreadDumpExtension + implements BeforeAllCallback, BeforeEachCallback, AfterAllCallback { + + /** Bootstrap time budget after which a stall is assumed and a thread dump is logged. */ + private static final long STALL_THRESHOLD_MILLIS = TimeUnit.SECONDS.toMillis(240); + + /** How often the watchdog thread re-checks the tracked bootstrap windows. */ + private static final long SCAN_PERIOD_MILLIS = TimeUnit.SECONDS.toMillis(30); + + /** + * Test classes currently inside their bootstrap window, mapped to the wall-clock start + * timestamp of that window. + */ + private static final Map<String, Long> BOOTSTRAP_START_MILLIS = new ConcurrentHashMap<>(); + + /** Classes already dumped once, so a stalled class does not flood the log every scan. */ + private static final Set<String> ALREADY_DUMPED = ConcurrentHashMap.newKeySet(); + + /** Ensures the single watchdog daemon thread is started at most once per JVM. */ + private static final AtomicBoolean WATCHDOG_STARTED = new AtomicBoolean(false); + + @Override + public void beforeAll(ExtensionContext context) { + // Extension beforeAll callbacks run before the class's own @BeforeAll methods, so this + // timestamp covers the whole server-bootstrap window where the known stalls occur. + BOOTSTRAP_START_MILLIS.put(context.getRequiredTestClass().getName(), currentTimeMillis()); + startWatchdogIfNeeded(); + } + + @Override + public void beforeEach(ExtensionContext context) { + // The first test-method setup proves @BeforeAll completed; stop monitoring this class so + // long-running test methods cannot trigger a spurious dump. + BOOTSTRAP_START_MILLIS.remove(context.getRequiredTestClass().getName()); + } + + @Override + public void afterAll(ExtensionContext context) { + // Covers classes whose test methods never start (all skipped, or bootstrap threw). + BOOTSTRAP_START_MILLIS.remove(context.getRequiredTestClass().getName()); + } + + private static void startWatchdogIfNeeded() { + if (!WATCHDOG_STARTED.compareAndSet(false, true)) { + return; + } + Thread watchdog = + new Thread(TestStallThreadDumpExtension::scanLoop, "seatunnel-test-stall-watchdog"); + // A daemon thread must never keep the surefire JVM alive after the test run finishes. + watchdog.setDaemon(true); + watchdog.start(); + } + + private static void scanLoop() { + while (true) { + try { + Thread.sleep(SCAN_PERIOD_MILLIS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return; + } + long now = currentTimeMillis(); + for (Map.Entry<String, Long> entry : BOOTSTRAP_START_MILLIS.entrySet()) { + long elapsedMillis = now - entry.getValue(); + if (elapsedMillis >= STALL_THRESHOLD_MILLIS && ALREADY_DUMPED.add(entry.getKey())) { + log.error( + "Test class {} has been inside its bootstrap window for {} seconds;" + + " logging a full thread dump before the Hazelcast join" + + " timeout converts this stall into an opaque" + + " 'Node failed to start!' failure.\n{}", + entry.getKey(), + TimeUnit.MILLISECONDS.toSeconds(elapsedMillis), + fullThreadDump()); + } + } + } + } + + /** + * Renders every live thread with its complete stack. + * + * <p>{@link ThreadInfo#toString()} silently truncates stacks to 8 frames, which is useless for + * locating a frame parked deep inside Hazelcast bootstrap, so the frames are formatted + * manually. + */ + private static String fullThreadDump() { + ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads(true, true); + StringBuilder dump = new StringBuilder(threads.length * 512); + for (ThreadInfo thread : threads) { + if (thread == null) { + continue; + } + dump.append('"') + .append(thread.getThreadName()) + .append("\" id=") + .append(thread.getThreadId()) + .append(' ') + .append(thread.getThreadState()); + if (thread.getLockName() != null) { + dump.append(" on ").append(thread.getLockName()); + } + if (thread.getLockOwnerName() != null) { + dump.append(" owned by \"") + .append(thread.getLockOwnerName()) + .append("\" id=") + .append(thread.getLockOwnerId()); + } + dump.append('\n'); + for (StackTraceElement frame : thread.getStackTrace()) { + dump.append(" at ").append(frame).append('\n'); + } + for (MonitorInfo monitor : thread.getLockedMonitors()) { + dump.append(" locked ") + .append(monitor) + .append(" at frame depth ") + .append(monitor.getLockedStackDepth()) + .append('\n'); + } + dump.append('\n'); + } + return dump.toString(); + } + + private static long currentTimeMillis() { + return System.currentTimeMillis(); + } +} diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/FakeResourceManager.java b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/FakeResourceManager.java index 7755effb74..3c739ce701 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/FakeResourceManager.java +++ b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/FakeResourceManager.java @@ -51,7 +51,7 @@ public class FakeResourceManager extends AbstractResourceManager { } private void generateWorker(int port) throws UnknownHostException { - Address address = new Address("localhost", port); + Address address = new Address("127.0.0.1", port); WorkerProfile workerProfile = new WorkerProfile( address, diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/FakeResourceManagerForExternalExceptionTest.java b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/FakeResourceManagerForExternalExceptionTest.java index 259c7fc440..e6691f8069 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/FakeResourceManagerForExternalExceptionTest.java +++ b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/FakeResourceManagerForExternalExceptionTest.java @@ -47,7 +47,7 @@ public class FakeResourceManagerForExternalExceptionTest extends AbstractResourc } private void generateWorker(int port) throws UnknownHostException { - Address address = new Address("localhost", port); + Address address = new Address("127.0.0.1", port); WorkerProfile workerProfile = new WorkerProfile( address, diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/FakeResourceManagerForRequestSlotRetryTest.java b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/FakeResourceManagerForRequestSlotRetryTest.java index 40a239b375..7d4f9ca61e 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/FakeResourceManagerForRequestSlotRetryTest.java +++ b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/FakeResourceManagerForRequestSlotRetryTest.java @@ -64,7 +64,7 @@ public class FakeResourceManagerForRequestSlotRetryTest extends AbstractResource } private void generateWorker(int port) throws UnknownHostException { - Address address = new Address("localhost", port); + Address address = new Address("127.0.0.1", port); WorkerProfile workerProfile = new WorkerProfile( address, diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/ResourceManagerTest.java b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/ResourceManagerTest.java index 0e76b5114c..a2466077a7 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/ResourceManagerTest.java +++ b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/ResourceManagerTest.java @@ -235,7 +235,7 @@ public class ResourceManagerTest extends AbstractSeaTunnelServerTest<ResourceMan List<ResourceProfile> resourceProfiles = new ArrayList<>(); resourceProfiles.add(new ResourceProfile()); ConcurrentMap<Address, WorkerProfile> registerWorker = new ConcurrentHashMap<>(); - Address address1 = new Address("localhost", 5801); + Address address1 = new Address("127.0.0.1", 5801); WorkerProfile workerProfile1 = new WorkerProfile( address1, @@ -247,7 +247,7 @@ public class ResourceManagerTest extends AbstractSeaTunnelServerTest<ResourceMan Collections.emptyMap()); registerWorker.put(address1, workerProfile1); - Address address2 = new Address("localhost", 5802); + Address address2 = new Address("127.0.0.1", 5802); WorkerProfile workerProfile2 = new WorkerProfile( address2, diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/WorkerTagTest.java b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/WorkerTagTest.java index 700e8046f6..6ba193bddc 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/WorkerTagTest.java +++ b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/resourcemanager/WorkerTagTest.java @@ -61,7 +61,7 @@ public class WorkerTagTest extends AbstractSeaTunnelServerTest<WorkerTagTest> { + " tcp-ip:\n" + " enabled: true\n" + " member-list:\n" - + " - localhost\n" + + " - 127.0.0.1\n" + " port:\n" + " auto-increment: true\n" + " port-count: 100\n" diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/OptionRulesApiTest.java b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/OptionRulesApiTest.java index cc3125dcc1..5737f4722e 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/OptionRulesApiTest.java +++ b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/OptionRulesApiTest.java @@ -161,7 +161,7 @@ class OptionRulesApiTest { + " tcp-ip:\n" + " enabled: true\n" + " member-list:\n" - + " - localhost\n" + + " - 127.0.0.1\n" + " port:\n" + " auto-increment: true\n" + " port-count: 100\n" diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/RestApiSubmitJobConfigShadeDecryptTest.java b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/RestApiSubmitJobConfigShadeDecryptTest.java index 89cd82ab06..f2d2316b85 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/RestApiSubmitJobConfigShadeDecryptTest.java +++ b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/RestApiSubmitJobConfigShadeDecryptTest.java @@ -369,7 +369,7 @@ public class RestApiSubmitJobConfigShadeDecryptTest { + " tcp-ip:\n" + " enabled: true\n" + " member-list:\n" - + " - localhost\n" + + " - 127.0.0.1\n" + " port:\n" + " auto-increment: true\n" + " port-count: 100\n" diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/RestApiSubmitJobStartWithSavePointTest.java b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/RestApiSubmitJobStartWithSavePointTest.java index 2210579a1f..e6ce345c08 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/RestApiSubmitJobStartWithSavePointTest.java +++ b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/RestApiSubmitJobStartWithSavePointTest.java @@ -521,7 +521,7 @@ public class RestApiSubmitJobStartWithSavePointTest { + " tcp-ip:\n" + " enabled: true\n" + " member-list:\n" - + " - localhost\n" + + " - 127.0.0.1\n" + " port:\n" + " auto-increment: true\n" + " port-count: 100\n" diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/resources/hazelcast-client.yaml b/seatunnel-engine/seatunnel-engine-server/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension similarity index 60% copy from seatunnel-engine/seatunnel-engine-server/src/test/resources/hazelcast-client.yaml copy to seatunnel-engine/seatunnel-engine-server/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension index 9552c382ed..861342d7bd 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/test/resources/hazelcast-client.yaml +++ b/seatunnel-engine/seatunnel-engine-server/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension @@ -1,4 +1,3 @@ -# # 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. @@ -6,32 +5,12 @@ # (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 +# 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. -# - -hazelcast-client: - cluster-name: seatunnel - network: - cluster-members: - - localhost:5801 - - localhost:5802 - - localhost:5803 - - localhost:5804 - - localhost:5805 - - localhost:5806 - - localhost:5807 - - localhost:5808 - - localhost:5809 - - localhost:5810 - - localhost:5811 - - localhost:5812 - - localhost:5813 - - localhost:5814 - - localhost:5815 +org.apache.seatunnel.engine.server.TestStallThreadDumpExtension diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/resources/batch_fake_to_inmemory.conf b/seatunnel-engine/seatunnel-engine-server/src/test/resources/batch_fake_to_inmemory.conf index ebe025644a..716f9eb158 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/test/resources/batch_fake_to_inmemory.conf +++ b/seatunnel-engine/seatunnel-engine-server/src/test/resources/batch_fake_to_inmemory.conf @@ -46,7 +46,7 @@ sink { plugin_input = "fake" username = "st" password = "stpassword" - address = "localhost" + address = "127.0.0.1" port = 1234 } -} \ No newline at end of file +} diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/resources/hazelcast-client.yaml b/seatunnel-engine/seatunnel-engine-server/src/test/resources/hazelcast-client.yaml index 9552c382ed..b256c5f9a5 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/test/resources/hazelcast-client.yaml +++ b/seatunnel-engine/seatunnel-engine-server/src/test/resources/hazelcast-client.yaml @@ -20,18 +20,18 @@ hazelcast-client: network: cluster-members: - - localhost:5801 - - localhost:5802 - - localhost:5803 - - localhost:5804 - - localhost:5805 - - localhost:5806 - - localhost:5807 - - localhost:5808 - - localhost:5809 - - localhost:5810 - - localhost:5811 - - localhost:5812 - - localhost:5813 - - localhost:5814 - - localhost:5815 + - 127.0.0.1:5801 + - 127.0.0.1:5802 + - 127.0.0.1:5803 + - 127.0.0.1:5804 + - 127.0.0.1:5805 + - 127.0.0.1:5806 + - 127.0.0.1:5807 + - 127.0.0.1:5808 + - 127.0.0.1:5809 + - 127.0.0.1:5810 + - 127.0.0.1:5811 + - 127.0.0.1:5812 + - 127.0.0.1:5813 + - 127.0.0.1:5814 + - 127.0.0.1:5815 diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/resources/hazelcast.yaml b/seatunnel-engine/seatunnel-engine-server/src/test/resources/hazelcast.yaml index c3596f53b4..af81ee98a8 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/test/resources/hazelcast.yaml +++ b/seatunnel-engine/seatunnel-engine-server/src/test/resources/hazelcast.yaml @@ -22,7 +22,7 @@ hazelcast: tcp-ip: enabled: true member-list: - - localhost + - 127.0.0.1 port: auto-increment: true port-count: 100 @@ -37,4 +37,4 @@ hazelcast: path: /tmp/file-store-map properties: hazelcast.slow.operation.detector.stacktrace.logging.enabled: true - hazelcast.slow.operation.detector.logging.enabled: true \ No newline at end of file + hazelcast.slow.operation.detector.logging.enabled: true diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/resources/junit-platform.properties b/seatunnel-engine/seatunnel-engine-server/src/test/resources/junit-platform.properties new file mode 100644 index 0000000000..0c3682ddd9 --- /dev/null +++ b/seatunnel-engine/seatunnel-engine-server/src/test/resources/junit-platform.properties @@ -0,0 +1,24 @@ +################################################################################ +# 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. +################################################################################ + +# Required so TestStallThreadDumpExtension (registered through +# META-INF/services/org.junit.jupiter.api.extension.Extension) is picked up without +# annotating every test class. The extension logs a full thread dump when a test +# class's bootstrap stalls, which is the only way to diagnose the recurring +# Windows-only "Node failed to start!" hang from CI output. +junit.jupiter.extensions.autodetection.enabled=true diff --git a/seatunnel-engine/seatunnel-engine-server/src/test/resources/log4j2-test.properties b/seatunnel-engine/seatunnel-engine-server/src/test/resources/log4j2-test.properties index cb58829e4f..bdf2fe133c 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/test/resources/log4j2-test.properties +++ b/seatunnel-engine/seatunnel-engine-server/src/test/resources/log4j2-test.properties @@ -64,3 +64,22 @@ appender.routing.route.job.appender.name = job-${ctx:ST-JID} appender.routing.route.job.appender.fileName = ${file_path}/job-${ctx:ST-JID}.log appender.routing.route.job.appender.layout.type = PatternLayout appender.routing.route.job.appender.layout.pattern = %d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%-30.30c{1.}] [%t] - %m%n + +# The routing appender's system route above references fileAppender, but this test config +# historically omitted the definition (it was copied from config/log4j2.properties without this +# block), so every server bootstrap logged "ERROR Appender fileAppender cannot be located. Route +# ignored" - misleading noise when triaging startup hangs. Mirrors the production definition. +appender.file.name = fileAppender +appender.file.type = RollingFile +appender.file.fileName = ${file_path}/${file_name}.log +appender.file.filePattern = ${file_path}/${file_name}.log.%d{yyyy-MM-dd}-%i +appender.file.append = true +appender.file.layout.type = PatternLayout +appender.file.layout.pattern = [%X{ST-JID}] %d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%-30.30c{1.}] [%t] - %m%n +appender.file.policies.type = Policies +appender.file.policies.time.type = TimeBasedTriggeringPolicy +appender.file.policies.time.modulate = true +appender.file.policies.size.type = SizeBasedTriggeringPolicy +appender.file.policies.size.size = ${file_split_size} +appender.file.strategy.type = DefaultRolloverStrategy +appender.file.strategy.fileIndex = nomax
