From 4fab35bf4b0adee9017e495786887c55ff3c303d Mon Sep 17 00:00:00 2001 From: moogacs Date: Sat, 21 Dec 2024 16:58:04 +0100 Subject: [PATCH] revert TerminateOption to terminateOptions, seperate from DockerContainer and introduce configuration test --- cleanup.go | 14 +++++++------- docker.go | 26 ++++++++++++++++---------- docker_test.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 17 deletions(-) diff --git a/cleanup.go b/cleanup.go index 714e3d087d..ccdcc31528 100644 --- a/cleanup.go +++ b/cleanup.go @@ -15,21 +15,21 @@ type terminateOptions struct { } // TerminateOption is a type that represents an option for terminating a container. -type TerminateOption func(*DockerContainer) +type TerminateOption func(*terminateOptions) // StopContext returns a TerminateOption that sets the context. // Default: context.Background(). func StopContext(ctx context.Context) TerminateOption { - return func(c *DockerContainer) { - c.terminationOptions.ctx = ctx + return func(c *terminateOptions) { + c.ctx = ctx } } // StopTimeout returns a TerminateOption that sets the timeout. // Default: See [Container.Stop]. func StopTimeout(timeout time.Duration) TerminateOption { - return func(c *DockerContainer) { - c.terminationOptions.timeout = &timeout + return func(c *terminateOptions) { + c.timeout = &timeout } } @@ -38,8 +38,8 @@ func StopTimeout(timeout time.Duration) TerminateOption { // which are not removed by default. // Default: nil. func RemoveVolumes(volumes ...string) TerminateOption { - return func(c *DockerContainer) { - c.terminationOptions.volumes = volumes + return func(c *terminateOptions) { + c.volumes = volumes } } diff --git a/docker.go b/docker.go index 68c74cc9e4..9f0285b64e 100644 --- a/docker.go +++ b/docker.go @@ -89,7 +89,6 @@ type DockerContainer struct { logProductionCtx context.Context logProductionTimeout *time.Duration - terminationOptions terminateOptions logger Logging lifecycleHooks []ContainerLifecycleHooks @@ -299,8 +298,15 @@ func (c *DockerContainer) Stop(ctx context.Context, timeout *time.Duration) erro // WithTerminateTimeout is a functional option that sets the timeout for the container termination. func WithTerminateTimeout(timeout time.Duration) TerminateOption { - return func(c *DockerContainer) { - c.terminationOptions.timeout = &timeout + return func(c *terminateOptions) { + c.timeout = &timeout + } +} + +// WithTerminateVolumes is a functional option that sets the volumes for the container termination. +func WithTerminateVolumes(volumes ...string) TerminateOption { + return func(opts *terminateOptions) { + opts.volumes = volumes } } @@ -314,16 +320,16 @@ func WithTerminateTimeout(timeout time.Duration) TerminateOption { // // Default: timeout is 10 seconds. func (c *DockerContainer) Terminate(ctx context.Context, opts ...TerminateOption) error { - if len(opts) == 0 { - d := 10 * time.Second - c.terminationOptions.timeout = &d + defaultTimeout := 10 * time.Second + options := &terminateOptions{ + timeout: &defaultTimeout, } for _, opt := range opts { - opt(c) + opt(options) } - err := c.Stop(ctx, c.terminationOptions.timeout) + err := c.Stop(ctx, options.timeout) if err != nil && !isCleanupSafe(err) { return fmt.Errorf("stop: %w", err) } @@ -359,7 +365,7 @@ func (c *DockerContainer) Terminate(ctx context.Context, opts ...TerminateOption c.isRunning = false // Remove additional volumes if any. - if len(c.terminationOptions.volumes) == 0 { + if len(options.volumes) == 0 { return nil } @@ -371,7 +377,7 @@ func (c *DockerContainer) Terminate(ctx context.Context, opts ...TerminateOption defer client.Close() // Best effort to remove all volumes. - for _, volume := range c.terminationOptions.volumes { + for _, volume := range options.volumes { if errRemove := client.VolumeRemove(ctx, volume, true); errRemove != nil { errs = append(errs, fmt.Errorf("volume remove %q: %w", volume, errRemove)) } diff --git a/docker_test.go b/docker_test.go index 58cabb0f21..d49d4b053b 100644 --- a/docker_test.go +++ b/docker_test.go @@ -1108,6 +1108,56 @@ func TestContainerCreationWithVolumeAndFileWritingToIt(t *testing.T) { require.NoError(t, err) } +func TestContainerCreationWithVolumeCleaning(t *testing.T) { + absPath, err := filepath.Abs(filepath.Join(".", "testdata", "hello.sh")) + require.NoError(t, err) + ctx, cnl := context.WithTimeout(context.Background(), 30*time.Second) + defer cnl() + + // Create the volume. + volumeName := "volumeName" + + // Create the container that writes into the mounted volume. + bashC, err := GenericContainer(ctx, GenericContainerRequest{ + ProviderType: providerType, + ContainerRequest: ContainerRequest{ + Image: "bash:5.2.26", + Files: []ContainerFile{ + { + HostFilePath: absPath, + ContainerFilePath: "/hello.sh", + }, + }, + Mounts: Mounts(VolumeMount(volumeName, "/data")), + Cmd: []string{"bash", "/hello.sh"}, + WaitingFor: wait.ForLog("done"), + }, + Started: true, + }) + require.NoError(t, err) + err = bashC.Terminate(ctx, WithTerminateVolumes(volumeName)) + require.NoError(t, err) +} + +func TestContainerTerminationOptions(t *testing.T) { + volumeName := "volumeName" + definedVolumeOpt := &terminateOptions{} + volumeOpt := WithTerminateVolumes(volumeName) + volumeOpt(definedVolumeOpt) + require.Equal(t, definedVolumeOpt.volumes, []string{volumeName}) + + defaultTimeout := 10 * time.Second + definedTimeoutOpt := &terminateOptions{ + timeout: &defaultTimeout, + } + + configuredTimeout := 1 * time.Second + + timeoutOpt := WithTerminateTimeout(1 * time.Second) + timeoutOpt(definedTimeoutOpt) + require.Equal(t, *definedTimeoutOpt.timeout, configuredTimeout) +} + func TestContainerWithTmpFs(t *testing.T) { ctx := context.Background() req := ContainerRequest{