Skip to content

fix(postgres): make BasicWaitStrategies safe with container reuse - #3807

Draft
malikov73 wants to merge 1 commit into
testcontainers:mainfrom
malikov73:fix/postgres-basic-wait-reuse
Draft

fix(postgres): make BasicWaitStrategies safe with container reuse#3807
malikov73 wants to merge 1 commit into
testcontainers:mainfrom
malikov73:fix/postgres-basic-wait-reuse

Conversation

@malikov73

Copy link
Copy Markdown

What does this PR do?

Makes postgres.BasicWaitStrategies() safe to use with container reuse. The log-based wait (ForLog("database system is ready to accept connections").WithOccurrence(2)) stays as the first gate, and a live-state probe is added after it:

wait.ForExec([]string{"sh", "-c", `command -v pg_isready >/dev/null 2>&1 || exit 0; pg_isready || pg_isready -h 127.0.0.1 -p "${PGPORT:-5432}"`})

The probe prefers the unix socket, falls back to TCP on loopback honoring PGPORT, needs no valid credentials (pg_isready uses PQping, which does not authenticate — custom user/database/password keep working), and is skipped gracefully on images that do not ship pg_isready, preserving the previous behavior for them. On fresh starts the log gate passes only once the server is up, so the probe usually succeeds on its first attempt and adds no meaningful overhead.

It also adds a regression test that puts a reused container through unclean restarts: WithReuseByName, then Stop with a zero timeout while a client session keeps postgres from completing its shutdown checkpoint, so the next start is guaranteed to run crash recovery. The test asserts that a single, retry-free connection attempt succeeds right after Run returns, and that every cycle actually went through crash recovery, so the reproducer cannot degrade silently.

Why is it important?

Container logs survive restarts. On a reused container the readiness lines of the previous run already satisfy the two-occurrence log wait, so Run can return while the current postgres process is still in crash recovery, and clients fail with FATAL: the database system is not yet accepting connections. On main the added test fails consistently with exactly that error.

Related issues

How to test this PR

cd modules/postgres
go test -race -count=1 -run TestBasicWaitStrategies_reusedContainer .

On main the test fails with "the database system is not yet accepting connections"; with this change it passes. The full module suite passes with -race, and make lint is clean.

Follow-ups

  • Log-based waits remain reuse-unsafe in general (any module, any wait.ForLog user). A lifecycle-aware log wait (reading logs only since the current StartedAt) would fix the whole class, but occurrence counting needs rethinking there: a restarted data dir logs readiness only once, so WithOccurrence(2) would hang. This PR is intentionally scoped to the postgres module; I can follow up on the general mechanism if there is interest.
  • While testing I noticed DockerContainer.Exec never closes the ExecAttach hijacked response, so polling exec strategies leak one daemon connection per poll; I will file that separately.

Container logs survive restarts, so on a reused container the log-based
wait could be satisfied by the readiness messages of a previous run and
unblock before the current postgres process accepts connections.

Keep the log wait as the first gate and add a pg_isready probe of the
live server state after it. The probe cannot match stale output,
prefers the unix socket with a TCP loopback fallback honoring PGPORT,
needs no valid credentials, and is skipped on images that do not ship
pg_isready, preserving the previous behavior for them. On fresh starts
the log gate passes only once the server is up, so the probe usually
succeeds on its first attempt.

Fixes testcontainers#3671
@netlify

netlify Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploy Preview for testcontainers-go ready!

Name Link
🔨 Latest commit 018aff8
🔍 Latest deploy log https://app.netlify.com/projects/testcontainers-go/deploys/6a58dc114563c7000819bf74
😎 Deploy Preview https://deploy-preview-3807--testcontainers-go.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4ffd3a0f-ccaf-40e9-adee-a4760f978cf6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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]: BasicWaitStrategies() gives false-positive ready signal on reused containers

1 participant