Skip to content

Commit

Permalink
Move the container and config tests into a test package
Browse files Browse the repository at this point in the history
This work has been extracted from testcontainers#2202 and is related to testcontainers#2180. See the original PR for the full context and reasoning.
  • Loading branch information
Minivera committed Feb 16, 2024
1 parent 5054ae1 commit 2dc8276
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 63 deletions.
9 changes: 5 additions & 4 deletions config_test.go
@@ -1,10 +1,11 @@
package testcontainers
package testcontainers_test

import (
"testing"

"github.com/stretchr/testify/assert"

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

Expand All @@ -26,9 +27,9 @@ func TestReadConfig(t *testing.T) {
t.Setenv("USERPROFILE", "") // Windows support
t.Setenv("TESTCONTAINERS_RYUK_DISABLED", "true")

cfg := ReadConfig()
cfg := testcontainers.ReadConfig()

expected := TestcontainersConfig{
expected := testcontainers.TestcontainersConfig{
RyukDisabled: true,
Config: config.Config{
RyukDisabled: true,
Expand All @@ -38,7 +39,7 @@ func TestReadConfig(t *testing.T) {
assert.Equal(t, expected, cfg)

t.Setenv("TESTCONTAINERS_RYUK_DISABLED", "false")
cfg = ReadConfig()
cfg = testcontainers.ReadConfig()
assert.Equal(t, expected, cfg)
})
}
34 changes: 34 additions & 0 deletions container_ignore_test.go
@@ -0,0 +1,34 @@
// This test is testing very internal logic that should not be exported away from this package. We'll
// leave it in the main testcontainers package. Do not use for user facing examples.
package testcontainers

import (
"testing"

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

func TestParseDockerIgnore(t *testing.T) {
testCases := []struct {
filePath string
expectedErr error
expectedExcluded []string
}{
{
filePath: "./testdata/dockerignore",
expectedErr: nil,
expectedExcluded: []string{"vendor", "foo", "bar"},
},
{
filePath: "./testdata",
expectedErr: nil,
expectedExcluded: []string(nil),
},
}

for _, testCase := range testCases {
excluded, err := parseDockerIgnore(testCase.filePath)
assert.Equal(t, testCase.expectedErr, err)
assert.Equal(t, testCase.expectedExcluded, excluded)
}
}
94 changes: 35 additions & 59 deletions container_test.go
@@ -1,4 +1,4 @@
package testcontainers
package testcontainers_test

import (
"archive/tar"
Expand All @@ -16,22 +16,23 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

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

func Test_ContainerValidation(t *testing.T) {
type ContainerValidationTestCase struct {
Name string
ExpectedError error
ContainerRequest ContainerRequest
ContainerRequest testcontainers.ContainerRequest
}

testTable := []ContainerValidationTestCase{
{
Name: "cannot set both context and image",
ExpectedError: errors.New("you cannot specify both an Image and Context in a ContainerRequest"),
ContainerRequest: ContainerRequest{
FromDockerfile: FromDockerfile{
ContainerRequest: testcontainers.ContainerRequest{
FromDockerfile: testcontainers.FromDockerfile{
Context: ".",
},
Image: "redis:latest",
Expand All @@ -40,23 +41,23 @@ func Test_ContainerValidation(t *testing.T) {
{
Name: "can set image without context",
ExpectedError: nil,
ContainerRequest: ContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
Image: "redis:latest",
},
},
{
Name: "can set context without image",
ExpectedError: nil,
ContainerRequest: ContainerRequest{
FromDockerfile: FromDockerfile{
ContainerRequest: testcontainers.ContainerRequest{
FromDockerfile: testcontainers.FromDockerfile{
Context: ".",
},
},
},
{
Name: "Can mount same source to multiple targets",
ExpectedError: nil,
ContainerRequest: ContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
Image: "redis:latest",
HostConfigModifier: func(hc *container.HostConfig) {
hc.Binds = []string{"/data:/srv", "/data:/data"}
Expand All @@ -66,7 +67,7 @@ func Test_ContainerValidation(t *testing.T) {
{
Name: "Cannot mount multiple sources to same target",
ExpectedError: errors.New("duplicate mount target detected: /data"),
ContainerRequest: ContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
Image: "redis:latest",
HostConfigModifier: func(hc *container.HostConfig) {
hc.Binds = []string{"/data:/data", "/data:/data"}
Expand All @@ -76,7 +77,7 @@ func Test_ContainerValidation(t *testing.T) {
{
Name: "Invalid bind mount",
ExpectedError: errors.New("invalid bind mount: /data:/data:/data"),
ContainerRequest: ContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
Image: "redis:latest",
HostConfigModifier: func(hc *container.HostConfig) {
hc.Binds = []string{"/data:/data:/data"}
Expand Down Expand Up @@ -106,27 +107,27 @@ func Test_GetDockerfile(t *testing.T) {
type TestCase struct {
name string
ExpectedDockerfileName string
ContainerRequest ContainerRequest
ContainerRequest testcontainers.ContainerRequest
}

testTable := []TestCase{
{
name: "defaults to \"Dockerfile\" 1",
ExpectedDockerfileName: "Dockerfile",
ContainerRequest: ContainerRequest{},
ContainerRequest: testcontainers.ContainerRequest{},
},
{
name: "defaults to \"Dockerfile\" 2",
ExpectedDockerfileName: "Dockerfile",
ContainerRequest: ContainerRequest{
FromDockerfile: FromDockerfile{},
ContainerRequest: testcontainers.ContainerRequest{
FromDockerfile: testcontainers.FromDockerfile{},
},
},
{
name: "will override name",
ExpectedDockerfileName: "CustomDockerfile",
ContainerRequest: ContainerRequest{
FromDockerfile: FromDockerfile{
ContainerRequest: testcontainers.ContainerRequest{
FromDockerfile: testcontainers.FromDockerfile{
Dockerfile: "CustomDockerfile",
},
},
Expand Down Expand Up @@ -278,16 +279,16 @@ func Test_BuildImageWithContexts(t *testing.T) {
if err != nil {
t.Fatal(err)
}
req := ContainerRequest{
FromDockerfile: FromDockerfile{
req := testcontainers.ContainerRequest{
FromDockerfile: testcontainers.FromDockerfile{
ContextArchive: a,
Context: testCase.ContextPath,
Dockerfile: testCase.Dockerfile,
},
WaitingFor: wait.ForLog(testCase.ExpectedEchoOutput).WithStartupTimeout(1 * time.Minute),
}

c, err := GenericContainer(ctx, GenericContainerRequest{
c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
Expand All @@ -308,14 +309,14 @@ func Test_BuildImageWithContexts(t *testing.T) {
func Test_GetLogsFromFailedContainer(t *testing.T) {
ctx := context.Background()
// directDockerHubReference {
req := ContainerRequest{
req := testcontainers.ContainerRequest{
Image: "docker.io/alpine",
Cmd: []string{"echo", "-n", "I was not expecting this"},
WaitingFor: wait.ForLog("I was expecting this").WithStartupTimeout(5 * time.Second),
}
// }

c, err := GenericContainer(ctx, GenericContainerRequest{
c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
Expand Down Expand Up @@ -391,7 +392,7 @@ func TestImageSubstitutors(t *testing.T) {
tests := []struct {
name string
image string // must be a valid image, as the test will try to create a container from it
substitutors []ImageSubstitutor
substitutors []testcontainers.ImageSubstitutor
expectedImage string
expectedError error
}{
Expand All @@ -403,19 +404,19 @@ func TestImageSubstitutors(t *testing.T) {
{
name: "Noop substitutor",
image: "alpine",
substitutors: []ImageSubstitutor{NoopImageSubstitutor{}},
substitutors: []testcontainers.ImageSubstitutor{NoopImageSubstitutor{}},
expectedImage: "alpine",
},
{
name: "Prepend namespace",
image: "alpine",
substitutors: []ImageSubstitutor{dockerImageSubstitutor{}},
substitutors: []testcontainers.ImageSubstitutor{dockerImageSubstitutor{}},
expectedImage: "docker.io/alpine",
},
{
name: "Substitution with error",
image: "alpine",
substitutors: []ImageSubstitutor{errorSubstitutor{}},
substitutors: []testcontainers.ImageSubstitutor{errorSubstitutor{}},
expectedImage: "alpine",
expectedError: errSubstitution,
},
Expand All @@ -424,12 +425,12 @@ func TestImageSubstitutors(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctx := context.Background()
req := ContainerRequest{
req := testcontainers.ContainerRequest{
Image: test.image,
ImageSubstitutors: test.substitutors,
}

container, err := GenericContainer(ctx, GenericContainerRequest{
container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
Expand All @@ -447,7 +448,7 @@ func TestImageSubstitutors(t *testing.T) {

// enforce the concrete type, as GenericContainer returns an interface,
// which will be changed in future implementations of the library
dockerContainer := container.(*DockerContainer)
dockerContainer := container.(*testcontainers.DockerContainer)
assert.Equal(t, test.expectedImage, dockerContainer.Image)
})
}
Expand All @@ -462,12 +463,12 @@ func TestShouldStartContainersInParallel(t *testing.T) {
t.Run(fmt.Sprintf("iteration_%d", i), func(t *testing.T) {
t.Parallel()

req := ContainerRequest{
req := testcontainers.ContainerRequest{
Image: nginxAlpineImage,
ExposedPorts: []string{nginxDefaultPort},
WaitingFor: wait.ForHTTP("/").WithStartupTimeout(10 * time.Second),
}
container, err := GenericContainer(ctx, GenericContainerRequest{
container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
Expand All @@ -488,39 +489,14 @@ func TestShouldStartContainersInParallel(t *testing.T) {
}
}

func TestParseDockerIgnore(t *testing.T) {
testCases := []struct {
filePath string
expectedErr error
expectedExcluded []string
}{
{
filePath: "./testdata/dockerignore",
expectedErr: nil,
expectedExcluded: []string{"vendor", "foo", "bar"},
},
{
filePath: "./testdata",
expectedErr: nil,
expectedExcluded: []string(nil),
},
}

for _, testCase := range testCases {
excluded, err := parseDockerIgnore(testCase.filePath)
assert.Equal(t, testCase.expectedErr, err)
assert.Equal(t, testCase.expectedExcluded, excluded)
}
}

func ExampleGenericContainer_withSubstitutors() {
ctx := context.Background()

// applyImageSubstitutors {
container, err := GenericContainer(ctx, GenericContainerRequest{
ContainerRequest: ContainerRequest{
container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
Image: "alpine:latest",
ImageSubstitutors: []ImageSubstitutor{dockerImageSubstitutor{}},
ImageSubstitutors: []testcontainers.ImageSubstitutor{dockerImageSubstitutor{}},
},
Started: true,
})
Expand All @@ -538,7 +514,7 @@ func ExampleGenericContainer_withSubstitutors() {

// enforce the concrete type, as GenericContainer returns an interface,
// which will be changed in future implementations of the library
dockerContainer := container.(*DockerContainer)
dockerContainer := container.(*testcontainers.DockerContainer)

fmt.Println(dockerContainer.Image)

Expand Down
36 changes: 36 additions & 0 deletions utils_test.go
@@ -0,0 +1,36 @@
package testcontainers_test

import (
"context"
"os"
"strings"
"testing"

"github.com/stretchr/testify/require"

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

const (
nginxAlpineImage = "docker.io/nginx:alpine"
nginxDefaultPort = "80/tcp"
)

var providerType = testcontainers.ProviderDocker

func init() {
if strings.Contains(os.Getenv("DOCKER_HOST"), "podman.sock") {
providerType = testcontainers.ProviderPodman
}
}

func terminateContainerOnEnd(tb testing.TB, ctx context.Context, ctr testcontainers.Container) {
tb.Helper()
if ctr == nil {
return
}
tb.Cleanup(func() {
tb.Log("terminating container")
require.NoError(tb, ctr.Terminate(ctx))
})
}

0 comments on commit 2dc8276

Please sign in to comment.