Skip to content

feat: improve container conflict detection#3574

Merged
mdelapenya merged 1 commit intotestcontainers:mainfrom
Desuuuu:improve-container-conflict-detection
Mar 8, 2026
Merged

feat: improve container conflict detection#3574
mdelapenya merged 1 commit intotestcontainers:mainfrom
Desuuuu:improve-container-conflict-detection

Conversation

@Desuuuu
Copy link
Copy Markdown
Contributor

@Desuuuu Desuuuu commented Mar 7, 2026

What does this PR do?

Modify the container conflict detection regex for improved Podman compatibility.

The shape of the conflict error comes from Podman's test suite.

Why is it important?

Container creation conflicts happen fairly often when creating the reaper container in parallel tests. Making the retry logic work with the Podman provider can prevent some of these errors from happening.

Related issues

@Desuuuu Desuuuu requested a review from a team as a code owner March 7, 2026 14:10
@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 7, 2026

Deploy Preview for testcontainers-go ready!

Name Link
🔨 Latest commit a60fd7e
🔍 Latest deploy log https://app.netlify.com/projects/testcontainers-go/deploys/69ac49b96771dc0008e0e7cb
😎 Deploy Preview https://deploy-preview-3574--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
Copy link
Copy Markdown

coderabbitai Bot commented Mar 7, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bdf868a9-26e4-4b57-b114-627cd1253e40

📥 Commits

Reviewing files that changed from the base of the PR and between c0e8ab1 and a60fd7e.

📒 Files selected for processing (2)
  • docker.go
  • reaper_test.go

Summary by CodeRabbit

  • Bug Fixes

    • Broadened recognition of container name-conflict messages to handle additional wording and capitalization variations, improving reliable handling of creation races.
  • Tests

    • Added tests covering error classification across container conflicts, syscall/OS errors, context timeouts, and other error scenarios, verifying which errors are treated as permanent versus transient.

Walkthrough

Broadened container-name conflict detection regex to match Docker and Podman messages; added table-driven tests for spawner.retryError covering multiple error types and verifying permanent vs. non-permanent classification.

Changes

Cohort / File(s) Summary
Container Conflict Detection
docker.go
Adjusted the container-name conflict regex from matching "Conflict. The container name ..." to a pattern matching "[Tt]he container name .* is already in use by .*", allowing detection of Podman-style errors.
Spawner Retry Error Testing
reaper_test.go
Added TestSpawnerRetryError with multiple cases (nil path, Docker/Podman conflict messages, syscall/context/timeout-like errors, OS errors, arbitrary errors). Introduced timeoutErr test type and assertions verifying which errors are wrapped as backoff.PermanentError.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I sniffed the names in logs and hay,
Found Podman words that once went astray,
Tweaked my pattern, tests came to play,
Timeouts and conflicts now sorted today,
I hop on guard — come what may.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The test additions in reaper_test.go extend coverage beyond the scope of the linked issue #3569, which focuses solely on regex pattern updates for conflict detection. The new TestSpawnerRetryError test appears unrelated to container conflict detection regex changes; verify whether this test is necessary for the PR objectives or should be split into a separate change.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change - improving container conflict detection regex for better provider compatibility.
Description check ✅ Passed The description is directly related to the changeset, explaining the regex modification and its motivation for Podman compatibility.
Linked Issues check ✅ Passed The changes fully implement the objective from issue #3569 by updating the conflict detection regex to match both Docker and Podman error formats without requiring exact 'Conflict.' prefix.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
reaper_test.go (1)

544-613: Add coverage for the Timeout() bool retry path.

This table still misses the retryable branch for errors that only satisfy the timeout interface in reaperSpawner.retryError, so that path can regress unnoticed.

Suggested addition
 var errExpected = errors.New("expected")
+
+type timeoutErr struct{}
+
+func (timeoutErr) Error() string { return "timeout" }
+func (timeoutErr) Timeout() bool { return true }
 	tests := []struct {
 		name      string
 		err       error
 		permanent bool
 	}{
+		{
+			name:      "timeout interface error",
+			err:       fmt.Errorf("foo: %w", timeoutErr{}),
+			permanent: false,
+		},
 		{
 			name:      "random error",
 			err:       errors.New("some random error"),
 			permanent: true,
 		},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@reaper_test.go` around lines 544 - 613, Add a test case that exercises the
retry path for errors implementing the timeout interface (Timeout() bool) in
reaperSpawner.retryError: create a small error type that implements error and
Timeout() bool returning true (or wrap a net.Error-like timeout), add it to the
tests table in reaper_test.go alongside the other cases, assert that retryError
returns a non-nil error and that it is not a *backoff.PermanentError; place the
new case with name like "timeout interface error" and permanent: false so the
timeout-only branch is covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@reaper_test.go`:
- Around line 544-613: Add a test case that exercises the retry path for errors
implementing the timeout interface (Timeout() bool) in reaperSpawner.retryError:
create a small error type that implements error and Timeout() bool returning
true (or wrap a net.Error-like timeout), add it to the tests table in
reaper_test.go alongside the other cases, assert that retryError returns a
non-nil error and that it is not a *backoff.PermanentError; place the new case
with name like "timeout interface error" and permanent: false so the
timeout-only branch is covered.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8354bc0d-025a-4a45-8cba-75900218670a

📥 Commits

Reviewing files that changed from the base of the PR and between bc5413d and bdb6d18.

📒 Files selected for processing (2)
  • docker.go
  • reaper_test.go

@Desuuuu Desuuuu force-pushed the improve-container-conflict-detection branch from bdb6d18 to c0e8ab1 Compare March 7, 2026 14:52
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
reaper_test.go (1)

554-614: Add a cleanup-safe case to this table.

retryError short-circuits on isCleanupSafe(err) before the name-conflict and timeout checks, but this matrix never exercises that branch. A regression in the cleanup-safe unwrapping logic would still pass this test, so I’d add at least one retryable case for a cleanup-safe error (for example a containerd not-found/already-in-progress error).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@reaper_test.go` around lines 554 - 614, The test matrix for retryError
doesn't include a case exercising the isCleanupSafe(err) branch, so add a test
entry in the tests slice that supplies an error which isCleanupSafe should
detect (e.g., a containerd "not found" or "already in progress" diagnostic
wrapped via fmt.Errorf) and assert permanent: false; update the table near the
other cases so retryError and isCleanupSafe are exercised together and prevent
regressions in the cleanup-safe unwrapping logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@reaper_test.go`:
- Around line 554-614: The test matrix for retryError doesn't include a case
exercising the isCleanupSafe(err) branch, so add a test entry in the tests slice
that supplies an error which isCleanupSafe should detect (e.g., a containerd
"not found" or "already in progress" diagnostic wrapped via fmt.Errorf) and
assert permanent: false; update the table near the other cases so retryError and
isCleanupSafe are exercised together and prevent regressions in the cleanup-safe
unwrapping logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fe2266f8-98ef-4966-b6ba-052204227507

📥 Commits

Reviewing files that changed from the base of the PR and between bdb6d18 and c0e8ab1.

📒 Files selected for processing (2)
  • docker.go
  • reaper_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • docker.go

Modify the container conflict detection regex for improved Podman compatibility.
@Desuuuu Desuuuu force-pushed the improve-container-conflict-detection branch from c0e8ab1 to a60fd7e Compare March 7, 2026 15:52
Comment thread docker.go
var (
// createContainerFailDueToNameConflictRegex is a regular expression that matches the container is already in use error.
createContainerFailDueToNameConflictRegex = regexp.MustCompile("Conflict. The container name .* is already in use by container .*")
createContainerFailDueToNameConflictRegex = regexp.MustCompile("[Tt]he container name .* is already in use by .*")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, although we should look for another way to detect the conflicts, logs are fragile. cc/ @stevenh

Copy link
Copy Markdown
Member

@mdelapenya mdelapenya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@mdelapenya mdelapenya self-assigned this Mar 8, 2026
@mdelapenya mdelapenya added feature New functionality or new behaviors on the existing one podman Issues regarding podman. labels Mar 8, 2026
@mdelapenya mdelapenya merged commit c4e345e into testcontainers:main Mar 8, 2026
216 checks passed
mdelapenya added a commit that referenced this pull request Mar 9, 2026
…m-v2

* upstream/main: (269 commits)
  chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#3560)
  chore(deps): bump go.opentelemetry.io/otel/sdk to v1.41.0 (#3589)
  feat: add TiDB module (#3575)
  feat: add Forgejo module (#3556)
  feat: improve container conflict detection (#3574)
  chore(deps): bump go to 1.25 everywhere (#3572)
  chore(pulsar): bump base image to 4.x, replacing the wait for log strategy with wait for listening port (deterministic) (#3573)
  chore(deps): bump github.com/sigstore/sigstore in /modules/compose (#3571)
  chore(compose): update to compose-v5 (#3568)
  chore(deps): bump github.com/modelcontextprotocol/go-sdk (#3557)
  chore(deps): bump mkdocs-codeinclude-plugin from 0.2.1 to 0.3.1 (#3561)
  chore: update usage metrics (2026-03-02) (#3565)
  chore(deps): bump mkdocs-include-markdown-plugin from 7.2.0 to 7.2.1 (#3562)
  chore(deps): bump go.opentelemetry.io/otel/sdk in /modules/grafana-lgtm (#3563)
  chore(deps): bump go.opentelemetry.io/otel/sdk in /modules/toxiproxy (#3564)
  feat(azure): add lowkey vault container (#3542)
  feat(chroma): update to chroma 1.x (#3552)
  chore(deps): bump mkdocs-include-markdown-plugin from 7.2.0 to 7.2.1 (#3547)
  chore(deps): bump tj-actions/changed-files from 47.0.0 to 47.0.1 (#3546)
  chore(deps): bump actions/upload-artifact from 4.6.2 to 6.0.0 (#3545)
  ...
mdelapenya added a commit that referenced this pull request Mar 9, 2026
…archive-temp

* upstream/main:
  chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#3560)
  chore(deps): bump go.opentelemetry.io/otel/sdk to v1.41.0 (#3589)
  feat: add TiDB module (#3575)
  feat: add Forgejo module (#3556)
  feat: improve container conflict detection (#3574)
  chore(deps): bump go to 1.25 everywhere (#3572)
  chore(pulsar): bump base image to 4.x, replacing the wait for log strategy with wait for listening port (deterministic) (#3573)
  chore(deps): bump github.com/sigstore/sigstore in /modules/compose (#3571)
  chore(compose): update to compose-v5 (#3568)
  chore(deps): bump github.com/modelcontextprotocol/go-sdk (#3557)
  chore(deps): bump mkdocs-codeinclude-plugin from 0.2.1 to 0.3.1 (#3561)
  chore: update usage metrics (2026-03-02) (#3565)
  chore(deps): bump mkdocs-include-markdown-plugin from 7.2.0 to 7.2.1 (#3562)
  chore(deps): bump go.opentelemetry.io/otel/sdk in /modules/grafana-lgtm (#3563)
  chore(deps): bump go.opentelemetry.io/otel/sdk in /modules/toxiproxy (#3564)
mdelapenya added a commit that referenced this pull request Mar 10, 2026
…-action

* upstream/main: (22 commits)
  chore(deps): bump golang.org/x/mod in /modules/localstack (#3587)
  chore(deps): bump golang.org/x/mod in /modules/elasticsearch (#3585)
  chore(deps): bump golang.org/x/mod in /modules/redpanda (#3588)
  chore(deps): bump golang.org/x/mod in /modules/kafka (#3586)
  chore(deps): bump github.com/shirou/gopsutil/v4 from 4.25.12 to 4.26.2 (#3576)
  chore(deps): bump github.com/moby/go-archive from 0.1.0 to 0.2.0 (#3548)
  chore(deps): bump github.com/moby/term from 0.5.0 to 0.5.2 (#3081)
  chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#3560)
  chore(deps): bump go.opentelemetry.io/otel/sdk to v1.41.0 (#3589)
  feat: add TiDB module (#3575)
  feat: add Forgejo module (#3556)
  feat: improve container conflict detection (#3574)
  chore(deps): bump go to 1.25 everywhere (#3572)
  chore(pulsar): bump base image to 4.x, replacing the wait for log strategy with wait for listening port (deterministic) (#3573)
  chore(deps): bump github.com/sigstore/sigstore in /modules/compose (#3571)
  chore(compose): update to compose-v5 (#3568)
  chore(deps): bump github.com/modelcontextprotocol/go-sdk (#3557)
  chore(deps): bump mkdocs-codeinclude-plugin from 0.2.1 to 0.3.1 (#3561)
  chore: update usage metrics (2026-03-02) (#3565)
  chore(deps): bump mkdocs-include-markdown-plugin from 7.2.0 to 7.2.1 (#3562)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New functionality or new behaviors on the existing one podman Issues regarding podman.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Enhancement]: Improve container conflict detection compatibility

2 participants