Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ func (c *DockerContainer) Endpoint(ctx context.Context, proto string) (string, e
}

// PortEndpoint gets proto://host:port string for the given exposed port
// Will returns just host:port if proto is ""
// It returns proto://host:port or proto://[IPv6host]:port string for the given exposed port.
// It returns just host:port or [IPv6host]:port if proto is blank.
func (c *DockerContainer) PortEndpoint(ctx context.Context, port nat.Port, proto string) (string, error) {
host, err := c.Host(ctx)
if err != nil {
Expand All @@ -151,12 +152,12 @@ func (c *DockerContainer) PortEndpoint(ctx context.Context, port nat.Port, proto
return "", err
}

protoFull := ""
if proto != "" {
protoFull = proto + "://"
hostPort := net.JoinHostPort(host, outerPort.Port())
if proto == "" {
return hostPort, nil
}

return fmt.Sprintf("%s%s:%s", protoFull, host, outerPort.Port()), nil
return proto + "://" + hostPort, nil
}

// Host gets host (ip or name) of the docker daemon where the container port is exposed
Expand Down Expand Up @@ -1445,7 +1446,7 @@ func (p *DockerProvider) attemptToPullImage(ctx context.Context, tag string, pul
defer pull.Close()

// download of docker image finishes at EOF of the pull request
_, err = io.ReadAll(pull)
_, err = io.Copy(io.Discard, pull)
return err
}

Expand Down
10 changes: 2 additions & 8 deletions examples/nginx/nginx.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package nginx

import (
"context"
"fmt"
"time"

"github.com/testcontainers/testcontainers-go"
Expand Down Expand Up @@ -32,16 +31,11 @@ func startContainer(ctx context.Context) (*nginxContainer, error) {
return nginxC, err
}

ip, err := container.Host(ctx)
endpoint, err := container.PortEndpoint(ctx, "80", "http")
if err != nil {
return nginxC, err
}

mappedPort, err := container.MappedPort(ctx, "80")
if err != nil {
return nginxC, err
}

nginxC.URI = fmt.Sprintf("http://%s:%s", ip, mappedPort.Port())
nginxC.URI = endpoint
return nginxC, nil
}
6 changes: 5 additions & 1 deletion lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,11 @@ func (c *DockerContainer) printLogs(ctx context.Context, cause error) {

b, err := io.ReadAll(reader)
if err != nil {
c.logger.Printf("failed reading container logs: %v\n", err)
if len(b) > 0 {
c.logger.Printf("failed reading container logs: %v\npartial container logs (%s):\n%s", err, cause, b)
} else {
c.logger.Printf("failed reading container logs: %v\n", err)
}
return
}

Expand Down
12 changes: 1 addition & 11 deletions modules/azure/azurite/azurite.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,6 @@ func (c *Container) TableServiceURL(ctx context.Context) (string, error) {
}

func (c *Container) serviceURL(ctx context.Context, srv service) (string, error) {
hostname, err := c.Host(ctx)
if err != nil {
return "", fmt.Errorf("host: %w", err)
}

var port nat.Port
switch srv {
case blobService:
Expand All @@ -72,12 +67,7 @@ func (c *Container) serviceURL(ctx context.Context, srv service) (string, error)
return "", fmt.Errorf("unknown service: %s", srv)
}

mappedPort, err := c.MappedPort(ctx, port)
if err != nil {
return "", fmt.Errorf("mapped port: %w", err)
}

return fmt.Sprintf("http://%s:%d", hostname, mappedPort.Int()), nil
return c.PortEndpoint(ctx, port, "http")
}

// Run creates an instance of the Azurite container type
Expand Down
12 changes: 1 addition & 11 deletions modules/cassandra/cassandra.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,7 @@ type CassandraContainer struct {
// ConnectionHost returns the host and port of the cassandra container, using the default, native 9000 port, and
// obtaining the host and exposed port from the container
func (c *CassandraContainer) ConnectionHost(ctx context.Context) (string, error) {
host, err := c.Host(ctx)
if err != nil {
return "", err
}

port, err := c.MappedPort(ctx, port)
if err != nil {
return "", err
}

return host + ":" + port.Port(), nil
return c.PortEndpoint(ctx, port, "")
}

// WithConfigFile sets the YAML config file to be used for the cassandra container
Expand Down
13 changes: 1 addition & 12 deletions modules/chroma/chroma.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package chroma

import (
"context"
"errors"
"fmt"

"github.com/testcontainers/testcontainers-go"
Expand Down Expand Up @@ -60,15 +59,5 @@ func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustom

// RESTEndpoint returns the REST endpoint of the Chroma container
func (c *ChromaContainer) RESTEndpoint(ctx context.Context) (string, error) {
containerPort, err := c.MappedPort(ctx, "8000/tcp")
if err != nil {
return "", fmt.Errorf("failed to get container port: %w", err)
}

host, err := c.Host(ctx)
if err != nil {
return "", errors.New("failed to get container host")
}

return fmt.Sprintf("http://%s:%s", host, containerPort.Port()), nil
return c.PortEndpoint(ctx, "8000/tcp", "http")
}
12 changes: 1 addition & 11 deletions modules/clickhouse/clickhouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,7 @@ type ClickHouseContainer struct {
// ConnectionHost returns the host and port of the clickhouse container, using the default, native 9000 port, and
// obtaining the host and exposed port from the container
func (c *ClickHouseContainer) ConnectionHost(ctx context.Context) (string, error) {
host, err := c.Host(ctx)
if err != nil {
return "", err
}

port, err := c.MappedPort(ctx, nativePort)
if err != nil {
return "", err
}

return host + ":" + port.Port(), nil
return c.PortEndpoint(ctx, nativePort, "")
}

// ConnectionString returns the dsn string for the clickhouse container, using the default, native 9000 port, and
Expand Down
13 changes: 1 addition & 12 deletions modules/consul/consul.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,7 @@ type ConsulContainer struct {
//
//nolint:revive,staticcheck //FIXME
func (c *ConsulContainer) ApiEndpoint(ctx context.Context) (string, error) {
mappedPort, err := c.MappedPort(ctx, defaultHTTPAPIPort)
if err != nil {
return "", err
}

hostIP, err := c.Host(ctx)
if err != nil {
return "", err
}

uri := fmt.Sprintf("%s:%s", hostIP, mappedPort.Port())
return uri, nil
return c.PortEndpoint(ctx, defaultHTTPAPIPort, "")
}

// WithConfigString takes in a JSON string of keys and values to define a configuration to be used by the instance.
Expand Down
22 changes: 3 additions & 19 deletions modules/couchbase/couchbase.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,7 @@ func StartContainer(ctx context.Context, opts ...Option) (*CouchbaseContainer, e
// ConnectionString returns the connection string to connect to the Couchbase container instance.
// It returns a string with the format couchbase://<host>:<port>
func (c *CouchbaseContainer) ConnectionString(ctx context.Context) (string, error) {
host, err := c.Host(ctx)
if err != nil {
return "", err
}

port, err := c.MappedPort(ctx, KV_PORT)
if err != nil {
return "", err
}

return fmt.Sprintf("couchbase://%s:%d", host, port.Int()), nil
return c.PortEndpoint(ctx, KV_PORT, "couchbase")
}

// Username returns the username of the Couchbase administrator.
Expand Down Expand Up @@ -607,17 +597,11 @@ func (c *CouchbaseContainer) doHTTPRequest(ctx context.Context, port, path, meth
}

func (c *CouchbaseContainer) getURL(ctx context.Context, port, path string) (string, error) {
host, err := c.Host(ctx)
if err != nil {
return "", err
}

mappedPort, err := c.MappedPort(ctx, nat.Port(port))
endpoint, err := c.PortEndpoint(ctx, nat.Port(port), "http")
if err != nil {
return "", err
}

return fmt.Sprintf("http://%s:%d%s", host, mappedPort.Int(), path), nil
return endpoint + path, nil
}

func (c *CouchbaseContainer) getInternalIPAddress(ctx context.Context) (string, error) {
Expand Down
11 changes: 3 additions & 8 deletions modules/databend/databend.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,9 @@ func (c *DatabendContainer) MustConnectionString(ctx context.Context, args ...st
}

func (c *DatabendContainer) ConnectionString(ctx context.Context, args ...string) (string, error) {
containerPort, err := c.MappedPort(ctx, "8000/tcp")
endpoint, err := c.PortEndpoint(ctx, "8000/tcp", "")
if err != nil {
return "", fmt.Errorf("mapped port: %w", err)
}

host, err := c.Host(ctx)
if err != nil {
return "", err
return "", fmt.Errorf("port endpoint: %w", err)
}

extraArgs := ""
Expand All @@ -112,7 +107,7 @@ func (c *DatabendContainer) ConnectionString(ctx context.Context, args ...string
}

// databend://databend:databend@localhost:8000/default?sslmode=disable
connectionString := fmt.Sprintf("databend://%s:%s@%s:%s/%s%s", c.username, c.password, host, containerPort.Port(), c.database, extraArgs)
connectionString := fmt.Sprintf("databend://%s:%s@%s/%s%s", c.username, c.password, endpoint, c.database, extraArgs)
return connectionString, nil
}

Expand Down
18 changes: 4 additions & 14 deletions modules/dolt/dolt.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,17 +152,12 @@ func (c *DoltContainer) initialize(ctx context.Context, createUser bool) error {
}

func (c *DoltContainer) initialConnectionString(ctx context.Context) (string, error) {
containerPort, err := c.MappedPort(ctx, "3306/tcp")
endpoint, err := c.PortEndpoint(ctx, "3306/tcp", "")
if err != nil {
return "", err
}

host, err := c.Host(ctx)
if err != nil {
return "", err
}

connectionString := fmt.Sprintf("root:@tcp(%s:%s)/", host, containerPort.Port())
connectionString := fmt.Sprintf("root:@tcp(%s)/", endpoint)
return connectionString, nil
}

Expand All @@ -175,12 +170,7 @@ func (c *DoltContainer) MustConnectionString(ctx context.Context, args ...string
}

func (c *DoltContainer) ConnectionString(ctx context.Context, args ...string) (string, error) {
containerPort, err := c.MappedPort(ctx, "3306/tcp")
if err != nil {
return "", err
}

host, err := c.Host(ctx)
endpoint, err := c.PortEndpoint(ctx, "3306/tcp", "")
if err != nil {
return "", err
}
Expand All @@ -193,7 +183,7 @@ func (c *DoltContainer) ConnectionString(ctx context.Context, args ...string) (s
extraArgs = "?" + extraArgs
}

connectionString := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s%s", c.username, c.password, host, containerPort.Port(), c.database, extraArgs)
connectionString := fmt.Sprintf("%s:%s@tcp(%s)/%s%s", c.username, c.password, endpoint, c.database, extraArgs)
return connectionString, nil
}

Expand Down
12 changes: 1 addition & 11 deletions modules/dynamodb/dynamodb.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,7 @@ func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustom

// ConnectionString returns DynamoDB local endpoint host and port in <host>:<port> format
func (c *DynamoDBContainer) ConnectionString(ctx context.Context) (string, error) {
mappedPort, err := c.MappedPort(ctx, port)
if err != nil {
return "", err
}

hostIP, err := c.Host(ctx)
if err != nil {
return "", err
}

return hostIP + ":" + mappedPort.Port(), nil
return c.PortEndpoint(ctx, port, "")
}

// WithSharedDB allows container reuse between successive runs. Data will be persisted
Expand Down
17 changes: 6 additions & 11 deletions modules/elasticsearch/elasticsearch.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,22 +159,17 @@ func setWaitFor(options *Options, req *testcontainers.ContainerRequest) {
// configureAddress sets the address of the Elasticsearch container.
// If the certificate is set, it will use https as protocol, otherwise http.
func (c *ElasticsearchContainer) configureAddress(ctx context.Context) error {
containerPort, err := c.MappedPort(ctx, defaultHTTPPort+"/tcp")
if err != nil {
return fmt.Errorf("mapped port: %w", err)
}

host, err := c.Host(ctx)
if err != nil {
return fmt.Errorf("host: %w", err)
}

proto := "http"
if c.Settings.CACert != nil {
proto = "https"
}

c.Settings.Address = fmt.Sprintf("%s://%s:%s", proto, host, containerPort.Port())
endpoint, err := c.PortEndpoint(ctx, defaultHTTPPort+"/tcp", proto)
if err != nil {
return fmt.Errorf("port endpoint: %w", err)
}

c.Settings.Address = endpoint

return nil
}
Expand Down
24 changes: 2 additions & 22 deletions modules/etcd/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,17 +206,7 @@ func configureCMD(settings options) []string {
// ClientEndpoint returns the client endpoint for the etcd container, and an error if any.
// For a cluster, it returns the client endpoint of the first node.
func (c *EtcdContainer) ClientEndpoint(ctx context.Context) (string, error) {
host, err := c.Host(ctx)
if err != nil {
return "", err
}

port, err := c.MappedPort(ctx, clientPort)
if err != nil {
return "", err
}

return fmt.Sprintf("http://%s:%s", host, port.Port()), nil
return c.PortEndpoint(ctx, clientPort, "http")
}

// ClientEndpoints returns the client endpoints for the etcd cluster.
Expand All @@ -242,17 +232,7 @@ func (c *EtcdContainer) ClientEndpoints(ctx context.Context) ([]string, error) {
// PeerEndpoint returns the peer endpoint for the etcd container, and an error if any.
// For a cluster, it returns the peer endpoint of the first node.
func (c *EtcdContainer) PeerEndpoint(ctx context.Context) (string, error) {
host, err := c.Host(ctx)
if err != nil {
return "", err
}

port, err := c.MappedPort(ctx, peerPort)
if err != nil {
return "", err
}

return fmt.Sprintf("http://%s:%s", host, port.Port()), nil
return c.PortEndpoint(ctx, peerPort, "http")
}

// PeerEndpoints returns the peer endpoints for the etcd cluster.
Expand Down
2 changes: 1 addition & 1 deletion modules/gcloud/bigquery.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ func RunBigQuery(ctx context.Context, img string, opts ...testcontainers.Contain
})
}

return newGCloudContainer(ctx, req, 9050, settings, "http://")
return newGCloudContainer(ctx, req, 9050, settings, "http")
}
Loading