HTTP(S) Wait strategy¶
The HTTP wait strategy will check the result of an HTTP(S) request against the container and allows to set the following conditions:
- the port to be used. If no port is passed, it will use the lowest exposed port in the image.
- the path to be used.
- the HTTP method to be used.
- the HTTP request body to be sent.
- the HTTP status code matcher as a function.
- the HTTP response matcher as a function.
- the HTTP headers to be used.
- the HTTP response headers matcher as a function.
- the TLS config to be used for HTTPS.
- the startup timeout to be used in seconds, default is 60 seconds.
- the poll interval to be used in milliseconds, default is 100 milliseconds.
- the basic auth credentials to be used.
Info
It's important to notice that the HTTP wait strategy will default to the first port exported/published by the image.
Variations on the HTTP wait strategy are supported, including:
Match an HTTP method¶
ctx := context.Background()
c, err := testcontainers.Run(ctx, "nginx:latest",
testcontainers.WithExposedPorts("80/tcp"),
testcontainers.WithWaitStrategy(wait.ForHTTP("/").WithStartupTimeout(10*time.Second)),
)
defer func() {
if err := testcontainers.TerminateContainer(c); err != nil {
log.Printf("failed to terminate container: %s", err)
}
}()
if err != nil {
log.Printf("failed to start container: %s", err)
return
}
Match an HTTP method with Port¶
ctx := context.Background()
c, err := testcontainers.Run(ctx, "nginx:latest",
testcontainers.WithExposedPorts("8080/tcp", "80/tcp"),
testcontainers.WithWaitStrategy(wait.ForHTTP("/").WithPort("80/tcp")),
)
defer func() {
if err := testcontainers.TerminateContainer(c); err != nil {
log.Printf("failed to terminate container: %s", err)
}
}()
if err != nil {
log.Printf("failed to start container: %s", err)
return
}
Match an HTTP method with Basic Auth¶
ctx := context.Background()
gogs, err := testcontainers.Run(ctx, "gogs/gogs:0.11.91",
testcontainers.WithExposedPorts("3000/tcp"),
testcontainers.WithWaitStrategy(wait.ForHTTP("/").WithBasicAuth("username", "password")),
)
defer func() {
if err := testcontainers.TerminateContainer(gogs); err != nil {
log.Printf("failed to terminate container: %s", err)
}
}()
if err != nil {
log.Printf("failed to start container: %s", err)
return
}
Match an HTTPS status code and a response matcher¶
tlsconfig := &tls.Config{RootCAs: certpool, ServerName: "testcontainer.go.test"}
var i int
ctx := context.Background()
ctr, err := testcontainers.Run(context.Background(), "",
testcontainers.WithDockerfile(testcontainers.FromDockerfile{
Context: "testdata/http",
}),
testcontainers.WithExposedPorts("6443/tcp"),
testcontainers.WithWaitStrategy(wait.NewHTTPStrategy("/ping").WithTLS(true, tlsconfig).
WithStartupTimeout(time.Second*10).
WithResponseMatcher(func(body io.Reader) bool {
data, _ := io.ReadAll(body)
return bytes.Equal(data, []byte("pong"))
}).
WithStatusCodeMatcher(func(status int) bool {
i++ // always fail the first try in order to force the polling loop to be re-run
return i > 1 && status == 200
}).
WithMethod(http.MethodPost).WithBody(bytes.NewReader([]byte("ping"))),
),
)
Match for HTTP response headers¶
tlsconfig := &tls.Config{RootCAs: certpool, ServerName: "testcontainer.go.test"}
c, err := testcontainers.Run(ctx, "",
testcontainers.WithDockerfile(testcontainers.FromDockerfile{
Context: "testdata/http",
}),
testcontainers.WithExposedPorts("6443/tcp"),
testcontainers.WithWaitStrategy(wait.ForHTTP("/headers").
WithTLS(true, tlsconfig).
WithPort("6443/tcp").
WithHeaders(map[string]string{"X-request-header": "value"}).
WithResponseHeadersMatcher(func(headers http.Header) bool {
return headers.Get("X-response-header") == "value"
}),
),
)