Skip to content

Commit

Permalink
Merge branch 'main' into feat/copy-host-path-to
Browse files Browse the repository at this point in the history
  • Loading branch information
mdelapenya authored Sep 19, 2024
2 parents 2c6196f + fa560fb commit 85930b2
Show file tree
Hide file tree
Showing 14 changed files with 327 additions and 104 deletions.
9 changes: 8 additions & 1 deletion container.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,14 @@ func (c *ContainerRequest) BuildOptions() (types.ImageBuildOptions, error) {
}

if !c.ShouldKeepBuiltImage() {
buildOptions.Labels = core.DefaultLabels(core.SessionID())
dst := GenericLabels()
if err = core.MergeCustomLabels(dst, c.Labels); err != nil {
return types.ImageBuildOptions{}, err
}
if err = core.MergeCustomLabels(dst, buildOptions.Labels); err != nil {
return types.ImageBuildOptions{}, err
}
buildOptions.Labels = dst
}

// Do this as late as possible to ensure we don't leak the context on error/panic.
Expand Down
59 changes: 59 additions & 0 deletions container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"testing"
"time"

"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -302,6 +303,64 @@ func Test_BuildImageWithContexts(t *testing.T) {
}
}

func TestCustomLabelsImage(t *testing.T) {
const (
myLabelName = "org.my.label"
myLabelValue = "my-label-value"
)

ctx := context.Background()
req := testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
Image: "alpine:latest",
Labels: map[string]string{myLabelName: myLabelValue},
},
}

ctr, err := testcontainers.GenericContainer(ctx, req)

require.NoError(t, err)
t.Cleanup(func() { assert.NoError(t, ctr.Terminate(ctx)) })

ctrJSON, err := ctr.Inspect(ctx)
require.NoError(t, err)
assert.Equal(t, myLabelValue, ctrJSON.Config.Labels[myLabelName])
}

func TestCustomLabelsBuildOptionsModifier(t *testing.T) {
const (
myLabelName = "org.my.label"
myLabelValue = "my-label-value"
myBuildOptionLabel = "org.my.bo.label"
myBuildOptionValue = "my-bo-label-value"
)

ctx := context.Background()
req := testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
FromDockerfile: testcontainers.FromDockerfile{
Context: "./testdata",
Dockerfile: "Dockerfile",
BuildOptionsModifier: func(opts *types.ImageBuildOptions) {
opts.Labels = map[string]string{
myBuildOptionLabel: myBuildOptionValue,
}
},
},
Labels: map[string]string{myLabelName: myLabelValue},
},
}

ctr, err := testcontainers.GenericContainer(ctx, req)
testcontainers.CleanupContainer(t, ctr)
require.NoError(t, err)

ctrJSON, err := ctr.Inspect(ctx)
require.NoError(t, err)
require.Equal(t, myLabelValue, ctrJSON.Config.Labels[myLabelName])
require.Equal(t, myBuildOptionValue, ctrJSON.Config.Labels[myBuildOptionLabel])
}

func Test_GetLogsFromFailedContainer(t *testing.T) {
ctx := context.Background()
// directDockerHubReference {
Expand Down
20 changes: 20 additions & 0 deletions internal/core/labels.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package core

import (
"errors"
"fmt"
"strings"

"github.com/testcontainers/testcontainers-go/internal"
)

Expand All @@ -21,3 +25,19 @@ func DefaultLabels(sessionID string) map[string]string {
LabelVersion: internal.Version,
}
}

// MergeCustomLabels sets labels from src to dst.
// If a key in src has [LabelBase] prefix returns an error.
// If dst is nil returns an error.
func MergeCustomLabels(dst, src map[string]string) error {
if dst == nil {
return errors.New("destination map is nil")
}
for key, value := range src {
if strings.HasPrefix(key, LabelBase) {
return fmt.Errorf("key %q has %q prefix", key, LabelBase)
}
dst[key] = value
}
return nil
}
34 changes: 34 additions & 0 deletions internal/core/labels_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package core

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestMergeCustomLabels(t *testing.T) {
t.Run("success", func(t *testing.T) {
dst := map[string]string{"A": "1", "B": "2"}
src := map[string]string{"B": "X", "C": "3"}

err := MergeCustomLabels(dst, src)
require.NoError(t, err)
require.Equal(t, map[string]string{"A": "1", "B": "X", "C": "3"}, dst)
})

t.Run("invalid-prefix", func(t *testing.T) {
dst := map[string]string{"A": "1", "B": "2"}
src := map[string]string{"B": "X", LabelLang: "go"}

err := MergeCustomLabels(dst, src)

require.EqualError(t, err, `key "org.testcontainers.lang" has "org.testcontainers" prefix`)
require.Equal(t, map[string]string{"A": "1", "B": "X"}, dst)
})

t.Run("nil-destination", func(t *testing.T) {
src := map[string]string{"A": "1"}
err := MergeCustomLabels(nil, src)
require.Error(t, err)
})
}
5 changes: 5 additions & 0 deletions modules/mongodb/mongodb.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package mongodb
import (
"context"
"fmt"
"time"

"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
Expand Down Expand Up @@ -89,6 +90,10 @@ func WithPassword(password string) testcontainers.CustomizeRequestOption {
func WithReplicaSet(replSetName string) testcontainers.CustomizeRequestOption {
return func(req *testcontainers.GenericContainerRequest) error {
req.Cmd = append(req.Cmd, "--replSet", replSetName)
req.WaitingFor = wait.ForAll(
req.WaitingFor,
wait.ForExec(eval("rs.status().ok")),
).WithDeadline(60 * time.Second)
req.LifecycleHooks = append(req.LifecycleHooks, testcontainers.ContainerLifecycleHooks{
PostStarts: []testcontainers.ContainerHook{
func(ctx context.Context, c testcontainers.Container) error {
Expand Down
13 changes: 12 additions & 1 deletion modules/mongodb/mongodb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"github.com/stretchr/testify/require"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"

Expand Down Expand Up @@ -48,6 +49,13 @@ func TestMongoDB(t *testing.T) {
mongodb.WithReplicaSet("rs"),
},
},
{
name: "With Replica set and mongo:7",
img: "mongo:7",
opts: []testcontainers.ContainerCustomizer{
mongodb.WithReplicaSet("rs"),
},
},
}

for _, tc := range testCases {
Expand All @@ -67,12 +75,15 @@ func TestMongoDB(t *testing.T) {
// Force direct connection to the container to avoid the replica set
// connection string that is returned by the container itself when
// using the replica set option.
mongoClient, err := mongo.Connect(ctx, options.Client().ApplyURI(endpoint+"/?connect=direct"))
mongoClient, err := mongo.Connect(ctx, options.Client().ApplyURI(endpoint).SetDirect(true))
require.NoError(tt, err)

err = mongoClient.Ping(ctx, nil)
require.NoError(tt, err)
require.Equal(t, "test", mongoClient.Database("test").Name())

_, err = mongoClient.Database("testcontainer").Collection("test").InsertOne(context.Background(), bson.M{})
require.NoError(tt, err)
})
}
}
2 changes: 1 addition & 1 deletion modules/mssql/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func ExampleRun() {
password := "SuperStrong@Passw0rd"

mssqlContainer, err := mssql.Run(ctx,
"mcr.microsoft.com/mssql/server:2022-RTM-GDR1-ubuntu-20.04",
"mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04",
mssql.WithAcceptEULA(),
mssql.WithPassword(password),
)
Expand Down
2 changes: 1 addition & 1 deletion modules/mssql/mssql.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func WithPassword(password string) testcontainers.CustomizeRequestOption {
// Deprecated: use Run instead
// RunContainer creates an instance of the MSSQLServer container type
func RunContainer(ctx context.Context, opts ...testcontainers.ContainerCustomizer) (*MSSQLServerContainer, error) {
return Run(ctx, "mcr.microsoft.com/mssql/server:2022-CU10-ubuntu-22.04", opts...)
return Run(ctx, "mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04", opts...)
}

// Run creates an instance of the MSSQLServer container type
Expand Down
32 changes: 5 additions & 27 deletions modules/mssql/mssql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestMSSQLServer(t *testing.T) {
ctx := context.Background()

ctr, err := mssql.Run(ctx,
"mcr.microsoft.com/mssql/server:2022-CU10-ubuntu-22.04",
"mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04",
mssql.WithAcceptEULA(),
)
testcontainers.CleanupContainer(t, ctr)
Expand Down Expand Up @@ -46,7 +46,7 @@ func TestMSSQLServerWithMissingEulaOption(t *testing.T) {
ctx := context.Background()

ctr, err := mssql.Run(ctx,
"mcr.microsoft.com/mssql/server:2022-CU10-ubuntu-22.04",
"mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04",
testcontainers.WithWaitStrategy(
wait.ForLog("The SQL Server End-User License Agreement (EULA) must be accepted")),
)
Expand All @@ -65,7 +65,7 @@ func TestMSSQLServerWithConnectionStringParameters(t *testing.T) {
ctx := context.Background()

ctr, err := mssql.Run(ctx,
"mcr.microsoft.com/mssql/server:2022-CU10-ubuntu-22.04",
"mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04",
mssql.WithAcceptEULA(),
)
testcontainers.CleanupContainer(t, ctr)
Expand Down Expand Up @@ -95,7 +95,7 @@ func TestMSSQLServerWithCustomStrongPassword(t *testing.T) {
ctx := context.Background()

ctr, err := mssql.Run(ctx,
"mcr.microsoft.com/mssql/server:2022-CU10-ubuntu-22.04",
"mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04",
mssql.WithAcceptEULA(),
mssql.WithPassword("Strong@Passw0rd"),
)
Expand All @@ -119,7 +119,7 @@ func TestMSSQLServerWithInvalidPassword(t *testing.T) {
ctx := context.Background()

ctr, err := mssql.Run(ctx,
"mcr.microsoft.com/mssql/server:2022-CU10-ubuntu-22.04",
"mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04",
testcontainers.WithWaitStrategy(
wait.ForLog("Password validation failed")),
mssql.WithAcceptEULA(),
Expand All @@ -128,25 +128,3 @@ func TestMSSQLServerWithInvalidPassword(t *testing.T) {
testcontainers.CleanupContainer(t, ctr)
require.NoError(t, err)
}

func TestMSSQLServerWithAlternativeImage(t *testing.T) {
ctx := context.Background()

ctr, err := mssql.Run(ctx,
"mcr.microsoft.com/mssql/server:2022-RTM-GDR1-ubuntu-20.04",
mssql.WithAcceptEULA(),
)
testcontainers.CleanupContainer(t, ctr)
require.NoError(t, err)

// perform assertions
connectionString, err := ctr.ConnectionString(ctx)
require.NoError(t, err)

db, err := sql.Open("sqlserver", connectionString)
require.NoError(t, err)
defer db.Close()

err = db.Ping()
require.NoError(t, err)
}
2 changes: 2 additions & 0 deletions modules/postgres/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import (
type options struct {
// SQLDriverName is the name of the SQL driver to use.
SQLDriverName string
Snapshot string
}

func defaultOptions() options {
return options{
SQLDriverName: "postgres",
Snapshot: defaultSnapshotName,
}
}

Expand Down
1 change: 1 addition & 0 deletions modules/postgres/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustom
password: req.Env["POSTGRES_PASSWORD"],
user: req.Env["POSTGRES_USER"],
sqlDriverName: settings.SQLDriverName,
snapshotName: settings.Snapshot,
}
}

Expand Down
Loading

0 comments on commit 85930b2

Please sign in to comment.