From ce8b62fbfe7f074768daf5d6d05967ce0048df72 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Wed, 28 Feb 2024 14:57:28 -0500 Subject: [PATCH 1/2] Move the file and mounts tests into a test package This work has been extracted from #2202 and is related to #2180. See the original PR for the full context and reasoning. This will help with the documentation, since all examples will now have the module prefixes. --- docker_files_test.go | 49 ++++++++++++++++++++-------------- docker_mounts.go | 6 +++++ file_test.go | 2 ++ mounts_test.go | 62 +++++++++++++++++++++++--------------------- utils_test.go | 21 +++++++++++++++ 5 files changed, 90 insertions(+), 50 deletions(-) create mode 100644 utils_test.go diff --git a/docker_files_test.go b/docker_files_test.go index d6eb15b804..afdb44822d 100644 --- a/docker_files_test.go +++ b/docker_files_test.go @@ -1,4 +1,4 @@ -package testcontainers +package testcontainers_test import ( "context" @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" ) @@ -21,10 +22,10 @@ func TestCopyFileToContainer(t *testing.T) { t.Fatal(err) } - container, err := GenericContainer(ctx, GenericContainerRequest{ - ContainerRequest: ContainerRequest{ + container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ + ContainerRequest: testcontainers.ContainerRequest{ Image: "docker.io/bash", - Files: []ContainerFile{ + Files: []testcontainers.ContainerFile{ { HostFilePath: absPath, ContainerFilePath: "/hello.sh", @@ -57,10 +58,10 @@ func TestCopyFileToRunningContainer(t *testing.T) { t.Fatal(err) } - container, err := GenericContainer(ctx, GenericContainerRequest{ - ContainerRequest: ContainerRequest{ + container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ + ContainerRequest: testcontainers.ContainerRequest{ Image: "docker.io/bash:5.2.26", - Files: []ContainerFile{ + Files: []testcontainers.ContainerFile{ { HostFilePath: waitForPath, ContainerFilePath: "/waitForHello.sh", @@ -98,10 +99,10 @@ func TestCopyDirectoryToContainer(t *testing.T) { t.Fatal(err) } - container, err := GenericContainer(ctx, GenericContainerRequest{ - ContainerRequest: ContainerRequest{ + container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ + ContainerRequest: testcontainers.ContainerRequest{ Image: "docker.io/bash", - Files: []ContainerFile{ + Files: []testcontainers.ContainerFile{ { HostFilePath: dataDirectory, // ContainerFile cannot create the parent directory, so we copy the scripts @@ -136,10 +137,10 @@ func TestCopyDirectoryToRunningContainerAsFile(t *testing.T) { t.Fatal(err) } - container, err := GenericContainer(ctx, GenericContainerRequest{ - ContainerRequest: ContainerRequest{ + container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ + ContainerRequest: testcontainers.ContainerRequest{ Image: "docker.io/bash", - Files: []ContainerFile{ + Files: []testcontainers.ContainerFile{ { HostFilePath: waitForPath, ContainerFilePath: "/waitForHello.sh", @@ -150,11 +151,15 @@ func TestCopyDirectoryToRunningContainerAsFile(t *testing.T) { }, Started: true, }) - require.NoError(t, err) + if err != nil { + t.Fatal(err) + } // as the container is started, we can create the directory first _, _, err = container.Exec(ctx, []string{"mkdir", "-p", "/scripts"}) - require.NoError(t, err) + if err != nil { + t.Fatal(err) + } // because the container path is a directory, it will use the copy dir method as fallback err = container.CopyFileToContainer(ctx, dataDirectory, "/scripts", 0o700) @@ -182,10 +187,10 @@ func TestCopyDirectoryToRunningContainerAsDir(t *testing.T) { t.Fatal(err) } - container, err := GenericContainer(ctx, GenericContainerRequest{ - ContainerRequest: ContainerRequest{ + container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ + ContainerRequest: testcontainers.ContainerRequest{ Image: "docker.io/bash", - Files: []ContainerFile{ + Files: []testcontainers.ContainerFile{ { HostFilePath: waitForPath, ContainerFilePath: "/waitForHello.sh", @@ -196,11 +201,15 @@ func TestCopyDirectoryToRunningContainerAsDir(t *testing.T) { }, Started: true, }) - require.NoError(t, err) + if err != nil { + t.Fatal(err) + } // as the container is started, we can create the directory first _, _, err = container.Exec(ctx, []string{"mkdir", "-p", "/scripts"}) - require.NoError(t, err) + if err != nil { + t.Fatal(err) + } err = container.CopyDirToContainer(ctx, dataDirectory, "/scripts", 0o700) if err != nil { diff --git a/docker_mounts.go b/docker_mounts.go index 4906a90692..aed3010361 100644 --- a/docker_mounts.go +++ b/docker_mounts.go @@ -81,6 +81,12 @@ func (s DockerTmpfsMountSource) GetTmpfsOptions() *mount.TmpfsOptions { return s.TmpfsOptions } +// PrepareMounts maps the given []ContainerMount to the corresponding +// []mount.Mount for further processing +func (m ContainerMounts) PrepareMounts() []mount.Mount { + return mapToDockerMounts(m) +} + // mapToDockerMounts maps the given []ContainerMount to the corresponding // []mount.Mount for further processing func mapToDockerMounts(containerMounts ContainerMounts) []mount.Mount { diff --git a/file_test.go b/file_test.go index 367e4833bc..c1fc9f0704 100644 --- a/file_test.go +++ b/file_test.go @@ -1,3 +1,5 @@ +// 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 ( diff --git a/mounts_test.go b/mounts_test.go index 6ec994c635..ecf91943dd 100644 --- a/mounts_test.go +++ b/mounts_test.go @@ -1,4 +1,4 @@ -package testcontainers +package testcontainers_test import ( "context" @@ -7,51 +7,53 @@ import ( "github.com/docker/docker/api/types/mount" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/testcontainers/testcontainers-go" ) func TestVolumeMount(t *testing.T) { t.Parallel() type args struct { volumeName string - mountTarget ContainerMountTarget + mountTarget testcontainers.ContainerMountTarget } tests := []struct { name string args args - want ContainerMount + want testcontainers.ContainerMount }{ { name: "sample-data:/data", args: args{volumeName: "sample-data", mountTarget: "/data"}, - want: ContainerMount{Source: GenericVolumeMountSource{Name: "sample-data"}, Target: "/data"}, + want: testcontainers.ContainerMount{Source: testcontainers.GenericVolumeMountSource{Name: "sample-data"}, Target: "/data"}, }, { name: "web:/var/nginx/html", args: args{volumeName: "web", mountTarget: "/var/nginx/html"}, - want: ContainerMount{Source: GenericVolumeMountSource{Name: "web"}, Target: "/var/nginx/html"}, + want: testcontainers.ContainerMount{Source: testcontainers.GenericVolumeMountSource{Name: "web"}, Target: "/var/nginx/html"}, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() - assert.Equalf(t, tt.want, VolumeMount(tt.args.volumeName, tt.args.mountTarget), "VolumeMount(%v, %v)", tt.args.volumeName, tt.args.mountTarget) + assert.Equalf(t, tt.want, testcontainers.VolumeMount(tt.args.volumeName, tt.args.mountTarget), "VolumeMount(%v, %v)", tt.args.volumeName, tt.args.mountTarget) }) } } func TestContainerMounts_PrepareMounts(t *testing.T) { volumeOptions := &mount.VolumeOptions{ - Labels: GenericLabels(), + Labels: testcontainers.GenericLabels(), } - expectedLabels := GenericLabels() + expectedLabels := testcontainers.GenericLabels() expectedLabels["hello"] = "world" t.Parallel() tests := []struct { name string - mounts ContainerMounts + mounts testcontainers.ContainerMounts want []mount.Mount }{ { @@ -61,7 +63,7 @@ func TestContainerMounts_PrepareMounts(t *testing.T) { }, { name: "Single volume mount", - mounts: ContainerMounts{{Source: GenericVolumeMountSource{Name: "app-data"}, Target: "/data"}}, + mounts: testcontainers.ContainerMounts{{Source: testcontainers.GenericVolumeMountSource{Name: "app-data"}, Target: "/data"}}, want: []mount.Mount{ { Type: mount.TypeVolume, @@ -73,7 +75,7 @@ func TestContainerMounts_PrepareMounts(t *testing.T) { }, { name: "Single volume mount - read-only", - mounts: ContainerMounts{{Source: GenericVolumeMountSource{Name: "app-data"}, Target: "/data", ReadOnly: true}}, + mounts: testcontainers.ContainerMounts{{Source: testcontainers.GenericVolumeMountSource{Name: "app-data"}, Target: "/data", ReadOnly: true}}, want: []mount.Mount{ { Type: mount.TypeVolume, @@ -86,9 +88,9 @@ func TestContainerMounts_PrepareMounts(t *testing.T) { }, { name: "Single volume mount - with options", - mounts: ContainerMounts{ + mounts: testcontainers.ContainerMounts{ { - Source: DockerVolumeMountSource{ + Source: testcontainers.DockerVolumeMountSource{ Name: "app-data", VolumeOptions: &mount.VolumeOptions{ NoCopy: true, @@ -115,7 +117,7 @@ func TestContainerMounts_PrepareMounts(t *testing.T) { { name: "Single tmpfs mount", - mounts: ContainerMounts{{Source: GenericTmpfsMountSource{}, Target: "/data"}}, + mounts: testcontainers.ContainerMounts{{Source: testcontainers.GenericTmpfsMountSource{}, Target: "/data"}}, want: []mount.Mount{ { Type: mount.TypeTmpfs, @@ -124,8 +126,8 @@ func TestContainerMounts_PrepareMounts(t *testing.T) { }, }, { - name: "Single tmpfs mount - read-only", - mounts: ContainerMounts{{Source: GenericTmpfsMountSource{}, Target: "/data", ReadOnly: true}}, + name: "Single volume mount - read-only", + mounts: testcontainers.ContainerMounts{{Source: testcontainers.GenericTmpfsMountSource{}, Target: "/data", ReadOnly: true}}, want: []mount.Mount{ { Type: mount.TypeTmpfs, @@ -136,9 +138,9 @@ func TestContainerMounts_PrepareMounts(t *testing.T) { }, { name: "Single tmpfs mount - with options", - mounts: ContainerMounts{ + mounts: testcontainers.ContainerMounts{ { - Source: DockerTmpfsMountSource{ + Source: testcontainers.DockerTmpfsMountSource{ TmpfsOptions: &mount.TmpfsOptions{ SizeBytes: 50 * 1024 * 1024, Mode: 0o644, @@ -163,18 +165,18 @@ func TestContainerMounts_PrepareMounts(t *testing.T) { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() - assert.Equalf(t, tt.want, mapToDockerMounts(tt.mounts), "PrepareMounts()") + assert.Equalf(t, tt.want, tt.mounts.PrepareMounts(), "PrepareMounts()") }) } } func TestCreateContainerWithVolume(t *testing.T) { // volumeMounts { - req := ContainerRequest{ + req := testcontainers.ContainerRequest{ Image: "alpine", - Mounts: ContainerMounts{ + Mounts: testcontainers.ContainerMounts{ { - Source: GenericVolumeMountSource{ + Source: testcontainers.GenericVolumeMountSource{ Name: "test-volume", }, Target: "/data", @@ -184,7 +186,7 @@ func TestCreateContainerWithVolume(t *testing.T) { // } ctx := context.Background() - c, err := GenericContainer(ctx, GenericContainerRequest{ + c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ ContainerRequest: req, Started: true, }) @@ -192,7 +194,7 @@ func TestCreateContainerWithVolume(t *testing.T) { terminateContainerOnEnd(t, ctx, c) // Check if volume is created - client, err := NewDockerClientWithOpts(ctx) + client, err := testcontainers.NewDockerClientWithOpts(ctx) require.NoError(t, err) defer client.Close() @@ -202,11 +204,11 @@ func TestCreateContainerWithVolume(t *testing.T) { } func TestMountsReceiveRyukLabels(t *testing.T) { - req := ContainerRequest{ + req := testcontainers.ContainerRequest{ Image: "alpine", - Mounts: ContainerMounts{ + Mounts: testcontainers.ContainerMounts{ { - Source: GenericVolumeMountSource{ + Source: testcontainers.GenericVolumeMountSource{ Name: "app-data", }, Target: "/data", @@ -215,7 +217,7 @@ func TestMountsReceiveRyukLabels(t *testing.T) { } ctx := context.Background() - c, err := GenericContainer(ctx, GenericContainerRequest{ + c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ ContainerRequest: req, Started: true, }) @@ -223,11 +225,11 @@ func TestMountsReceiveRyukLabels(t *testing.T) { terminateContainerOnEnd(t, ctx, c) // Check if volume is created with the expected labels - client, err := NewDockerClientWithOpts(ctx) + client, err := testcontainers.NewDockerClientWithOpts(ctx) require.NoError(t, err) defer client.Close() volume, err := client.VolumeInspect(ctx, "app-data") require.NoError(t, err) - assert.Equal(t, GenericLabels(), volume.Labels) + assert.Equal(t, testcontainers.GenericLabels(), volume.Labels) } diff --git a/utils_test.go b/utils_test.go new file mode 100644 index 0000000000..480cf857a3 --- /dev/null +++ b/utils_test.go @@ -0,0 +1,21 @@ +package testcontainers_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/testcontainers/testcontainers-go" +) + +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)) + }) +} From adbd26469d75351ce56a240b5910faaa13c24af1 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Thu, 29 Feb 2024 15:43:31 -0500 Subject: [PATCH 2/2] Rename the utils file --- utils_test.go => testhelpers_test.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename utils_test.go => testhelpers_test.go (100%) diff --git a/utils_test.go b/testhelpers_test.go similarity index 100% rename from utils_test.go rename to testhelpers_test.go