build: upgrade dependencies and build with go 1.21
This commit is contained in:
80
vendor/github.com/testcontainers/testcontainers-go/wait/all.go
generated
vendored
Normal file
80
vendor/github.com/testcontainers/testcontainers-go/wait/all.go
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Implement interface
|
||||
var _ Strategy = (*MultiStrategy)(nil)
|
||||
var _ StrategyTimeout = (*MultiStrategy)(nil)
|
||||
|
||||
type MultiStrategy struct {
|
||||
// all Strategies should have a startupTimeout to avoid waiting infinitely
|
||||
timeout *time.Duration
|
||||
deadline *time.Duration
|
||||
|
||||
// additional properties
|
||||
Strategies []Strategy
|
||||
}
|
||||
|
||||
// WithStartupTimeoutDefault sets the default timeout for all inner wait strategies
|
||||
func (ms *MultiStrategy) WithStartupTimeoutDefault(timeout time.Duration) *MultiStrategy {
|
||||
ms.timeout = &timeout
|
||||
return ms
|
||||
}
|
||||
|
||||
// WithStartupTimeout sets a time.Duration which limits all wait strategies
|
||||
//
|
||||
// Deprecated: use WithDeadline
|
||||
func (ms *MultiStrategy) WithStartupTimeout(timeout time.Duration) Strategy {
|
||||
return ms.WithDeadline(timeout)
|
||||
}
|
||||
|
||||
// WithDeadline sets a time.Duration which limits all wait strategies
|
||||
func (ms *MultiStrategy) WithDeadline(deadline time.Duration) *MultiStrategy {
|
||||
ms.deadline = &deadline
|
||||
return ms
|
||||
}
|
||||
|
||||
func ForAll(strategies ...Strategy) *MultiStrategy {
|
||||
return &MultiStrategy{
|
||||
Strategies: strategies,
|
||||
}
|
||||
}
|
||||
|
||||
func (ms *MultiStrategy) Timeout() *time.Duration {
|
||||
return ms.timeout
|
||||
}
|
||||
|
||||
func (ms *MultiStrategy) WaitUntilReady(ctx context.Context, target StrategyTarget) error {
|
||||
var cancel context.CancelFunc
|
||||
if ms.deadline != nil {
|
||||
ctx, cancel = context.WithTimeout(ctx, *ms.deadline)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
if len(ms.Strategies) == 0 {
|
||||
return fmt.Errorf("no wait strategy supplied")
|
||||
}
|
||||
|
||||
for _, strategy := range ms.Strategies {
|
||||
strategyCtx := ctx
|
||||
|
||||
// Set default Timeout when strategy implements StrategyTimeout
|
||||
if st, ok := strategy.(StrategyTimeout); ok {
|
||||
if ms.Timeout() != nil && st.Timeout() == nil {
|
||||
strategyCtx, cancel = context.WithTimeout(ctx, *ms.Timeout())
|
||||
defer cancel()
|
||||
}
|
||||
}
|
||||
|
||||
err := strategy.WaitUntilReady(strategyCtx, target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
1
vendor/github.com/testcontainers/testcontainers-go/wait/errors.go
generated
vendored
1
vendor/github.com/testcontainers/testcontainers-go/wait/errors.go
generated
vendored
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package wait
|
||||
|
99
vendor/github.com/testcontainers/testcontainers-go/wait/exec.go
generated
vendored
Normal file
99
vendor/github.com/testcontainers/testcontainers-go/wait/exec.go
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
tcexec "github.com/testcontainers/testcontainers-go/exec"
|
||||
)
|
||||
|
||||
// Implement interface
|
||||
var _ Strategy = (*ExecStrategy)(nil)
|
||||
var _ StrategyTimeout = (*ExecStrategy)(nil)
|
||||
|
||||
type ExecStrategy struct {
|
||||
// all Strategies should have a startupTimeout to avoid waiting infinitely
|
||||
timeout *time.Duration
|
||||
cmd []string
|
||||
|
||||
// additional properties
|
||||
ExitCodeMatcher func(exitCode int) bool
|
||||
ResponseMatcher func(body io.Reader) bool
|
||||
PollInterval time.Duration
|
||||
}
|
||||
|
||||
// NewExecStrategy constructs an Exec strategy ...
|
||||
func NewExecStrategy(cmd []string) *ExecStrategy {
|
||||
return &ExecStrategy{
|
||||
cmd: cmd,
|
||||
ExitCodeMatcher: defaultExitCodeMatcher,
|
||||
ResponseMatcher: func(body io.Reader) bool { return true },
|
||||
PollInterval: defaultPollInterval(),
|
||||
}
|
||||
}
|
||||
|
||||
func defaultExitCodeMatcher(exitCode int) bool {
|
||||
return exitCode == 0
|
||||
}
|
||||
|
||||
// WithStartupTimeout can be used to change the default startup timeout
|
||||
func (ws *ExecStrategy) WithStartupTimeout(startupTimeout time.Duration) *ExecStrategy {
|
||||
ws.timeout = &startupTimeout
|
||||
return ws
|
||||
}
|
||||
|
||||
func (ws *ExecStrategy) WithExitCodeMatcher(exitCodeMatcher func(exitCode int) bool) *ExecStrategy {
|
||||
ws.ExitCodeMatcher = exitCodeMatcher
|
||||
return ws
|
||||
}
|
||||
|
||||
func (ws *ExecStrategy) WithResponseMatcher(matcher func(body io.Reader) bool) *ExecStrategy {
|
||||
ws.ResponseMatcher = matcher
|
||||
return ws
|
||||
}
|
||||
|
||||
// WithPollInterval can be used to override the default polling interval of 100 milliseconds
|
||||
func (ws *ExecStrategy) WithPollInterval(pollInterval time.Duration) *ExecStrategy {
|
||||
ws.PollInterval = pollInterval
|
||||
return ws
|
||||
}
|
||||
|
||||
// ForExec is a convenience method to assign ExecStrategy
|
||||
func ForExec(cmd []string) *ExecStrategy {
|
||||
return NewExecStrategy(cmd)
|
||||
}
|
||||
|
||||
func (ws *ExecStrategy) Timeout() *time.Duration {
|
||||
return ws.timeout
|
||||
}
|
||||
|
||||
func (ws *ExecStrategy) WaitUntilReady(ctx context.Context, target StrategyTarget) error {
|
||||
timeout := defaultStartupTimeout()
|
||||
if ws.timeout != nil {
|
||||
timeout = *ws.timeout
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-time.After(ws.PollInterval):
|
||||
exitCode, resp, err := target.Exec(ctx, ws.cmd, tcexec.Multiplexed())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !ws.ExitCodeMatcher(exitCode) {
|
||||
continue
|
||||
}
|
||||
if ws.ResponseMatcher != nil && !ws.ResponseMatcher(resp) {
|
||||
continue
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
89
vendor/github.com/testcontainers/testcontainers-go/wait/exit.go
generated
vendored
Normal file
89
vendor/github.com/testcontainers/testcontainers-go/wait/exit.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Implement interface
|
||||
var _ Strategy = (*ExitStrategy)(nil)
|
||||
var _ StrategyTimeout = (*ExitStrategy)(nil)
|
||||
|
||||
// ExitStrategy will wait until container exit
|
||||
type ExitStrategy struct {
|
||||
// all Strategies should have a timeout to avoid waiting infinitely
|
||||
timeout *time.Duration
|
||||
|
||||
// additional properties
|
||||
PollInterval time.Duration
|
||||
}
|
||||
|
||||
// NewExitStrategy constructs with polling interval of 100 milliseconds without timeout by default
|
||||
func NewExitStrategy() *ExitStrategy {
|
||||
return &ExitStrategy{
|
||||
PollInterval: defaultPollInterval(),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// fluent builders for each property
|
||||
// since go has neither covariance nor generics, the return type must be the type of the concrete implementation
|
||||
// this is true for all properties, even the "shared" ones
|
||||
|
||||
// WithExitTimeout can be used to change the default exit timeout
|
||||
func (ws *ExitStrategy) WithExitTimeout(exitTimeout time.Duration) *ExitStrategy {
|
||||
ws.timeout = &exitTimeout
|
||||
return ws
|
||||
}
|
||||
|
||||
// WithPollInterval can be used to override the default polling interval of 100 milliseconds
|
||||
func (ws *ExitStrategy) WithPollInterval(pollInterval time.Duration) *ExitStrategy {
|
||||
ws.PollInterval = pollInterval
|
||||
return ws
|
||||
}
|
||||
|
||||
// ForExit is the default construction for the fluid interface.
|
||||
//
|
||||
// For Example:
|
||||
//
|
||||
// wait.
|
||||
// ForExit().
|
||||
// WithPollInterval(1 * time.Second)
|
||||
func ForExit() *ExitStrategy {
|
||||
return NewExitStrategy()
|
||||
}
|
||||
|
||||
func (ws *ExitStrategy) Timeout() *time.Duration {
|
||||
return ws.timeout
|
||||
}
|
||||
|
||||
// WaitUntilReady implements Strategy.WaitUntilReady
|
||||
func (ws *ExitStrategy) WaitUntilReady(ctx context.Context, target StrategyTarget) (err error) {
|
||||
if ws.timeout != nil {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithTimeout(ctx, *ws.timeout)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
state, err := target.State(ctx)
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), "No such container") {
|
||||
return err
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if state.Running {
|
||||
time.Sleep(ws.PollInterval)
|
||||
continue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
91
vendor/github.com/testcontainers/testcontainers-go/wait/health.go
generated
vendored
Normal file
91
vendor/github.com/testcontainers/testcontainers-go/wait/health.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
)
|
||||
|
||||
// Implement interface
|
||||
var _ Strategy = (*HealthStrategy)(nil)
|
||||
var _ StrategyTimeout = (*HealthStrategy)(nil)
|
||||
|
||||
// HealthStrategy will wait until the container becomes healthy
|
||||
type HealthStrategy struct {
|
||||
// all Strategies should have a startupTimeout to avoid waiting infinitely
|
||||
timeout *time.Duration
|
||||
|
||||
// additional properties
|
||||
PollInterval time.Duration
|
||||
}
|
||||
|
||||
// NewHealthStrategy constructs with polling interval of 100 milliseconds and startup timeout of 60 seconds by default
|
||||
func NewHealthStrategy() *HealthStrategy {
|
||||
return &HealthStrategy{
|
||||
PollInterval: defaultPollInterval(),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// fluent builders for each property
|
||||
// since go has neither covariance nor generics, the return type must be the type of the concrete implementation
|
||||
// this is true for all properties, even the "shared" ones like startupTimeout
|
||||
|
||||
// WithStartupTimeout can be used to change the default startup timeout
|
||||
func (ws *HealthStrategy) WithStartupTimeout(startupTimeout time.Duration) *HealthStrategy {
|
||||
ws.timeout = &startupTimeout
|
||||
return ws
|
||||
}
|
||||
|
||||
// WithPollInterval can be used to override the default polling interval of 100 milliseconds
|
||||
func (ws *HealthStrategy) WithPollInterval(pollInterval time.Duration) *HealthStrategy {
|
||||
ws.PollInterval = pollInterval
|
||||
return ws
|
||||
}
|
||||
|
||||
// ForHealthCheck is the default construction for the fluid interface.
|
||||
//
|
||||
// For Example:
|
||||
//
|
||||
// wait.
|
||||
// ForHealthCheck().
|
||||
// WithPollInterval(1 * time.Second)
|
||||
func ForHealthCheck() *HealthStrategy {
|
||||
return NewHealthStrategy()
|
||||
}
|
||||
|
||||
func (ws *HealthStrategy) Timeout() *time.Duration {
|
||||
return ws.timeout
|
||||
}
|
||||
|
||||
// WaitUntilReady implements Strategy.WaitUntilReady
|
||||
func (ws *HealthStrategy) WaitUntilReady(ctx context.Context, target StrategyTarget) (err error) {
|
||||
timeout := defaultStartupTimeout()
|
||||
if ws.timeout != nil {
|
||||
timeout = *ws.timeout
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
state, err := target.State(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := checkState(state); err != nil {
|
||||
return err
|
||||
}
|
||||
if state.Health == nil || state.Health.Status != types.Healthy {
|
||||
time.Sleep(ws.PollInterval)
|
||||
continue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
126
vendor/github.com/testcontainers/testcontainers-go/wait/host_port.go
generated
vendored
126
vendor/github.com/testcontainers/testcontainers-go/wait/host_port.go
generated
vendored
@@ -2,31 +2,37 @@ package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/docker/go-connections/nat"
|
||||
)
|
||||
|
||||
// Implement interface
|
||||
var _ Strategy = (*HostPortStrategy)(nil)
|
||||
var _ StrategyTimeout = (*HostPortStrategy)(nil)
|
||||
|
||||
var errShellNotExecutable = errors.New("/bin/sh command not executable")
|
||||
|
||||
type HostPortStrategy struct {
|
||||
// Port is a string containing port number and protocol in the format "80/tcp"
|
||||
// which
|
||||
Port nat.Port
|
||||
// all WaitStrategies should have a startupTimeout to avoid waiting infinitely
|
||||
startupTimeout time.Duration
|
||||
timeout *time.Duration
|
||||
PollInterval time.Duration
|
||||
}
|
||||
|
||||
// NewHostPortStrategy constructs a default host port strategy
|
||||
func NewHostPortStrategy(port nat.Port) *HostPortStrategy {
|
||||
return &HostPortStrategy{
|
||||
Port: port,
|
||||
startupTimeout: defaultStartupTimeout(),
|
||||
Port: port,
|
||||
PollInterval: defaultPollInterval(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,70 +46,150 @@ func ForListeningPort(port nat.Port) *HostPortStrategy {
|
||||
return NewHostPortStrategy(port)
|
||||
}
|
||||
|
||||
// ForExposedPort constructs an exposed port strategy. Alias for `NewHostPortStrategy("")`.
|
||||
// This strategy waits for the first port exposed in the Docker container.
|
||||
func ForExposedPort() *HostPortStrategy {
|
||||
return NewHostPortStrategy("")
|
||||
}
|
||||
|
||||
// WithStartupTimeout can be used to change the default startup timeout
|
||||
func (hp *HostPortStrategy) WithStartupTimeout(startupTimeout time.Duration) *HostPortStrategy {
|
||||
hp.startupTimeout = startupTimeout
|
||||
hp.timeout = &startupTimeout
|
||||
return hp
|
||||
}
|
||||
|
||||
// WithPollInterval can be used to override the default polling interval of 100 milliseconds
|
||||
func (hp *HostPortStrategy) WithPollInterval(pollInterval time.Duration) *HostPortStrategy {
|
||||
hp.PollInterval = pollInterval
|
||||
return hp
|
||||
}
|
||||
|
||||
func (hp *HostPortStrategy) Timeout() *time.Duration {
|
||||
return hp.timeout
|
||||
}
|
||||
|
||||
// WaitUntilReady implements Strategy.WaitUntilReady
|
||||
func (hp *HostPortStrategy) WaitUntilReady(ctx context.Context, target StrategyTarget) (err error) {
|
||||
// limit context to startupTimeout
|
||||
ctx, cancelContext := context.WithTimeout(ctx, hp.startupTimeout)
|
||||
defer cancelContext()
|
||||
timeout := defaultStartupTimeout()
|
||||
if hp.timeout != nil {
|
||||
timeout = *hp.timeout
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
ipAddress, err := target.Host(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
port, err := target.MappedPort(ctx, hp.Port)
|
||||
if err != nil {
|
||||
var waitInterval = hp.PollInterval
|
||||
|
||||
internalPort := hp.Port
|
||||
if internalPort == "" {
|
||||
var ports nat.PortMap
|
||||
ports, err = target.Ports(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(ports) > 0 {
|
||||
for p := range ports {
|
||||
internalPort = p
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if internalPort == "" {
|
||||
err = fmt.Errorf("no port to wait for")
|
||||
return
|
||||
}
|
||||
|
||||
var port nat.Port
|
||||
port, err = target.MappedPort(ctx, internalPort)
|
||||
var i = 0
|
||||
|
||||
for port == "" {
|
||||
i++
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("%s:%w", ctx.Err(), err)
|
||||
case <-time.After(waitInterval):
|
||||
if err := checkTarget(ctx, target); err != nil {
|
||||
return err
|
||||
}
|
||||
port, err = target.MappedPort(ctx, internalPort)
|
||||
if err != nil {
|
||||
fmt.Printf("(%d) [%s] %s\n", i, port, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := externalCheck(ctx, ipAddress, port, target, waitInterval); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = internalCheck(ctx, internalPort, target)
|
||||
if err != nil && errors.Is(errShellNotExecutable, err) {
|
||||
log.Println("Shell not executable in container, only external port check will be performed")
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func externalCheck(ctx context.Context, ipAddress string, port nat.Port, target StrategyTarget, waitInterval time.Duration) error {
|
||||
proto := port.Proto()
|
||||
portNumber := port.Int()
|
||||
portString := strconv.Itoa(portNumber)
|
||||
|
||||
//external check
|
||||
dialer := net.Dialer{}
|
||||
address := net.JoinHostPort(ipAddress, portString)
|
||||
for {
|
||||
if err := checkTarget(ctx, target); err != nil {
|
||||
return err
|
||||
}
|
||||
conn, err := dialer.DialContext(ctx, proto, address)
|
||||
if err != nil {
|
||||
if v, ok := err.(*net.OpError); ok {
|
||||
if v2, ok := (v.Err).(*os.SyscallError); ok {
|
||||
if isConnRefusedErr(v2.Err) {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
time.Sleep(waitInterval)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
} else {
|
||||
conn.Close()
|
||||
_ = conn.Close()
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//internal check
|
||||
command := buildInternalCheckCommand(hp.Port.Int())
|
||||
func internalCheck(ctx context.Context, internalPort nat.Port, target StrategyTarget) error {
|
||||
command := buildInternalCheckCommand(internalPort.Int())
|
||||
for {
|
||||
if ctx.Err() != nil {
|
||||
return ctx.Err()
|
||||
}
|
||||
exitCode, err := target.Exec(ctx, []string{"/bin/sh", "-c", command})
|
||||
if err := checkTarget(ctx, target); err != nil {
|
||||
return err
|
||||
}
|
||||
exitCode, _, err := target.Exec(ctx, []string{"/bin/sh", "-c", command})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "host port waiting failed")
|
||||
return fmt.Errorf("%w, host port waiting failed", err)
|
||||
}
|
||||
|
||||
if exitCode == 0 {
|
||||
break
|
||||
} else if exitCode == 126 {
|
||||
return errors.New("/bin/sh command not executable")
|
||||
return errShellNotExecutable
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
114
vendor/github.com/testcontainers/testcontainers-go/wait/http.go
generated
vendored
114
vendor/github.com/testcontainers/testcontainers-go/wait/http.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package wait
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
@@ -8,6 +9,7 @@ import (
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -16,10 +18,11 @@ import (
|
||||
|
||||
// Implement interface
|
||||
var _ Strategy = (*HTTPStrategy)(nil)
|
||||
var _ StrategyTimeout = (*HTTPStrategy)(nil)
|
||||
|
||||
type HTTPStrategy struct {
|
||||
// all Strategies should have a startupTimeout to avoid waiting infinitely
|
||||
startupTimeout time.Duration
|
||||
timeout *time.Duration
|
||||
|
||||
// additional properties
|
||||
Port nat.Port
|
||||
@@ -32,13 +35,13 @@ type HTTPStrategy struct {
|
||||
Method string // http method
|
||||
Body io.Reader // http request body
|
||||
PollInterval time.Duration
|
||||
UserInfo *url.Userinfo
|
||||
}
|
||||
|
||||
// NewHTTPStrategy constructs a HTTP strategy waiting on port 80 and status code 200
|
||||
func NewHTTPStrategy(path string) *HTTPStrategy {
|
||||
return &HTTPStrategy{
|
||||
startupTimeout: defaultStartupTimeout(),
|
||||
Port: "80/tcp",
|
||||
Port: "",
|
||||
Path: path,
|
||||
StatusCodeMatcher: defaultStatusCodeMatcher,
|
||||
ResponseMatcher: func(body io.Reader) bool { return true },
|
||||
@@ -47,6 +50,7 @@ func NewHTTPStrategy(path string) *HTTPStrategy {
|
||||
Method: http.MethodGet,
|
||||
Body: nil,
|
||||
PollInterval: defaultPollInterval(),
|
||||
UserInfo: nil,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,8 +62,9 @@ func defaultStatusCodeMatcher(status int) bool {
|
||||
// since go has neither covariance nor generics, the return type must be the type of the concrete implementation
|
||||
// this is true for all properties, even the "shared" ones like startupTimeout
|
||||
|
||||
func (ws *HTTPStrategy) WithStartupTimeout(startupTimeout time.Duration) *HTTPStrategy {
|
||||
ws.startupTimeout = startupTimeout
|
||||
// WithStartupTimeout can be used to change the default startup timeout
|
||||
func (ws *HTTPStrategy) WithStartupTimeout(timeout time.Duration) *HTTPStrategy {
|
||||
ws.timeout = &timeout
|
||||
return ws
|
||||
}
|
||||
|
||||
@@ -101,6 +106,11 @@ func (ws *HTTPStrategy) WithBody(reqdata io.Reader) *HTTPStrategy {
|
||||
return ws
|
||||
}
|
||||
|
||||
func (ws *HTTPStrategy) WithBasicAuth(username, password string) *HTTPStrategy {
|
||||
ws.UserInfo = url.UserPassword(username, password)
|
||||
return ws
|
||||
}
|
||||
|
||||
// WithPollInterval can be used to override the default polling interval of 100 milliseconds
|
||||
func (ws *HTTPStrategy) WithPollInterval(pollInterval time.Duration) *HTTPStrategy {
|
||||
ws.PollInterval = pollInterval
|
||||
@@ -113,24 +123,71 @@ func ForHTTP(path string) *HTTPStrategy {
|
||||
return NewHTTPStrategy(path)
|
||||
}
|
||||
|
||||
func (ws *HTTPStrategy) Timeout() *time.Duration {
|
||||
return ws.timeout
|
||||
}
|
||||
|
||||
// WaitUntilReady implements Strategy.WaitUntilReady
|
||||
func (ws *HTTPStrategy) WaitUntilReady(ctx context.Context, target StrategyTarget) (err error) {
|
||||
// limit context to startupTimeout
|
||||
ctx, cancelContext := context.WithTimeout(ctx, ws.startupTimeout)
|
||||
defer cancelContext()
|
||||
timeout := defaultStartupTimeout()
|
||||
if ws.timeout != nil {
|
||||
timeout = *ws.timeout
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
ipAddress, err := target.Host(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
port, err := target.MappedPort(ctx, ws.Port)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var mappedPort nat.Port
|
||||
if ws.Port == "" {
|
||||
ports, err := target.Ports(ctx)
|
||||
for err != nil {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("%s:%w", ctx.Err(), err)
|
||||
case <-time.After(ws.PollInterval):
|
||||
if err := checkTarget(ctx, target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if port.Proto() != "tcp" {
|
||||
return errors.New("Cannot use HTTP client on non-TCP ports")
|
||||
ports, err = target.Ports(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
for k, bindings := range ports {
|
||||
if len(bindings) == 0 || k.Proto() != "tcp" {
|
||||
continue
|
||||
}
|
||||
mappedPort, _ = nat.NewPort(k.Proto(), bindings[0].HostPort)
|
||||
break
|
||||
}
|
||||
|
||||
if mappedPort == "" {
|
||||
return errors.New("No exposed tcp ports or mapped ports - cannot wait for status")
|
||||
}
|
||||
} else {
|
||||
mappedPort, err = target.MappedPort(ctx, ws.Port)
|
||||
|
||||
for mappedPort == "" {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("%s:%w", ctx.Err(), err)
|
||||
case <-time.After(ws.PollInterval):
|
||||
if err := checkTarget(ctx, target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mappedPort, err = target.MappedPort(ctx, ws.Port)
|
||||
}
|
||||
}
|
||||
|
||||
if mappedPort.Proto() != "tcp" {
|
||||
return errors.New("Cannot use HTTP client on non-TCP ports")
|
||||
}
|
||||
}
|
||||
|
||||
switch ws.Method {
|
||||
@@ -174,15 +231,36 @@ func (ws *HTTPStrategy) WaitUntilReady(ctx context.Context, target StrategyTarge
|
||||
}
|
||||
|
||||
client := http.Client{Transport: tripper, Timeout: time.Second}
|
||||
address := net.JoinHostPort(ipAddress, strconv.Itoa(port.Int()))
|
||||
endpoint := fmt.Sprintf("%s://%s%s", proto, address, ws.Path)
|
||||
address := net.JoinHostPort(ipAddress, strconv.Itoa(mappedPort.Int()))
|
||||
|
||||
endpoint := url.URL{
|
||||
Scheme: proto,
|
||||
Host: address,
|
||||
Path: ws.Path,
|
||||
}
|
||||
|
||||
if ws.UserInfo != nil {
|
||||
endpoint.User = ws.UserInfo
|
||||
}
|
||||
|
||||
// cache the body into a byte-slice so that it can be iterated over multiple times
|
||||
var body []byte
|
||||
if ws.Body != nil {
|
||||
body, err = io.ReadAll(ws.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-time.After(ws.PollInterval):
|
||||
req, err := http.NewRequestWithContext(ctx, ws.Method, endpoint, ws.Body)
|
||||
if err := checkTarget(ctx, target); err != nil {
|
||||
return err
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, ws.Method, endpoint.String(), bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -191,9 +269,11 @@ func (ws *HTTPStrategy) WaitUntilReady(ctx context.Context, target StrategyTarge
|
||||
continue
|
||||
}
|
||||
if ws.StatusCodeMatcher != nil && !ws.StatusCodeMatcher(resp.StatusCode) {
|
||||
_ = resp.Body.Close()
|
||||
continue
|
||||
}
|
||||
if ws.ResponseMatcher != nil && !ws.ResponseMatcher(resp.Body) {
|
||||
_ = resp.Body.Close()
|
||||
continue
|
||||
}
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
|
66
vendor/github.com/testcontainers/testcontainers-go/wait/log.go
generated
vendored
66
vendor/github.com/testcontainers/testcontainers-go/wait/log.go
generated
vendored
@@ -2,18 +2,19 @@ package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Implement interface
|
||||
var _ Strategy = (*LogStrategy)(nil)
|
||||
var _ StrategyTimeout = (*LogStrategy)(nil)
|
||||
|
||||
// LogStrategy will wait until a given log entry shows up in the docker logs
|
||||
type LogStrategy struct {
|
||||
// all Strategies should have a startupTimeout to avoid waiting infinitely
|
||||
startupTimeout time.Duration
|
||||
timeout *time.Duration
|
||||
|
||||
// additional properties
|
||||
Log string
|
||||
@@ -21,15 +22,13 @@ type LogStrategy struct {
|
||||
PollInterval time.Duration
|
||||
}
|
||||
|
||||
// NewLogStrategy constructs a HTTP strategy waiting on port 80 and status code 200
|
||||
// NewLogStrategy constructs with polling interval of 100 milliseconds and startup timeout of 60 seconds by default
|
||||
func NewLogStrategy(log string) *LogStrategy {
|
||||
return &LogStrategy{
|
||||
startupTimeout: defaultStartupTimeout(),
|
||||
Log: log,
|
||||
Occurrence: 1,
|
||||
PollInterval: defaultPollInterval(),
|
||||
Log: log,
|
||||
Occurrence: 1,
|
||||
PollInterval: defaultPollInterval(),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// fluent builders for each property
|
||||
@@ -37,8 +36,8 @@ func NewLogStrategy(log string) *LogStrategy {
|
||||
// this is true for all properties, even the "shared" ones like startupTimeout
|
||||
|
||||
// WithStartupTimeout can be used to change the default startup timeout
|
||||
func (ws *LogStrategy) WithStartupTimeout(startupTimeout time.Duration) *LogStrategy {
|
||||
ws.startupTimeout = startupTimeout
|
||||
func (ws *LogStrategy) WithStartupTimeout(timeout time.Duration) *LogStrategy {
|
||||
ws.timeout = &timeout
|
||||
return ws
|
||||
}
|
||||
|
||||
@@ -49,7 +48,7 @@ func (ws *LogStrategy) WithPollInterval(pollInterval time.Duration) *LogStrategy
|
||||
}
|
||||
|
||||
func (ws *LogStrategy) WithOccurrence(o int) *LogStrategy {
|
||||
// the number of occurence needs to be positive
|
||||
// the number of occurrence needs to be positive
|
||||
if o <= 0 {
|
||||
o = 1
|
||||
}
|
||||
@@ -60,19 +59,29 @@ func (ws *LogStrategy) WithOccurrence(o int) *LogStrategy {
|
||||
// ForLog is the default construction for the fluid interface.
|
||||
//
|
||||
// For Example:
|
||||
// wait.
|
||||
// ForLog("some text").
|
||||
// WithPollInterval(1 * time.Second)
|
||||
//
|
||||
// wait.
|
||||
// ForLog("some text").
|
||||
// WithPollInterval(1 * time.Second)
|
||||
func ForLog(log string) *LogStrategy {
|
||||
return NewLogStrategy(log)
|
||||
}
|
||||
|
||||
func (ws *LogStrategy) Timeout() *time.Duration {
|
||||
return ws.timeout
|
||||
}
|
||||
|
||||
// WaitUntilReady implements Strategy.WaitUntilReady
|
||||
func (ws *LogStrategy) WaitUntilReady(ctx context.Context, target StrategyTarget) (err error) {
|
||||
// limit context to startupTimeout
|
||||
ctx, cancelContext := context.WithTimeout(ctx, ws.startupTimeout)
|
||||
defer cancelContext()
|
||||
currentOccurence := 0
|
||||
timeout := defaultStartupTimeout()
|
||||
if ws.timeout != nil {
|
||||
timeout = *ws.timeout
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
length := 0
|
||||
|
||||
LOOP:
|
||||
for {
|
||||
@@ -80,20 +89,27 @@ LOOP:
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
reader, err := target.Logs(ctx)
|
||||
checkErr := checkTarget(ctx, target)
|
||||
|
||||
reader, err := target.Logs(ctx)
|
||||
if err != nil {
|
||||
time.Sleep(ws.PollInterval)
|
||||
continue
|
||||
}
|
||||
b, err := ioutil.ReadAll(reader)
|
||||
|
||||
b, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
time.Sleep(ws.PollInterval)
|
||||
continue
|
||||
}
|
||||
|
||||
logs := string(b)
|
||||
if strings.Contains(logs, ws.Log) {
|
||||
currentOccurence++
|
||||
if ws.Occurrence == 0 || currentOccurence >= ws.Occurrence-1 {
|
||||
break LOOP
|
||||
}
|
||||
if length == len(logs) && checkErr != nil {
|
||||
return checkErr
|
||||
} else if strings.Count(logs, ws.Log) >= ws.Occurrence {
|
||||
break LOOP
|
||||
} else {
|
||||
length = len(logs)
|
||||
time.Sleep(ws.PollInterval)
|
||||
continue
|
||||
}
|
||||
|
47
vendor/github.com/testcontainers/testcontainers-go/wait/multi.go
generated
vendored
47
vendor/github.com/testcontainers/testcontainers-go/wait/multi.go
generated
vendored
@@ -1,47 +0,0 @@
|
||||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Implement interface
|
||||
var _ Strategy = (*MultiStrategy)(nil)
|
||||
|
||||
type MultiStrategy struct {
|
||||
// all Strategies should have a startupTimeout to avoid waiting infinitely
|
||||
startupTimeout time.Duration
|
||||
|
||||
// additional properties
|
||||
Strategies []Strategy
|
||||
}
|
||||
|
||||
func (ms *MultiStrategy) WithStartupTimeout(startupTimeout time.Duration) *MultiStrategy {
|
||||
ms.startupTimeout = startupTimeout
|
||||
return ms
|
||||
}
|
||||
|
||||
func ForAll(strategies ...Strategy) *MultiStrategy {
|
||||
return &MultiStrategy{
|
||||
startupTimeout: defaultStartupTimeout(),
|
||||
Strategies: strategies,
|
||||
}
|
||||
}
|
||||
|
||||
func (ms *MultiStrategy) WaitUntilReady(ctx context.Context, target StrategyTarget) (err error) {
|
||||
ctx, cancelContext := context.WithTimeout(ctx, ms.startupTimeout)
|
||||
defer cancelContext()
|
||||
|
||||
if len(ms.Strategies) == 0 {
|
||||
return fmt.Errorf("no wait strategy supplied")
|
||||
}
|
||||
|
||||
for _, strategy := range ms.Strategies {
|
||||
err := strategy.WaitUntilReady(ctx, target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
69
vendor/github.com/testcontainers/testcontainers-go/wait/nop.go
generated
vendored
Normal file
69
vendor/github.com/testcontainers/testcontainers-go/wait/nop.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/testcontainers/testcontainers-go/exec"
|
||||
)
|
||||
|
||||
var _ Strategy = (*NopStrategy)(nil)
|
||||
var _ StrategyTimeout = (*NopStrategy)(nil)
|
||||
|
||||
type NopStrategy struct {
|
||||
timeout *time.Duration
|
||||
waitUntilReady func(context.Context, StrategyTarget) error
|
||||
}
|
||||
|
||||
func ForNop(
|
||||
waitUntilReady func(context.Context, StrategyTarget) error,
|
||||
) *NopStrategy {
|
||||
return &NopStrategy{
|
||||
waitUntilReady: waitUntilReady,
|
||||
}
|
||||
}
|
||||
|
||||
func (ws *NopStrategy) Timeout() *time.Duration {
|
||||
return ws.timeout
|
||||
}
|
||||
|
||||
func (ws *NopStrategy) WithStartupTimeout(timeout time.Duration) *NopStrategy {
|
||||
ws.timeout = &timeout
|
||||
return ws
|
||||
}
|
||||
|
||||
func (ws *NopStrategy) WaitUntilReady(ctx context.Context, target StrategyTarget) error {
|
||||
return ws.waitUntilReady(ctx, target)
|
||||
}
|
||||
|
||||
type NopStrategyTarget struct {
|
||||
ReaderCloser io.ReadCloser
|
||||
ContainerState types.ContainerState
|
||||
}
|
||||
|
||||
func (st NopStrategyTarget) Host(_ context.Context) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (st NopStrategyTarget) Ports(_ context.Context) (nat.PortMap, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (st NopStrategyTarget) MappedPort(_ context.Context, n nat.Port) (nat.Port, error) {
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (st NopStrategyTarget) Logs(_ context.Context) (io.ReadCloser, error) {
|
||||
return st.ReaderCloser, nil
|
||||
}
|
||||
|
||||
func (st NopStrategyTarget) Exec(_ context.Context, _ []string, _ ...exec.ProcessOption) (int, io.Reader, error) {
|
||||
return 0, nil, nil
|
||||
}
|
||||
|
||||
func (st NopStrategyTarget) State(_ context.Context) (*types.ContainerState, error) {
|
||||
return &st.ContainerState, nil
|
||||
}
|
74
vendor/github.com/testcontainers/testcontainers-go/wait/sql.go
generated
vendored
74
vendor/github.com/testcontainers/testcontainers-go/wait/sql.go
generated
vendored
@@ -9,52 +9,92 @@ import (
|
||||
"github.com/docker/go-connections/nat"
|
||||
)
|
||||
|
||||
//ForSQL constructs a new waitForSql strategy for the given driver
|
||||
func ForSQL(port nat.Port, driver string, url func(nat.Port) string) *waitForSql {
|
||||
var _ Strategy = (*waitForSql)(nil)
|
||||
var _ StrategyTimeout = (*waitForSql)(nil)
|
||||
|
||||
const defaultForSqlQuery = "SELECT 1"
|
||||
|
||||
// ForSQL constructs a new waitForSql strategy for the given driver
|
||||
func ForSQL(port nat.Port, driver string, url func(host string, port nat.Port) string) *waitForSql {
|
||||
return &waitForSql{
|
||||
Port: port,
|
||||
URL: url,
|
||||
Driver: driver,
|
||||
startupTimeout: defaultStartupTimeout(),
|
||||
PollInterval: defaultPollInterval(),
|
||||
query: defaultForSqlQuery,
|
||||
}
|
||||
}
|
||||
|
||||
type waitForSql struct {
|
||||
URL func(port nat.Port) string
|
||||
timeout *time.Duration
|
||||
|
||||
URL func(host string, port nat.Port) string
|
||||
Driver string
|
||||
Port nat.Port
|
||||
startupTimeout time.Duration
|
||||
PollInterval time.Duration
|
||||
query string
|
||||
}
|
||||
|
||||
//Timeout sets the maximum waiting time for the strategy after which it'll give up and return an error
|
||||
func (w *waitForSql) Timeout(duration time.Duration) *waitForSql {
|
||||
w.startupTimeout = duration
|
||||
// WithStartupTimeout can be used to change the default startup timeout
|
||||
func (w *waitForSql) WithStartupTimeout(timeout time.Duration) *waitForSql {
|
||||
w.timeout = &timeout
|
||||
return w
|
||||
}
|
||||
|
||||
//WithPollInterval can be used to override the default polling interval of 100 milliseconds
|
||||
// WithPollInterval can be used to override the default polling interval of 100 milliseconds
|
||||
func (w *waitForSql) WithPollInterval(pollInterval time.Duration) *waitForSql {
|
||||
w.PollInterval = pollInterval
|
||||
return w
|
||||
}
|
||||
|
||||
//WaitUntilReady repeatedly tries to run "SELECT 1" query on the given port using sql and driver.
|
||||
// If the it doesn't succeed until the timeout value which defaults to 60 seconds, it will return an error
|
||||
// WithQuery can be used to override the default query used in the strategy.
|
||||
func (w *waitForSql) WithQuery(query string) *waitForSql {
|
||||
w.query = query
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *waitForSql) Timeout() *time.Duration {
|
||||
return w.timeout
|
||||
}
|
||||
|
||||
// WaitUntilReady repeatedly tries to run "SELECT 1" or user defined query on the given port using sql and driver.
|
||||
//
|
||||
// If it doesn't succeed until the timeout value which defaults to 60 seconds, it will return an error.
|
||||
func (w *waitForSql) WaitUntilReady(ctx context.Context, target StrategyTarget) (err error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, w.startupTimeout)
|
||||
timeout := defaultStartupTimeout()
|
||||
if w.timeout != nil {
|
||||
timeout = *w.timeout
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
host, err := target.Host(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(w.PollInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
port, err := target.MappedPort(ctx, w.Port)
|
||||
if err != nil {
|
||||
return fmt.Errorf("target.MappedPort: %v", err)
|
||||
var port nat.Port
|
||||
port, err = target.MappedPort(ctx, w.Port)
|
||||
|
||||
for port == "" {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("%s:%w", ctx.Err(), err)
|
||||
case <-ticker.C:
|
||||
if err := checkTarget(ctx, target); err != nil {
|
||||
return err
|
||||
}
|
||||
port, err = target.MappedPort(ctx, w.Port)
|
||||
}
|
||||
}
|
||||
|
||||
db, err := sql.Open(w.Driver, w.URL(port))
|
||||
db, err := sql.Open(w.Driver, w.URL(host, port))
|
||||
if err != nil {
|
||||
return fmt.Errorf("sql.Open: %v", err)
|
||||
}
|
||||
@@ -64,8 +104,10 @@ func (w *waitForSql) WaitUntilReady(ctx context.Context, target StrategyTarget)
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-ticker.C:
|
||||
|
||||
if _, err := db.ExecContext(ctx, "SELECT 1"); err != nil {
|
||||
if err := checkTarget(ctx, target); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.ExecContext(ctx, w.query); err != nil {
|
||||
continue
|
||||
}
|
||||
return nil
|
||||
|
36
vendor/github.com/testcontainers/testcontainers-go/wait/wait.go
generated
vendored
36
vendor/github.com/testcontainers/testcontainers-go/wait/wait.go
generated
vendored
@@ -2,21 +2,55 @@ package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/testcontainers/testcontainers-go/exec"
|
||||
)
|
||||
|
||||
// Strategy defines the basic interface for a Wait Strategy
|
||||
type Strategy interface {
|
||||
WaitUntilReady(context.Context, StrategyTarget) error
|
||||
}
|
||||
|
||||
// StrategyTimeout allows MultiStrategy to configure a Strategy's Timeout
|
||||
type StrategyTimeout interface {
|
||||
Timeout() *time.Duration
|
||||
}
|
||||
|
||||
type StrategyTarget interface {
|
||||
Host(context.Context) (string, error)
|
||||
Ports(ctx context.Context) (nat.PortMap, error)
|
||||
MappedPort(context.Context, nat.Port) (nat.Port, error)
|
||||
Logs(context.Context) (io.ReadCloser, error)
|
||||
Exec(ctx context.Context, cmd []string) (int, error)
|
||||
Exec(context.Context, []string, ...exec.ProcessOption) (int, io.Reader, error)
|
||||
State(context.Context) (*types.ContainerState, error)
|
||||
}
|
||||
|
||||
func checkTarget(ctx context.Context, target StrategyTarget) error {
|
||||
state, err := target.State(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return checkState(state)
|
||||
}
|
||||
|
||||
func checkState(state *types.ContainerState) error {
|
||||
switch {
|
||||
case state.Running:
|
||||
return nil
|
||||
case state.OOMKilled:
|
||||
return errors.New("container crashed with out-of-memory (OOMKilled)")
|
||||
case state.Status == "exited":
|
||||
return fmt.Errorf("container exited with code %d", state.ExitCode)
|
||||
default:
|
||||
return fmt.Errorf("unexpected container status %q", state.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func defaultStartupTimeout() time.Duration {
|
||||
|
Reference in New Issue
Block a user