diff --git a/generic_test.go b/generic_test.go index 77faa919c26..ca4e8a9ee98 100644 --- a/generic_test.go +++ b/generic_test.go @@ -3,6 +3,12 @@ package testcontainers import ( "context" "errors" + "fmt" + "net/http" + "os" + "os/exec" + "regexp" + "sync" "testing" "github.com/stretchr/testify/require" @@ -96,3 +102,77 @@ func TestGenericReusableContainer(t *testing.T) { }) } } + +func TestGenericReusableContainerInSubprocess(t *testing.T) { + containerIDOnce := sync.Once{} + containerID := "" + + wg := sync.WaitGroup{} + wg.Add(10) + for i := 0; i < 10; i++ { + go func() { + defer wg.Done() + + // create containers in subprocesses, as "go test ./..." does. + output := createReuseContainerInSubprocess(t) + + // check is container reused. + re := regexp.MustCompile(fmt.Sprintf("%s(.*)%s", + "🚧 Waiting for container id ", + regexp.QuoteMeta(fmt.Sprintf(" image: %s", nginxDelayedImage)), + )) + match := re.FindStringSubmatch(output) + + containerIDOnce.Do(func() { + containerID = match[1] + }) + require.Equal(t, containerID, match[1]) + }() + } + + wg.Wait() +} + +func createReuseContainerInSubprocess(t *testing.T) string { + cmd := exec.Command(os.Args[0], "-test.run=TestHelperContainerStarterProcess") + cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"} + + output, err := cmd.CombinedOutput() + require.NoError(t, err, string(output)) + + return string(output) +} + +func TestHelperContainerStarterProcess(t *testing.T) { + if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" { + return + } + + ctx := context.Background() + + nginxC, err := GenericContainer(ctx, GenericContainerRequest{ + ProviderType: providerType, + ContainerRequest: ContainerRequest{ + Image: nginxDelayedImage, + ExposedPorts: []string{nginxDefaultPort}, + WaitingFor: wait.ForListeningPort(nginxDefaultPort), // default startupTimeout is 60s + Name: reusableContainerName, + }, + Started: true, + Reuse: true, + }) + require.NoError(t, err) + require.True(t, nginxC.IsRunning()) + + origin, err := nginxC.PortEndpoint(ctx, nginxDefaultPort, "http") + require.NoError(t, err) + + // check is reuse container with WaitingFor work correctly. + resp, err := http.Get(origin) + require.NoError(t, err) + defer resp.Body.Close() + + require.Equal(t, http.StatusOK, resp.StatusCode) + + os.Exit(0) +}