Skip to content

Conversation

@mdelapenya
Copy link
Member

Fixes #2811

Previously ExposedHostPorts would start an SSHD container prior to
starting the testcontainer and inject a PostReadies lifecycle hook into
the testcontainer in order to set up remote port forwarding from the
host to the SSHD container so the testcontainer can talk to the host via
the SSHD container

This would be an issue if the testcontainer depends on accessing the
host port on startup ( e.g., a proxy server ) as the forwarding for the
host access isn't set up until all the WiatFor strategies on the
testcontainer have completed.

The fix is to move the forwarding setup to the PreCreates hook on the
testcontainer. Since remote forwarding doesn't establish a connection to
the host port until a connection is made to the remote port, this should
not be an issue even if the host isn't listening yet and ensures the
remote port is available to the testcontainer immediately.

What does this PR do?

Changes the lifecycle hook for the ExposedHostPorts forwarding to happen on PreCreates of the testcontainer instead of PostReadies. Additionally updates the port forwarding tests to ensure the host ports are accessible on startup and that there's no issues even if the host isn't listening until PostCreates.

Why is it important?

Previously ExposedHostPorts would start an SSHD container prior to starting the testcontainer and inject a PostReadies lifecycle hook into the testcontainer in order to set up remote port forwarding from the host to the SSHD container so the testcontainer can talk to the host via the SSHD container

This would be an issue if the testcontainer depends on accessing the host port on startup ( e.g., a proxy server ) as the forwarding for the host access isn't set up until all the WiatFor strategies on the testcontainer have completed.

Related issues

How to test this PR

go test port_forwarding_test.go

Additionally, I've provided a minimal example of my use case where I ran into the issue trying to test my Caddy configuration as an API gateway using testcontainers.

package caddy_test

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"net"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/testcontainers/testcontainers-go"
	"github.com/testcontainers/testcontainers-go/wait"
)

const caddyFileContent = `
listen :80

reverse_proxy /api/* {
	to {$API_SERVER}

	health_uri /health
	health_status 200
	health_interval 10s
}
`

func TestCaddyfile(t *testing.T) {
	ctx := context.Background()

	apiServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, World!")
	}))
	apiServerPort := apiServer.Listener.Addr().(*net.TCPAddr).Port

	caddyContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
		ContainerRequest: testcontainers.ContainerRequest{
			Image:        "caddy:2.8.4",
			ExposedPorts: []string{"80/tcp"},
			WaitingFor:   wait.ForLog("server running"),
			Env: map[string]string{
				"API_SERVER": fmt.Sprintf("http://%s:%d", testcontainers.HostInternal, apiServerPort),
			},
			Files: []testcontainers.ContainerFile{
				{
					Reader:            bytes.NewReader([]byte(caddyFileContent)),
					ContainerFilePath: "/etc/caddy/Caddyfile",
				},
			},
			HostAccessPorts: []int{apiServerPort},
		},
		Started: true,
	})
	require.NoError(t, err)
	defer caddyContainer.Terminate(ctx)

	caddyURL, err := caddyContainer.PortEndpoint(ctx, "80/tcp", "http")
	require.NoError(t, err)

	resp, err := http.Get(caddyURL + "/api/test")
	require.NoError(t, err)
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	require.NoError(t, err)

	assert.Equal(t, http.StatusOK, resp.StatusCode)
	assert.Equal(t, "Hello, World!", string(body))

	lr, err := caddyContainer.Logs(ctx)
	assert.NoError(t, err)
	lb, err := io.ReadAll(lr)
	assert.NoError(t, err)
	fmt.Printf("== Caddy Logs ==\n%s================\n\n", string(lb))
}

hathvi and others added 2 commits October 5, 2024 10:46
Fixes testcontainers#2811

Previously ExposedHostPorts would start an SSHD container prior to
starting the testcontainer and inject a PostReadies lifecycle hook into
the testcontainer in order to set up remote port forwarding from the
host to the SSHD container so the testcontainer can talk to the host via
the SSHD container

This would be an issue if the testcontainer depends on accessing the
host port on startup ( e.g., a proxy server ) as the forwarding for the
host access isn't set up until all the WiatFor strategies on the
testcontainer have completed.

The fix is to move the forwarding setup to the PreCreates hook on the
testcontainer. Since remote forwarding doesn't establish a connection to
the host port until a connection is made to the remote port, this should
not be an issue even if the host isn't listening yet and ensures the
remote port is available to the testcontainer immediately.
* main: (236 commits)
  feat(kafka,redpanda): support for waiting for mapped ports without external checks (testcontainers#3165)
  chore: bump ryuk to 0.12.0 (testcontainers#3195)
  feat!: add options when creating RawCommand (testcontainers#3168)
  chore(deps)!: bump github.com/docker/docker from 28.1.1+incompatible to 28.2.2+incompatible (testcontainers#3194)
  feat(couchbase): adding auth to couchbase initCluster functions to support container reuse (testcontainers#3048)
  chore(deps): bump github.com/containerd/containerd/v2 (testcontainers#3167)
  docs(options): refactor options layout in modules (testcontainers#3163)
  fix(ci): do not run sonar for Testcontainers Cloud (testcontainers#3166)
  chore(ci): do not fail fast in the Testcontainers Cloud run (testcontainers#3164)
  feat: support adding wait strategies as functional option (testcontainers#3161)
  fix(etcd): expose ports for the etcd nodes (testcontainers#3162)
  fix(wait): no port to wait for (testcontainers#3158)
  feat: add more functional options for customising containers (testcontainers#3156)
  docs(redpanda): update sasl authentication option to use scram sha 256 (testcontainers#3126)
  chore(deps): bump mkdocs-include-markdown-plugin from 6.2.2 to 7.1.5 (testcontainers#3137)
  chore(deps): bump github.com/shirou/gopsutil/v4 from 4.25.1 to 4.25.4 (testcontainers#3133)
  chore(deps): bump github.com/docker/docker from 28.0.1+incompatible to 28.1.1+incompatible (testcontainers#3152)
  feat(memcached): add memcached module (testcontainers#3132)
  fix(etcd): single node etcd cluster access (testcontainers#3149)
  feat(valkey): add TLS support for Valkey (testcontainers#3131)
  ...
@mdelapenya mdelapenya requested a review from a team as a code owner June 3, 2025 12:21
@mdelapenya mdelapenya added the chore Changes that do not impact the existing functionality label Jun 3, 2025
@mdelapenya mdelapenya self-assigned this Jun 3, 2025
@mdelapenya mdelapenya requested a review from stevenh June 3, 2025 12:21
@netlify
Copy link

netlify bot commented Jun 3, 2025

Deploy Preview for testcontainers-go ready!

Name Link
🔨 Latest commit 092e175
🔍 Latest deploy log https://app.netlify.com/projects/testcontainers-go/deploys/691ee3ded7e71900083951af
😎 Deploy Preview https://deploy-preview-3200--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.

* main: (30 commits)
  fix: preserve unix socket schema in testcontainers host from properties (testcontainers#3213)
  feat(registry): add helper functions to pull and tag images (testcontainers#3275)
  fix(reaper): remove termSignal override (testcontainers#3261)
  chore(deps): bump ryuk to v0.13.0, which uses scratch as base image (testcontainers#3274)
  chore(release): refine release script to update inter-module dependencies (testcontainers#3273)
  fix(registry): update `WithHtpasswd` to use `os.CreateTemp` instead of `os.Create` with `filepath.Join`. (testcontainers#3272)
  chore(deps): bump github.com/docker/docker from 28.2.2+incompatible to 28.3.3+incompatible (testcontainers#3270)
  chore(postgres): use require.NotNil instead of assert.NotNil (testcontainers#3252)
  fix(nats): use wait for listening port instead of wait for log (testcontainers#3256)
  chore(deps): bump github.com/go-viper/mapstructure/v2 (testcontainers#3267)
  fix(postgres): snapshot restore (testcontainers#3264)
  fix(dockermcpgateway): use duckduckgo instead of brave (testcontainers#3247)
  feat: add Solace pubsub+ module (testcontainers#3230)
  feat(options): add WithProvider (testcontainers#3241)
  chore(deps): bump github/codeql-action from 3.29.2 to 3.29.3 (testcontainers#3237)
  chore(deps): bump golang.org/x/oauth2 in /modules/weaviate (testcontainers#3240)
  chore(deps): bump mkdocs-include-markdown-plugin from 7.1.5 to 7.1.6 (testcontainers#3239)
  chore(deps): bump requests from 2.32.0 to 2.32.4 (testcontainers#3204)
  feat(mcpgateway): add MCP gateway module (testcontainers#3232)
  chore(deps): bump golang.org/x/oauth2 in /modules/pulsar (testcontainers#3236)
  ...
@mdelapenya mdelapenya added bug An issue with the library and removed chore Changes that do not impact the existing functionality labels Sep 11, 2025
@mdelapenya mdelapenya changed the title chore: setup ExposeHostPorts forward on container start hook fix: setup ExposeHostPorts forward on container start hook Sep 11, 2025
@kberezin-nshl
Copy link

When is this going to be merged @mdelapenya @stevenh ?

@coderabbitai
Copy link

coderabbitai bot commented Nov 17, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Improved Solace module startup reliability with adjusted timeout parameters.
  • Tests

    • Enhanced port forwarding verification with comprehensive per-port testing.
  • Chores

    • Updated CI dependencies and optimized internal port forwarding initialization.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

SSH-based port forwarding is moved earlier: the tunnel is created in PreCreates via a ContainerRequestHook using req.HostAccessPorts before container creation. Tests add per-port wait verification. Solace module increases exec readiness timeout and adds 30s per-port startup timeouts.

Changes

Cohort / File(s) Summary
SSH tunnel lifecycle & hook signatures
port_forwarding.go
Moves SSH tunnel init from PostReadies: []ContainerHook to PreCreates: []ContainerRequestHook. Updates hook callback from func(ctx context.Context, _ Container) error to func(ctx context.Context, req ContainerRequest) error and calls sshdContainer.exposeHostPort(ctx, req.HostAccessPorts...) during PreCreates.
Per-port wait verification in tests
port_forwarding_test.go
Adds per-port validation: numberOfPorts, multiple httptest.Server instances, captures hostPorts, and constructs per-port wait.Strategy via wait.ForExec(...).WithExitCodeMatcher(...).WithResponseMatcher(...). Ensures per-port cleanup with t.Cleanup.
Solace readiness and port timeouts
modules/solace/solace.go
Extends exec-based readiness timeout from 1m to 2m and adds a 30s startup timeout for each service port's port-listening wait strategy.
CI action version bump
.github/workflows/ci-test-go.yml
Updates docker/setup-docker-action usage from a specific commit tag to v4.5.0 in workflow steps.

Sequence Diagram(s)

sequenceDiagram
    actor Test
    participant PreCreate as PreCreates hook
    participant SSH as SSH helper
    participant Container as Target container
    participant Host as Host service

    rect rgb(230,245,230)
      Note over PreCreate: New flow — tunnel created before container start
      Test->>PreCreate: execute PreCreates hooks (ContainerRequest)
      PreCreate->>SSH: exposeHostPort(req.HostAccessPorts...)
      SSH->>Host: establish remote forwarding
      PreCreate->>Container: create/start container (forwarding available)
      Container->>Host: startup health checks / waits use forwarded ports
    end

    rect rgb(245,230,230)
      Note over Container: Old flow — tunnel after readiness (shown for contrast)
      Test->>Container: create/start container
      Container->>Container: perform startup checks (no forwarding)
      Container->>SSH: PostReadies -> exposeHostPort(...) (runs later)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Attention points:
    • All call sites and consumers of ContainerLifecycleHooks for compatibility with PreCreates/ContainerRequestHook.
    • Ensure req.HostAccessPorts is valid before container creation and that exposeHostPort does not assume a running Container.
    • Test reliability around per-port httptest servers and exec-based wait strategies.
    • Solace timeout increases and per-port startup timeout implications.

Possibly related PRs

Suggested reviewers

  • stevenh

Poem

🐰 A tunnel sewn before the start,
Ports hum early, playing their part,
Servers wake and waits align,
Requests find hosts on time,
Hooray — the startup's snug and smart! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: setup ExposeHostPorts forward on container start hook' clearly summarizes the main change: moving the ExposeHostPorts forwarding to an earlier container lifecycle hook (PreCreates instead of PostReadies).
Description check ✅ Passed The description provides comprehensive context explaining the issue (issue #2811), the problem, the solution, testing instructions, and includes a detailed example reproducing the original issue.
Linked Issues check ✅ Passed The PR successfully addresses all objectives from issue #2811: forwarding is moved to PreCreates hook before container creation [#2811], allowing host ports to be accessible during startup and wait strategies [#2811], with updated hook signatures and types [#2811], and enhanced test coverage [#2811].
Out of Scope Changes check ✅ Passed Changes remain scoped to the linked issue: port_forwarding lifecycle hook timing/types updated, tests enhanced for port accessibility verification, Solace module timeout adjustments align with testing robustness, and CI workflow version bump is standard maintenance.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 327ed8e and 092e175.

📒 Files selected for processing (1)
  • .github/workflows/ci-test-go.yml (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: mdelapenya
Repo: testcontainers/testcontainers-go PR: 3319
File: modules/arangodb/arangodb.go:46-57
Timestamp: 2025-09-29T13:57:14.636Z
Learning: In testcontainers-go ArangoDB module, the wait strategy combines port listening check with HTTP readiness check using wait.ForAll - both strategies are required and complementary, not redundant.
🔇 Additional comments (1)
.github/workflows/ci-test-go.yml (1)

58-58: Dependency update follows project conventions.

The version bump to docker/[email protected] is properly pinned to a specific commit hash, maintaining consistency with other action references in the workflow (lines 63, 69, 92, 108, 113, 148).


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.

@mdelapenya
Copy link
Member Author

@kberezin-nshl my bad, this PR was piled in the list. Thanks for the ping 🙏

Copy link

@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.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec51c67 and 1f48580.

📒 Files selected for processing (2)
  • port_forwarding.go (1 hunks)
  • port_forwarding_test.go (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-29T13:57:14.636Z
Learnt from: mdelapenya
Repo: testcontainers/testcontainers-go PR: 3319
File: modules/arangodb/arangodb.go:46-57
Timestamp: 2025-09-29T13:57:14.636Z
Learning: In testcontainers-go ArangoDB module, the wait strategy combines port listening check with HTTP readiness check using wait.ForAll - both strategies are required and complementary, not redundant.

Applied to files:

  • port_forwarding_test.go
📚 Learning: 2025-09-29T15:08:18.694Z
Learnt from: mdelapenya
Repo: testcontainers/testcontainers-go PR: 3320
File: modules/artemis/artemis.go:98-103
Timestamp: 2025-09-29T15:08:18.694Z
Learning: In testcontainers-go, nat.Port is a type alias for string, so untyped string constants can be passed directly to functions expecting nat.Port (like wait.ForListeningPort) without explicit type conversion - the Go compiler handles the implicit conversion automatically.

Applied to files:

  • port_forwarding_test.go
🧬 Code graph analysis (2)
port_forwarding.go (2)
lifecycle.go (2)
  • ContainerLifecycleHooks (43-55)
  • ContainerRequestHook (24-24)
container.go (1)
  • ContainerRequest (131-171)
port_forwarding_test.go (3)
wait/wait.go (1)
  • Strategy (17-19)
wait/exec.go (1)
  • ForExec (72-74)
port_forwarding.go (1)
  • HostInternal (28-28)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: lint (modules/cassandra) / lint: modules/cassandra
  • GitHub Check: lint (modules/artemis) / lint: modules/artemis
  • GitHub Check: lint (modules/grafana-lgtm) / lint: modules/grafana-lgtm
  • GitHub Check: lint (modules/aerospike) / lint: modules/aerospike
  • GitHub Check: lint (modules/solace) / lint: modules/solace
  • GitHub Check: lint (modules/mockserver) / lint: modules/mockserver
  • GitHub Check: lint / lint:
  • GitHub Check: lint (modules/meilisearch) / lint: modules/meilisearch
  • GitHub Check: lint (modules/mongodb) / lint: modules/mongodb
  • GitHub Check: lint (modules/surrealdb) / lint: modules/surrealdb
  • GitHub Check: lint (modules/dynamodb) / lint: modules/dynamodb
  • GitHub Check: lint (modules/couchbase) / lint: modules/couchbase
  • GitHub Check: lint (modules/azurite) / lint: modules/azurite
  • GitHub Check: lint (modules/mssql) / lint: modules/mssql
  • GitHub Check: lint (modules/k3s) / lint: modules/k3s
  • GitHub Check: lint (modules/elasticsearch) / lint: modules/elasticsearch
  • GitHub Check: lint (modules/gcloud) / lint: modules/gcloud
  • GitHub Check: lint (modules/postgres) / lint: modules/postgres
  • GitHub Check: lint (modules/cockroachdb) / lint: modules/cockroachdb
  • GitHub Check: Analyze (go)
🔇 Additional comments (2)
port_forwarding.go (1)

163-173: LGTM! Lifecycle hook change correctly fixes the issue.

Moving SSH tunnel setup from PostReadies to PreCreates ensures host ports are accessible during container startup and wait strategies. The hook signature change from ContainerHook to ContainerRequestHook is correct, and req.HostAccessPorts is available at this lifecycle stage. Since SSH remote port forwarding (line 316) only establishes the listener and doesn't require an active host connection until traffic arrives, this earlier setup aligns with the PR objectives.

port_forwarding_test.go (1)

42-51: Wait strategies are never used—test doesn't verify the fix.

The wait strategies verify that host ports are accessible during container startup (the core behavior this PR fixes), but they are never applied to any container request. Without these wait strategies, the test cannot confirm that ports are reachable before the container becomes ready.

Add the wait strategies to the container request. For example, in testExposeHostPorts or pass them as a parameter and combine them with wait.ForAll:

func testExposeHostPorts(t *testing.T, hostPorts []int, waitStrats []wait.Strategy, hasNetwork, hasHostAccess bool) {
	// ... existing code ...
	
	opts := []testcontainers.ContainerCustomizer{
		testcontainers.WithHostPortAccess(hostAccessPorts...),
		testcontainers.WithCmd("top"),
	}
	
	if hasHostAccess && len(waitStrats) > 0 {
		opts = append(opts, testcontainers.WithWaitStrategy(wait.ForAll(waitStrats...)))
	}
	
	// ... rest of function
}

Then update the test calls to pass the wait strategies, e.g.:

testExposeHostPorts(t, singlePort, waitStrategies[0:1], false, false)
⛔ Skipped due to learnings
Learnt from: mdelapenya
Repo: testcontainers/testcontainers-go PR: 3319
File: modules/arangodb/arangodb.go:46-57
Timestamp: 2025-09-29T13:57:14.636Z
Learning: In testcontainers-go ArangoDB module, the wait strategy combines port listening check with HTTP readiness check using wait.ForAll - both strategies are required and complementary, not redundant.
Learnt from: mdelapenya
Repo: testcontainers/testcontainers-go PR: 3320
File: modules/artemis/artemis.go:98-103
Timestamp: 2025-09-29T15:08:18.694Z
Learning: In testcontainers-go, nat.Port is a type alias for string, so untyped string constants can be passed directly to functions expecting nat.Port (like wait.ForListeningPort) without explicit type conversion - the Go compiler handles the implicit conversion automatically.

* main:
  fix(kafka): strip architecture suffix from Kafka image tags for semver parsing (testcontainers#3276)
  chore(deps): bump github.com/dvsekhvalnov/jose2go in /modules/pulsar (testcontainers#3491)
Copy link

@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.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1f48580 and 5f56647.

📒 Files selected for processing (1)
  • port_forwarding_test.go (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-29T15:08:18.694Z
Learnt from: mdelapenya
Repo: testcontainers/testcontainers-go PR: 3320
File: modules/artemis/artemis.go:98-103
Timestamp: 2025-09-29T15:08:18.694Z
Learning: In testcontainers-go, nat.Port is a type alias for string, so untyped string constants can be passed directly to functions expecting nat.Port (like wait.ForListeningPort) without explicit type conversion - the Go compiler handles the implicit conversion automatically.

Applied to files:

  • port_forwarding_test.go
📚 Learning: 2025-09-29T13:57:14.636Z
Learnt from: mdelapenya
Repo: testcontainers/testcontainers-go PR: 3319
File: modules/arangodb/arangodb.go:46-57
Timestamp: 2025-09-29T13:57:14.636Z
Learning: In testcontainers-go ArangoDB module, the wait strategy combines port listening check with HTTP readiness check using wait.ForAll - both strategies are required and complementary, not redundant.

Applied to files:

  • port_forwarding_test.go
🧬 Code graph analysis (1)
port_forwarding_test.go (3)
wait/wait.go (1)
  • Strategy (17-19)
wait/exec.go (1)
  • ForExec (72-74)
port_forwarding.go (1)
  • HostInternal (28-28)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
  • GitHub Check: Redirect rules - testcontainers-go
  • GitHub Check: Header rules - testcontainers-go
  • GitHub Check: Pages changed - testcontainers-go
  • GitHub Check: lint (modules/registry) / lint: modules/registry
  • GitHub Check: lint (modules/meilisearch) / lint: modules/meilisearch
  • GitHub Check: lint (modules/dockermodelrunner) / lint: modules/dockermodelrunner
  • GitHub Check: lint (modules/azurite) / lint: modules/azurite
  • GitHub Check: lint (modules/dynamodb) / lint: modules/dynamodb
  • GitHub Check: lint (modules/qdrant) / lint: modules/qdrant
  • GitHub Check: lint (modules/mssql) / lint: modules/mssql
  • GitHub Check: lint (modules/nats) / lint: modules/nats
  • GitHub Check: lint (modules/mongodb) / lint: modules/mongodb
  • GitHub Check: lint (modules/postgres) / lint: modules/postgres
  • GitHub Check: Analyze (go)

Comment on lines +18 to +31
"github.com/testcontainers/testcontainers-go/wait"
)

const (
expectedResponse = "Hello, World!"
)

func TestExposeHostPorts(t *testing.T) {
hostPorts := make([]int, 3)
const numberOfPorts = 3

servers := make([]*httptest.Server, numberOfPorts)
hostPorts := make([]int, numberOfPorts)
waitStrategies := make([]wait.Strategy, numberOfPorts)

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

New waitStrategies are never used; clarify intent or remove to avoid dead code

The waitStrategies slice is fully populated with wait.ForExec(...).WithExitCodeMatcher(...).WithResponseMatcher(...), but it’s never read or passed into testExposeHostPorts / container options. As written, the new wait logic has no effect, and the tests still only validate host access via the explicit containerHasHostAccess / containerHasNoHostAccess calls after the container is started.

Similarly, the servers slice is only written to and never read, so it’s functionally redundant right now.

Depending on your intent:

  • If these strategies are meant to assert that host ports are reachable during container startup (per the PR description), you likely want to plumb them into the container’s waiting strategy (e.g., via a WaitingFor / wait customization) and possibly thread them into testExposeHostPorts.
  • If they’re not required, consider removing waitStrategies (and the wait import) and possibly the unused servers slice to keep the test simple and avoid confusion.

Also applies to: 37-49

🤖 Prompt for AI Agents
In port_forwarding_test.go around lines 18 to 31 (and similarly 37 to 49), the
slices waitStrategies and servers are built but never used; either wire them
into the container waiting logic or remove them — to fix quickly, delete the
wait import, the waitStrategies and servers declarations and all code that
populates them (including the per-port wait.ForExec(...) setup), and remove any
related unused variables so the test only keeps hostPorts and the actual
assertions; if you prefer to use them instead, pass the corresponding
wait.Strategy into the container creation (e.g., via
WaitingFor/WithStartupTimeout or by extending testExposeHostPorts to accept and
apply a per-port wait strategy) and ensure servers is read where its
httptest.Servers are needed.

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

Labels

bug An issue with the library

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Unable to connect to HostAccessPorts on container startup

3 participants