[Improve][E2E] Make SeaTunnelContainer reusable across test classes to speed up E2E tests
#10784 opened on Apr 17, 2026
Description
Search before asking
- I had searched in the issues and found no similar feature requirement.
Background
E2E tests in SeaTunnel are slow. A significant portion of the overhead comes from the fact that each test class creates and destroys its own SeaTunnelContainer via ContainerTestingExtension.beforeAll/afterAll.
The full startup sequence runs for every single test class:
ContainerTestingExtension.beforeAll()
→ SeaTunnelContainer.startUp()
→ new GenericContainer(...).start() // Docker cold start: 30–60s
→ waitForLogMessage("received new worker register") // Hazelcast cluster ready
→ copyAllConnectorJarToContainer(...) // copy connector JARs into container
On teardown:
ContainerTestingExtension.afterAll()
→ SeaTunnelContainer.tearDown()
→ server.close() // container destroyed
This means a test suite with 20 test classes pays the 30–60s Docker startup cost 20 times.
Proposed Solution
Introduce a singleton/reusable SeaTunnelContainer that is started once per JVM and shared across all test classes, similar to the Testcontainers Singleton Pattern.
Key changes required:
1. Singleton container lifecycle
Move SeaTunnelContainer to a static singleton with a JVM shutdown hook instead of per-class beforeAll/afterAll:
class SharedSeaTunnelContainer {
static final SeaTunnelContainer INSTANCE;
static {
INSTANCE = new SeaTunnelContainer();
INSTANCE.startUp();
Runtime.getRuntime().addShutdownHook(new Thread(() -> INSTANCE.tearDown()));
}
}
2. Connector JAR pre-loading
Currently each test class copies only the connector JARs it needs. With a shared container, all required connectors must be copied once at startup (or support hot-copy to the container's connectors directory without restart, since Zeta supports dynamic connector loading).
3. Cleanup between test classes
tearDown currently deletes the volume and destroys the container. For a shared container, cleanup should only remove per-job artifacts (e.g., volume files written by a specific job), not destroy the container itself.
4. Adapt ContainerTestingExtension
Change the extension to inject the shared container instance instead of creating a new one in beforeAll.
Key Files
| File | Change needed |
|---|---|
SeaTunnelContainer.java |
Add singleton pattern, fix tearDown to not destroy container |
ContainerTestingExtension.java |
Inject shared container instead of creating per-class |
TestSuiteBase.java |
No change expected |
Expected Impact
- Before: N test classes × ~45s Docker startup = N × 45s overhead
- After: 1 startup × ~45s + N × ~0s (container already running)
- For a module with 20 test classes: ~15 minutes saved per CI run
Non-goals
- This issue does not cover Embedded Zeta or in-process execution
- Streaming/checkpoint E2E tests are still expected to run against the shared container (no scope reduction)
- This does not affect connector-specific external system containers (MySQL, Kafka, etc.), which remain per-class
Acceptance Criteria
-
SeaTunnelContainercan be started once and reused across multiple test classes - Connector JARs are loaded at container startup (not per test class)
- Per-job artifacts are cleaned up between test classes without container restart
- Existing E2E tests pass without modification to individual test classes
- CI wall-clock time for at least one E2E module is measurably reduced
Are you willing to submit a PR?
- Yes I am willing to submit a PR!
Code of Conduct
- I agree to follow this project's Code of Conduct