diff options
| author | mo khan <mo@mokhan.ca> | 2025-05-11 21:12:57 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-05-11 21:12:57 -0600 |
| commit | 60440f90dca28e99a31dd328c5f6d5dc0f9b6a2e (patch) | |
| tree | 2f54adf55086516f162f0a55a5347e6b25f7f176 /vendor/github.com/testcontainers/testcontainers-go/cleanup.go | |
| parent | 05ca9b8d3a9c7203a3a3b590beaa400900bd9007 (diff) | |
chore: vendor go dependencies
Diffstat (limited to 'vendor/github.com/testcontainers/testcontainers-go/cleanup.go')
| -rw-r--r-- | vendor/github.com/testcontainers/testcontainers-go/cleanup.go | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/vendor/github.com/testcontainers/testcontainers-go/cleanup.go b/vendor/github.com/testcontainers/testcontainers-go/cleanup.go new file mode 100644 index 0000000..bd93713 --- /dev/null +++ b/vendor/github.com/testcontainers/testcontainers-go/cleanup.go @@ -0,0 +1,123 @@ +package testcontainers + +import ( + "context" + "errors" + "fmt" + "reflect" + "time" +) + +// TerminateOptions is a type that holds the options for terminating a container. +type TerminateOptions struct { + ctx context.Context + stopTimeout *time.Duration + volumes []string +} + +// TerminateOption is a type that represents an option for terminating a container. +type TerminateOption func(*TerminateOptions) + +// NewTerminateOptions returns a fully initialised TerminateOptions. +// Defaults: StopTimeout: 10 seconds. +func NewTerminateOptions(ctx context.Context, opts ...TerminateOption) *TerminateOptions { + timeout := time.Second * 10 + options := &TerminateOptions{ + stopTimeout: &timeout, + ctx: ctx, + } + for _, opt := range opts { + opt(options) + } + return options +} + +// Context returns the context to use during a Terminate. +func (o *TerminateOptions) Context() context.Context { + return o.ctx +} + +// StopTimeout returns the stop timeout to use during a Terminate. +func (o *TerminateOptions) StopTimeout() *time.Duration { + return o.stopTimeout +} + +// Cleanup performs any clean up needed +func (o *TerminateOptions) Cleanup() error { + // TODO: simplify this when when perform the client refactor. + if len(o.volumes) == 0 { + return nil + } + client, err := NewDockerClientWithOpts(o.ctx) + if err != nil { + return fmt.Errorf("docker client: %w", err) + } + defer client.Close() + // Best effort to remove all volumes. + var errs []error + for _, volume := range o.volumes { + if errRemove := client.VolumeRemove(o.ctx, volume, true); errRemove != nil { + errs = append(errs, fmt.Errorf("volume remove %q: %w", volume, errRemove)) + } + } + return errors.Join(errs...) +} + +// StopContext returns a TerminateOption that sets the context. +// Default: context.Background(). +func StopContext(ctx context.Context) TerminateOption { + 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 *TerminateOptions) { + c.stopTimeout = &timeout + } +} + +// RemoveVolumes returns a TerminateOption that sets additional volumes to remove. +// This is useful when the container creates named volumes that should be removed +// which are not removed by default. +// Default: nil. +func RemoveVolumes(volumes ...string) TerminateOption { + return func(c *TerminateOptions) { + c.volumes = volumes + } +} + +// TerminateContainer calls [Container.Terminate] on the container if it is not nil. +// +// This should be called as a defer directly after [GenericContainer](...) +// or a modules Run(...) to ensure the container is terminated when the +// function ends. +func TerminateContainer(container Container, options ...TerminateOption) error { + if isNil(container) { + return nil + } + + err := container.Terminate(context.Background(), options...) + if !isCleanupSafe(err) { + return fmt.Errorf("terminate: %w", err) + } + + return nil +} + +// isNil returns true if val is nil or a nil instance false otherwise. +func isNil(val any) bool { + if val == nil { + return true + } + + valueOf := reflect.ValueOf(val) + switch valueOf.Kind() { + case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.UnsafePointer, reflect.Interface, reflect.Slice: + return valueOf.IsNil() + default: + return false + } +} |
