Skip to content

Commit

Permalink
Introduce a testcontainers_test package to solve some of the docs i…
Browse files Browse the repository at this point in the history
…mports

As discussed in testcontainers#2180, the imported examples from tests for the docs from lack the package prefix before the imports, which leads to the example not being directly copy/paste-able. To solve the issue it was suggested to create a `testcontainers_test` package for the example tests and to convert everything.

I did my best to convert all the tests in a way that makes sense, and I extracted any test that would import very internal things that we should not export. Some of the tests had to be slightly rewritten (the lifecycle tests in particular), but they should stay pretty much the same.

Test by running all the root unit tests, they should all work as expected. The examples in the docs should all have the packages as prefixes now.
  • Loading branch information
Minivera committed Feb 6, 2024
1 parent 0e16af2 commit a464f02
Show file tree
Hide file tree
Showing 25 changed files with 912 additions and 815 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

0 comments on commit a464f02

Please sign in to comment.