apache/seatunnel

[Improve][E2E] Make SeaTunnelContainer reusable across test classes to speed up E2E tests

Open

Aperta il 17 apr 2026

Vedi su GitHub
 (2 commenti) (0 reazioni) (1 assegnatario)Java (6897 star) (1432 fork)batch import
Testhelp wantedimprove

Descrizione

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

  • SeaTunnelContainer can 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

Guida contributor