summaryrefslogtreecommitdiff
path: root/vendor/github.com/testcontainers/testcontainers-go/cleanup.go
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-05-11 21:12:57 -0600
committermo khan <mo@mokhan.ca>2025-05-11 21:12:57 -0600
commit60440f90dca28e99a31dd328c5f6d5dc0f9b6a2e (patch)
tree2f54adf55086516f162f0a55a5347e6b25f7f176 /vendor/github.com/testcontainers/testcontainers-go/cleanup.go
parent05ca9b8d3a9c7203a3a3b590beaa400900bd9007 (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.go123
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
+ }
+}