Upgrade dependencies

This commit is contained in:
2021-01-17 19:00:46 +01:00
parent ee1ce9e0ae
commit 963220da41
123 changed files with 7786 additions and 3030 deletions

View File

@@ -5,6 +5,7 @@ import (
"crypto/tls"
"errors"
"fmt"
"io"
"net"
"net/http"
"strconv"
@@ -24,8 +25,13 @@ type HTTPStrategy struct {
Port nat.Port
Path string
StatusCodeMatcher func(status int) bool
ResponseMatcher func(body io.Reader) bool
UseTLS bool
AllowInsecure bool
TLSConfig *tls.Config // TLS config for HTTPS
Method string // http method
Body io.Reader // http request body
PollInterval time.Duration
}
// NewHTTPStrategy constructs a HTTP strategy waiting on port 80 and status code 200
@@ -35,9 +41,13 @@ func NewHTTPStrategy(path string) *HTTPStrategy {
Port: "80/tcp",
Path: path,
StatusCodeMatcher: defaultStatusCodeMatcher,
ResponseMatcher: func(body io.Reader) bool { return true },
UseTLS: false,
TLSConfig: nil,
Method: http.MethodGet,
Body: nil,
PollInterval: defaultPollInterval(),
}
}
func defaultStatusCodeMatcher(status int) bool {
@@ -63,8 +73,16 @@ func (ws *HTTPStrategy) WithStatusCodeMatcher(statusCodeMatcher func(status int)
return ws
}
func (ws *HTTPStrategy) WithTLS(useTLS bool) *HTTPStrategy {
func (ws *HTTPStrategy) WithResponseMatcher(matcher func(body io.Reader) bool) *HTTPStrategy {
ws.ResponseMatcher = matcher
return ws
}
func (ws *HTTPStrategy) WithTLS(useTLS bool, tlsconf ...*tls.Config) *HTTPStrategy {
ws.UseTLS = useTLS
if useTLS && len(tlsconf) > 0 {
ws.TLSConfig = tlsconf[0]
}
return ws
}
@@ -73,6 +91,22 @@ func (ws *HTTPStrategy) WithAllowInsecure(allowInsecure bool) *HTTPStrategy {
return ws
}
func (ws *HTTPStrategy) WithMethod(method string) *HTTPStrategy {
ws.Method = method
return ws
}
func (ws *HTTPStrategy) WithBody(reqdata io.Reader) *HTTPStrategy {
ws.Body = reqdata
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
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 {
@@ -99,49 +133,73 @@ func (ws *HTTPStrategy) WaitUntilReady(ctx context.Context, target StrategyTarge
return errors.New("Cannot use HTTP client on non-TCP ports")
}
portNumber := port.Int()
portString := strconv.Itoa(portNumber)
switch ws.Method {
case http.MethodGet, http.MethodHead, http.MethodPost,
http.MethodPut, http.MethodPatch, http.MethodDelete,
http.MethodConnect, http.MethodOptions, http.MethodTrace:
default:
if ws.Method != "" {
return fmt.Errorf("invalid http method %q", ws.Method)
}
ws.Method = http.MethodGet
}
address := net.JoinHostPort(ipAddress, portString)
tripper := &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
TLSClientConfig: ws.TLSConfig,
}
var proto string
if ws.UseTLS {
proto = "https"
if ws.AllowInsecure {
if ws.TLSConfig == nil {
tripper.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
} else {
ws.TLSConfig.InsecureSkipVerify = true
}
}
} else {
proto = "http"
}
url := fmt.Sprintf("%s://%s%s", proto, address, ws.Path)
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)
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:
return ctx.Err()
case <-time.After(ws.PollInterval):
req, err := http.NewRequestWithContext(ctx, ws.Method, endpoint, ws.Body)
if err != nil {
return err
}
resp, err := client.Do(req)
if err != nil || !ws.StatusCodeMatcher(resp.StatusCode) {
time.Sleep(100 * time.Millisecond)
if err != nil {
continue
}
break Retry
if ws.StatusCodeMatcher != nil && !ws.StatusCodeMatcher(resp.StatusCode) {
continue
}
if ws.ResponseMatcher != nil && !ws.ResponseMatcher(resp.Body) {
continue
}
if err := resp.Body.Close(); err != nil {
continue
}
return nil
}
}
return nil
}

View File

@@ -17,8 +17,8 @@ type LogStrategy struct {
// additional properties
Log string
PollInterval time.Duration
Occurrence int
PollInterval time.Duration
}
// NewLogStrategy constructs a HTTP strategy waiting on port 80 and status code 200
@@ -26,8 +26,8 @@ func NewLogStrategy(log string) *LogStrategy {
return &LogStrategy{
startupTimeout: defaultStartupTimeout(),
Log: log,
PollInterval: 100 * time.Millisecond,
Occurrence: 1,
PollInterval: defaultPollInterval(),
}
}

View File

@@ -16,6 +16,7 @@ func ForSQL(port nat.Port, driver string, url func(nat.Port) string) *waitForSql
URL: url,
Driver: driver,
startupTimeout: defaultStartupTimeout(),
PollInterval: defaultPollInterval(),
}
}
@@ -24,6 +25,7 @@ type waitForSql struct {
Driver string
Port nat.Port
startupTimeout time.Duration
PollInterval time.Duration
}
//Timeout sets the maximum waiting time for the strategy after which it'll give up and return an error
@@ -32,13 +34,19 @@ func (w *waitForSql) Timeout(duration time.Duration) *waitForSql {
return w
}
//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
func (w *waitForSql) WaitUntilReady(ctx context.Context, target StrategyTarget) (err error) {
ctx, cancel := context.WithTimeout(ctx, w.startupTimeout)
defer cancel()
ticker := time.NewTicker(time.Millisecond * 100)
ticker := time.NewTicker(w.PollInterval)
defer ticker.Stop()
port, err := target.MappedPort(ctx, w.Port)
@@ -50,6 +58,7 @@ func (w *waitForSql) WaitUntilReady(ctx context.Context, target StrategyTarget)
if err != nil {
return fmt.Errorf("sql.Open: %v", err)
}
defer db.Close()
for {
select {
case <-ctx.Done():

View File

@@ -22,3 +22,7 @@ type StrategyTarget interface {
func defaultStartupTimeout() time.Duration {
return 60 * time.Second
}
func defaultPollInterval() time.Duration {
return 100 * time.Millisecond
}