testcontainers / testcontainers-go

Testcontainers for Go is a Go package that makes it simple to create and clean up container-based dependencies for automated integration/smoke tests. The clean, easy-to-use API enables developers to programmatically define containers that should be run as part of a test and clean up those resources when the test is done.
https://golang.testcontainers.org
MIT License
3.57k stars 492 forks source link

[Bug]: Cannot create Snapshot without providing snapshot name in postgres #2821

Open torchsec-roni opened 6 days ago

torchsec-roni commented 6 days ago

Testcontainers version

37cc44b1c25154aa15ba91f8a444566098c2a248

Using the latest Testcontainers version?

Yes

Host OS

MacOS Sequoia 15.0

Host arch

ARM

Go version

1.23.2

Docker version

Client: Version: 27.2.0 API version: 1.47 Go version: go1.21.13 Git commit: 3ab4256 Built: Tue Aug 27 14:14:45 2024 OS/Arch: darwin/arm64 Context: desktop-linux

Server: Docker Desktop 4.34.3 (170107) Engine: Version: 27.2.0 API version: 1.47 (minimum version 1.24) Go version: go1.21.13 Git commit: 3ab5c7d Built: Tue Aug 27 14:15:41 2024 OS/Arch: linux/arm64 Experimental: false containerd: Version: 1.7.20 GitCommit: 8fc6bcff51318944179630522a095cc9dbf9f353 runc: Version: 1.1.13 GitCommit: v1.1.13-0-g58aa920 docker-init: Version: 0.19.0 GitCommit: de40ad0

Docker info

Client: Version: 27.2.0 Context: desktop-linux Debug Mode: false Plugins: buildx: Docker Buildx (Docker Inc.) Version: v0.16.2-desktop.1 Path: /Users/ronilichtman/.docker/cli-plugins/docker-buildx compose: Docker Compose (Docker Inc.) Version: v2.29.2-desktop.2 Path: /Users/ronilichtman/.docker/cli-plugins/docker-compose debug: Get a shell into any image or container (Docker Inc.) Version: 0.0.34 Path: /Users/ronilichtman/.docker/cli-plugins/docker-debug desktop: Docker Desktop commands (Alpha) (Docker Inc.) Version: v0.0.15 Path: /Users/ronilichtman/.docker/cli-plugins/docker-desktop dev: Docker Dev Environments (Docker Inc.) Version: v0.1.2 Path: /Users/ronilichtman/.docker/cli-plugins/docker-dev extension: Manages Docker extensions (Docker Inc.) Version: v0.2.25 Path: /Users/ronilichtman/.docker/cli-plugins/docker-extension feedback: Provide feedback, right in your terminal! (Docker Inc.) Version: v1.0.5 Path: /Users/ronilichtman/.docker/cli-plugins/docker-feedback init: Creates Docker-related starter files for your project (Docker Inc.) Version: v1.3.0 Path: /Users/ronilichtman/.docker/cli-plugins/docker-init sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc.) Version: 0.6.0 Path: /Users/ronilichtman/.docker/cli-plugins/docker-sbom scout: Docker Scout (Docker Inc.) Version: v1.13.0 Path: /Users/ronilichtman/.docker/cli-plugins/docker-scout

Server: Containers: 1 Running: 1 Paused: 0 Stopped: 0 Images: 460 Server Version: 27.2.0 Storage Driver: overlay2 Backing Filesystem: extfs Supports d_type: true Using metacopy: false Native Overlay Diff: true userxattr: false Logging Driver: json-file Cgroup Driver: cgroupfs Cgroup Version: 2 Plugins: Volume: local Network: bridge host ipvlan macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog Swarm: inactive Runtimes: io.containerd.runc.v2 runc Default Runtime: runc Init Binary: docker-init containerd version: 8fc6bcff51318944179630522a095cc9dbf9f353 runc version: v1.1.13-0-g58aa920 init version: de40ad0 Security Options: seccomp Profile: unconfined cgroupns Kernel Version: 6.10.4-linuxkit Operating System: Docker Desktop OSType: linux Architecture: aarch64 CPUs: 11 Total Memory: 10.69GiB Name: docker-desktop ID: 37501d53-78ee-4145-a6aa-7ae6bf8c3d63 Docker Root Dir: /var/lib/docker Debug Mode: false HTTP Proxy: http.docker.internal:3128 HTTPS Proxy: http.docker.internal:3128 No Proxy: hubproxy.docker.internal Labels: com.docker.desktop.address=unix:///Users/ronilichtman/Library/Containers/com.docker.docker/Data/docker-cli.sock Experimental: false Insecure Registries: hubproxy.docker.internal:5555 127.0.0.0/8 Live Restore Enabled: false

WARNING: daemon is not using the default seccomp profile

What happened?

See the comment on the call to Snapshot below:

func TestDefaultSnapshot(t *testing.T) {
    ctx := context.Background()

    dbName := "users"
    dbUser := "user"
    dbPassword := "password"

    postgresContainer, err := postgres.Run(ctx,
        "docker.io/postgres:16-alpine",
        postgres.WithDatabase(dbName),
        postgres.WithUsername(dbUser),
        postgres.WithPassword(dbPassword),
        postgres.BasicWaitStrategies(),
    )
    defer func() {
        if err := testcontainers.TerminateContainer(postgresContainer); err != nil {
            log.Printf("failed to terminate container: %s", err)
        }
    }()
    if err != nil {
        log.Printf("failed to start container: %s", err)
        return
    }

    // Despite the following comment on the Snapshot method, it does not work:
    // "By default, the snapshot will be created under a database called migrated_template."
    // Instead, we get the following error:
    // `Failed to snapshot test DB: non-zero exit code for restore command: ~ERROR:  zero-length delimited identifier at or near """"
    //  LINE 1: DROP DATABASE IF EXISTS ""`
    err = postgresContainer.Snapshot(ctx)
    if err != nil {
        log.Fatalf("Failed to snapshot test DB: %v", err)
    }
}

Relevant log output

Failed to snapshot test DB: non-zero exit code for restore command: ~ERROR:  zero-length delimited identifier at or near """"
LINE 1: DROP DATABASE IF EXISTS ""

Additional information

See https://github.com/torchsec-roni/public-playground/blob/main/testcontainers/my_test.go

stevenh commented 13 hours ago

I can't reproduce this @torchsec-roni with the following test case, could you check if this is still an issue:

func TestDefaultSnapshot(t *testing.T) {
    ctx := context.Background()

    ctr, err := postgres.Run(ctx, "docker.io/postgres:16-alpine",
        postgres.WithDatabase("users"),
        postgres.BasicWaitStrategies(),
    )
    testcontainers.CleanupContainer(t, ctr)
    require.NoError(t, err)

    err = ctr.Snapshot(ctx)
    require.NoError(t, err)
}