Skip to content

fix(wait): fail fast when container exits before the expected log output - #12152

Open
Inf1mum wants to merge 1 commit into
testcontainers:mainfrom
Inf1mum:fix/12151-log-wait-failfast
Open

Inf1mum wants to merge 1 commit into
testcontainers:mainfrom
Inf1mum:fix/12151-log-wait-failfast

Conversation

@Inf1mum

@Inf1mum Inf1mum commented Nov 4, 2026

Copy link
Copy Markdown

Fixes #12151

What has changed?

LogMessageWaitStrategy now aborts the wait as soon as waitStrategyTarget is no longer running, instead of waiting the whole startup timeout when the container exits before producing the expected log output.

The existing WaitingConsumer.waitUntil(...) call is unchanged (same startup timeout, same times semantics) and runs on the shared AbstractWaitStrategy.EXECUTOR, while the calling thread polls the target with the same Awaitility failFast pattern that HostPortWaitStrategy already relies on:

.failFast("container is no longer running", () -> !waitStrategyTarget.isRunning())

When the container exits before a match, the wait fails with Container stopped before the expected log output matching '<regEx>' was produced. A short (~1s) grace period lets output buffered right before the exit still match, so a container that prints the expected message and then exits keeps succeeding. Detecting OutputFrame.END in the wait predicate was considered but rejected: frames are polled from the buffer newest-first (pollLast in WaitingConsumer), so END can be examined before earlier buffered frames and would false-fail that case. Timeout semantics for a still-running container are unchanged (Timed out waiting for log output ...).

For the repro from the issue (alpine printing started, then exit 1 after ~2s, waiting for .*never.* with a 60s startup timeout), start() now fails in ~3s instead of ~62s.

Testing

Added LogMessageWaitStrategyTest (real containers, like DockerHealthcheckWaitStrategyTest):

  • shouldFailFastWhenContainerExitsBeforeExpectedLogOutput — the issue repro; asserts launch fails with the new message well under the startup timeout (measured ~3s vs the 60s timeout).
  • shouldStillTimeOutWhenContainerKeepsRunningWithoutExpectedLogOutput — timeout semantics for a still-running container are unchanged.
  • shouldSucceedWhenExpectedLogOutputAppearsWhileContainerIsRunning — the regular match path still works.

Ran locally with Docker available (docker info reports 29.7.2): all three tests pass, plus the existing org.testcontainers.containers.wait.strategy.* and org.testcontainers.containers.output.* tests. Formatting via ./gradlew spotlessApply.

@Inf1mum
Inf1mum requested a review from a team as a code owner November 4, 2026 22:41
@Inf1mum

Inf1mum commented Nov 5, 2026

Copy link
Copy Markdown
Author

Hi! These are my first PRs to this repo, so the CI workflows (CI, CI-Docker-Rootless, CI-Docker-Wormhole) have been sitting in "Awaiting approval" (action_required) since Nov 4 — could someone approve the workflow runs so the matrix can execute? Happy to address any review feedback. (Related: #12153, #12154)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: LogMessageWaitStrategy waits for the full startup timeout after the container exits

1 participant