diff --git a/port_forwarding.go b/port_forwarding.go index 107bd42d1b..bdfa7a9176 100644 --- a/port_forwarding.go +++ b/port_forwarding.go @@ -159,11 +159,11 @@ func exposeHostPorts(ctx context.Context, req *ContainerRequest, ports ...int) ( }, } - // after the container is ready, create the SSH tunnel + // before the container is created, create the SSH tunnel // for each exposed port from the host. sshdConnectHook = ContainerLifecycleHooks{ - PostReadies: []ContainerHook{ - func(ctx context.Context, _ Container) error { + PreCreates: []ContainerRequestHook{ + func(ctx context.Context, req ContainerRequest) error { return sshdContainer.exposeHostPort(ctx, req.HostAccessPorts...) }, }, diff --git a/port_forwarding_test.go b/port_forwarding_test.go index 662bc64119..5a87576207 100644 --- a/port_forwarding_test.go +++ b/port_forwarding_test.go @@ -15,6 +15,7 @@ import ( "github.com/testcontainers/testcontainers-go" tcexec "github.com/testcontainers/testcontainers-go/exec" "github.com/testcontainers/testcontainers-go/network" + "github.com/testcontainers/testcontainers-go/wait" ) const ( @@ -22,12 +23,33 @@ const ( ) 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) + for i := range hostPorts { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { fmt.Fprint(w, expectedResponse) })) hostPorts[i] = server.Listener.Addr().(*net.TCPAddr).Port + + servers[i] = server + freePort := server.Listener.Addr().(*net.TCPAddr).Port + hostPorts[i] = freePort + + waitStrategies[i] = wait. + ForExec([]string{"wget", "-q", "-O", "-", fmt.Sprintf("http://%s:%d", testcontainers.HostInternal, freePort)}). + WithExitCodeMatcher(func(code int) bool { + return code == 0 + }). + WithResponseMatcher(func(body io.Reader) bool { + bs, err := io.ReadAll(body) + require.NoError(t, err) + return string(bs) == expectedResponse + }) + t.Cleanup(server.Close) }