Fix dependencies
This commit is contained in:
116
vendor/github.com/testcontainers/testcontainers-go/wait/host_port.go
generated
vendored
Normal file
116
vendor/github.com/testcontainers/testcontainers-go/wait/host_port.go
generated
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/docker/go-connections/nat"
|
||||
)
|
||||
|
||||
// Implement interface
|
||||
var _ Strategy = (*HostPortStrategy)(nil)
|
||||
|
||||
type HostPortStrategy struct {
|
||||
Port nat.Port
|
||||
// all WaitStrategies should have a startupTimeout to avoid waiting infinitely
|
||||
startupTimeout time.Duration
|
||||
}
|
||||
|
||||
// NewHostPortStrategy constructs a default host port strategy
|
||||
func NewHostPortStrategy(port nat.Port) *HostPortStrategy {
|
||||
return &HostPortStrategy{
|
||||
Port: port,
|
||||
startupTimeout: defaultStartupTimeout(),
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
// ForListeningPort is a helper similar to those in Wait.java
|
||||
// https://github.com/testcontainers/testcontainers-java/blob/1d85a3834bd937f80aad3a4cec249c027f31aeb4/core/src/main/java/org/testcontainers/containers/wait/strategy/Wait.java
|
||||
func ForListeningPort(port nat.Port) *HostPortStrategy {
|
||||
return NewHostPortStrategy(port)
|
||||
}
|
||||
|
||||
func (hp *HostPortStrategy) WithStartupTimeout(startupTimeout time.Duration) *HostPortStrategy {
|
||||
hp.startupTimeout = startupTimeout
|
||||
return hp
|
||||
}
|
||||
|
||||
// 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()
|
||||
|
||||
ipAddress, err := target.Host(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
port, err := target.MappedPort(ctx, hp.Port)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
proto := port.Proto()
|
||||
portNumber := port.Int()
|
||||
portString := strconv.Itoa(portNumber)
|
||||
|
||||
//external check
|
||||
dialer := net.Dialer{}
|
||||
address := net.JoinHostPort(ipAddress, portString)
|
||||
for {
|
||||
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 v2.Err == syscall.ECONNREFUSED && ctx.Err() == nil {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
} else {
|
||||
conn.Close()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
//internal check
|
||||
command := buildInternalCheckCommand(hp.Port.Int())
|
||||
for {
|
||||
exitCode, err := target.Exec(ctx, []string{"/bin/sh", "-c", command})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "host port waiting failed")
|
||||
}
|
||||
|
||||
if exitCode == 0 {
|
||||
break
|
||||
} else if exitCode == 126 {
|
||||
return errors.New("/bin/sh command not executable")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildInternalCheckCommand(internalPort int) string {
|
||||
command := `(
|
||||
cat /proc/net/tcp* | awk '{print $2}' | grep -i :%04x ||
|
||||
nc -vz -w 1 localhost %d ||
|
||||
/bin/sh -c '</dev/tcp/localhost/%d'
|
||||
)
|
||||
`
|
||||
return "true && " + fmt.Sprintf(command, internalPort, internalPort, internalPort)
|
||||
}
|
147
vendor/github.com/testcontainers/testcontainers-go/wait/http.go
generated
vendored
Normal file
147
vendor/github.com/testcontainers/testcontainers-go/wait/http.go
generated
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/docker/go-connections/nat"
|
||||
)
|
||||
|
||||
// Implement interface
|
||||
var _ Strategy = (*HTTPStrategy)(nil)
|
||||
|
||||
type HTTPStrategy struct {
|
||||
// all Strategies should have a startupTimeout to avoid waiting infinitely
|
||||
startupTimeout time.Duration
|
||||
|
||||
// additional properties
|
||||
Port nat.Port
|
||||
Path string
|
||||
StatusCodeMatcher func(status int) bool
|
||||
UseTLS bool
|
||||
AllowInsecure bool
|
||||
}
|
||||
|
||||
// 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",
|
||||
Path: path,
|
||||
StatusCodeMatcher: defaultStatusCodeMatcher,
|
||||
UseTLS: false,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func defaultStatusCodeMatcher(status int) bool {
|
||||
return status == http.StatusOK
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
func (ws *HTTPStrategy) WithStartupTimeout(startupTimeout time.Duration) *HTTPStrategy {
|
||||
ws.startupTimeout = startupTimeout
|
||||
return ws
|
||||
}
|
||||
|
||||
func (ws *HTTPStrategy) WithPort(port nat.Port) *HTTPStrategy {
|
||||
ws.Port = port
|
||||
return ws
|
||||
}
|
||||
|
||||
func (ws *HTTPStrategy) WithStatusCodeMatcher(statusCodeMatcher func(status int) bool) *HTTPStrategy {
|
||||
ws.StatusCodeMatcher = statusCodeMatcher
|
||||
return ws
|
||||
}
|
||||
|
||||
func (ws *HTTPStrategy) WithTLS(useTLS bool) *HTTPStrategy {
|
||||
ws.UseTLS = useTLS
|
||||
return ws
|
||||
}
|
||||
|
||||
func (ws *HTTPStrategy) WithAllowInsecure(allowInsecure bool) *HTTPStrategy {
|
||||
ws.AllowInsecure = allowInsecure
|
||||
return ws
|
||||
}
|
||||
|
||||
// ForHTTP is a convenience method similar to Wait.java
|
||||
// https://github.com/testcontainers/testcontainers-java/blob/1d85a3834bd937f80aad3a4cec249c027f31aeb4/core/src/main/java/org/testcontainers/containers/wait/strategy/Wait.java
|
||||
func ForHTTP(path string) *HTTPStrategy {
|
||||
return NewHTTPStrategy(path)
|
||||
}
|
||||
|
||||
// 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()
|
||||
|
||||
ipAddress, err := target.Host(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
port, err := target.MappedPort(ctx, ws.Port)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if port.Proto() != "tcp" {
|
||||
return errors.New("Cannot use HTTP client on non-TCP ports")
|
||||
}
|
||||
|
||||
portNumber := port.Int()
|
||||
portString := strconv.Itoa(portNumber)
|
||||
|
||||
address := net.JoinHostPort(ipAddress, portString)
|
||||
|
||||
var proto string
|
||||
if ws.UseTLS {
|
||||
proto = "https"
|
||||
} else {
|
||||
proto = "http"
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s://%s%s", proto, address, ws.Path)
|
||||
|
||||
tripper := http.DefaultTransport
|
||||
|
||||
if ws.AllowInsecure {
|
||||
tripper.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
||||
}
|
||||
|
||||
client := http.Client{Timeout: ws.startupTimeout, Transport: tripper}
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
Retry:
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
break Retry
|
||||
default:
|
||||
resp, err := client.Do(req)
|
||||
if err != nil || !ws.StatusCodeMatcher(resp.StatusCode) {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
|
||||
break Retry
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
104
vendor/github.com/testcontainers/testcontainers-go/wait/log.go
generated
vendored
Normal file
104
vendor/github.com/testcontainers/testcontainers-go/wait/log.go
generated
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Implement interface
|
||||
var _ Strategy = (*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
|
||||
|
||||
// additional properties
|
||||
Log string
|
||||
PollInterval time.Duration
|
||||
Occurrence int
|
||||
}
|
||||
|
||||
// NewLogStrategy constructs a HTTP strategy waiting on port 80 and status code 200
|
||||
func NewLogStrategy(log string) *LogStrategy {
|
||||
return &LogStrategy{
|
||||
startupTimeout: defaultStartupTimeout(),
|
||||
Log: log,
|
||||
PollInterval: 100 * time.Millisecond,
|
||||
Occurrence: 1,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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 *LogStrategy) WithStartupTimeout(startupTimeout time.Duration) *LogStrategy {
|
||||
ws.startupTimeout = startupTimeout
|
||||
return ws
|
||||
}
|
||||
|
||||
// WithPollInterval can be used to override the default polling interval of 100 milliseconds
|
||||
func (ws *LogStrategy) WithPollInterval(pollInterval time.Duration) *LogStrategy {
|
||||
ws.PollInterval = pollInterval
|
||||
return ws
|
||||
}
|
||||
|
||||
func (ws *LogStrategy) WithOccurrence(o int) *LogStrategy {
|
||||
// the number of occurence needs to be positive
|
||||
if o <= 0 {
|
||||
o = 1
|
||||
}
|
||||
ws.Occurrence = o
|
||||
return ws
|
||||
}
|
||||
|
||||
// ForLog is the default construction for the fluid interface.
|
||||
//
|
||||
// For Example:
|
||||
// wait.
|
||||
// ForLog("some text").
|
||||
// WithPollInterval(1 * time.Second)
|
||||
func ForLog(log string) *LogStrategy {
|
||||
return NewLogStrategy(log)
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
LOOP:
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
reader, err := target.Logs(ctx)
|
||||
|
||||
if err != nil {
|
||||
time.Sleep(ws.PollInterval)
|
||||
continue
|
||||
}
|
||||
b, err := ioutil.ReadAll(reader)
|
||||
logs := string(b)
|
||||
if strings.Contains(logs, ws.Log) {
|
||||
currentOccurence++
|
||||
if ws.Occurrence == 0 || currentOccurence >= ws.Occurrence-1 {
|
||||
break LOOP
|
||||
}
|
||||
} else {
|
||||
time.Sleep(ws.PollInterval)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
47
vendor/github.com/testcontainers/testcontainers-go/wait/multi.go
generated
vendored
Normal file
47
vendor/github.com/testcontainers/testcontainers-go/wait/multi.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
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
|
||||
}
|
66
vendor/github.com/testcontainers/testcontainers-go/wait/sql.go
generated
vendored
Normal file
66
vendor/github.com/testcontainers/testcontainers-go/wait/sql.go
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"time"
|
||||
)
|
||||
|
||||
//ForSQL constructs a new waitForSql strategy for the given driver
|
||||
func ForSQL(port nat.Port, driver string, url func(nat.Port) string) *waitForSql {
|
||||
return &waitForSql{
|
||||
Port: port,
|
||||
URL: url,
|
||||
Driver: driver,
|
||||
}
|
||||
}
|
||||
|
||||
type waitForSql struct {
|
||||
URL func(port nat.Port) string
|
||||
Driver string
|
||||
Port nat.Port
|
||||
startupTimeout time.Duration
|
||||
}
|
||||
|
||||
//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
|
||||
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 10 seconds, it will return an error
|
||||
func (w *waitForSql) WaitUntilReady(ctx context.Context, target StrategyTarget) (err error) {
|
||||
if w.startupTimeout == 0 {
|
||||
w.startupTimeout = time.Second * 10
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(ctx, w.startupTimeout)
|
||||
defer cancel()
|
||||
|
||||
ticker := time.NewTicker(time.Millisecond * 100)
|
||||
defer ticker.Stop()
|
||||
|
||||
port, err := target.MappedPort(ctx, w.Port)
|
||||
if err != nil {
|
||||
return fmt.Errorf("target.MappedPort: %v", err)
|
||||
}
|
||||
|
||||
db, err := sql.Open(w.Driver, w.URL(port))
|
||||
if err != nil {
|
||||
return fmt.Errorf("sql.Open: %v", err)
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-ticker.C:
|
||||
|
||||
if _, err := db.ExecContext(ctx, "SELECT 1"); err != nil {
|
||||
continue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
24
vendor/github.com/testcontainers/testcontainers-go/wait/wait.go
generated
vendored
Normal file
24
vendor/github.com/testcontainers/testcontainers-go/wait/wait.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/docker/go-connections/nat"
|
||||
)
|
||||
|
||||
type Strategy interface {
|
||||
WaitUntilReady(context.Context, StrategyTarget) error
|
||||
}
|
||||
|
||||
type StrategyTarget interface {
|
||||
Host(context.Context) (string, error)
|
||||
MappedPort(context.Context, nat.Port) (nat.Port, error)
|
||||
Logs(context.Context) (io.ReadCloser, error)
|
||||
Exec(ctx context.Context, cmd []string) (int, error)
|
||||
}
|
||||
|
||||
func defaultStartupTimeout() time.Duration {
|
||||
return 60 * time.Second
|
||||
}
|
Reference in New Issue
Block a user