terraform-provider-docker/internal/provider/data_source_docker_image_test.go

204 lines
6.2 KiB
Go
Raw Normal View History

package provider
import (
"context"
"fmt"
"os/exec"
"regexp"
"strings"
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)
var imageRepoDigestRegexp = regexp.MustCompile(`^.*@sha256:[A-Fa-f0-9]+$`)
var imageNameWithTagAndDigestRegexp = regexp.MustCompile(`^.*:.*@sha256:[A-Fa-f0-9]+$`)
func TestAccDockerImageDataSource_withSpecificTag(t *testing.T) {
ctx := context.Background()
imageName := "busybox:1.35.0"
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
pullImageForTest(t, imageName)
},
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: loadTestConfiguration(t, DATA_SOURCE, "docker_image", "testAccDockerImageDataSourceWithSpecificTag"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.docker_image.foo", "name", imageName),
resource.TestCheckResourceAttr("data.docker_image.foo", "repo_digest", "busybox@sha256:a3170d3672568b2c6626710db3573f3d92ee31eed933c24f3d7ea978178e21b8"),
),
},
},
CheckDestroy: func(state *terraform.State) error {
return removeImageForTest(ctx, state, imageName)
},
})
}
func TestAccDockerImageDataSource_withDefaultTag(t *testing.T) {
ctx := context.Background()
imageName := "busybox"
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
pullImageForTest(t, imageName)
},
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: loadTestConfiguration(t, DATA_SOURCE, "docker_image", "testAccDockerImageDataSourceWithDefaultTag"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.docker_image.foo", "name", imageName),
resource.TestMatchResourceAttr("data.docker_image.foo", "repo_digest", imageRepoDigestRegexp),
),
},
},
CheckDestroy: func(state *terraform.State) error {
return removeImageForTest(ctx, state, imageName)
},
})
}
func TestAccDockerImageDataSource_withSha256Digest(t *testing.T) {
ctx := context.Background()
imageName := "busybox@sha256:8c40df61d40166f5791f44b3d90b77b4c7f59ed39a992fd9046886d3126ffa68"
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
pullImageForTest(t, imageName)
},
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: loadTestConfiguration(t, DATA_SOURCE, "docker_image", "testAccDockerImageDataSourceWithSha256Digest"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.docker_image.foo", "name", imageName),
resource.TestMatchResourceAttr("data.docker_image.foo", "repo_digest", imageRepoDigestRegexp),
),
},
},
CheckDestroy: func(state *terraform.State) error {
return removeImageForTest(ctx, state, imageName)
},
})
}
func TestAccDockerImageDataSource_withTagAndSha256Digest(t *testing.T) {
ctx := context.Background()
imageName := "busybox:1.35.0@sha256:8c40df61d40166f5791f44b3d90b77b4c7f59ed39a992fd9046886d3126ffa68"
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
pullImageForTest(t, imageName)
},
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: loadTestConfiguration(t, DATA_SOURCE, "docker_image", "testAccDockerImageDataSourceWithTagAndSha256Digest"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.docker_image.foo", "name", imageName),
resource.TestMatchResourceAttr("data.docker_image.foo", "repo_digest", imageRepoDigestRegexp),
),
},
},
CheckDestroy: func(state *terraform.State) error {
return removeImageForTest(ctx, state, imageName)
},
})
}
func TestAccDockerImageDataSource_withNonExistentImage(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: `
data "docker_image" "foo" {
name = "image-does-not-exist"
}
`,
ExpectError: regexp.MustCompile(`.*did not find docker image.*`),
},
{
Config: `
data "docker_image" "foo" {
name = "nginx:tag-does-not-exist"
}
`,
ExpectError: regexp.MustCompile(`.*did not find docker image.*`),
},
{
Config: `
data "docker_image" "foo" {
name = "nginx@sha256:3614ca5eacf0a3a1bcc361c939202a974b4902b9334ff36eb29ffe9011aaad83"
}
`,
ExpectError: regexp.MustCompile(`.*did not find docker image.*`),
},
{
Config: `
data "docker_image" "foo" {
name = "nginx:1.19.1@sha256:3614ca5eacf0a3a1bcc361c939202a974b4902b9334ff36eb29ffe9011aaad83"
}
`,
ExpectError: regexp.MustCompile(`.*did not find docker image.*`),
},
},
})
}
// Helpers
func pullImageForTest(t *testing.T, imageName string) {
cmd := exec.Command("docker", "pull", imageName)
if err := cmd.Run(); err != nil {
t.Fatalf("Failed to pull image '%s': %s", imageName, err)
}
}
func removeImageForTest(ctx context.Context, s *terraform.State, imageName string) error {
client := testAccProvider.Meta().(*ProviderConfig).DockerClient
// for images with tag and digest like e.g.
// 'nginx:1.19.1@sha256:36b74457bccb56fbf8b05f79c85569501b721d4db813b684391d63e02287c0b2'
// no image is found. This is why we strip the tag to remain with
// 'nginx@sha256:36b74457bccb56fbf8b05f79c85569501b721d4db813b684391d63e02287c0b2'
if imageNameWithTagAndDigestRegexp.MatchString(imageName) {
tagStartIndex := strings.Index(imageName, ":")
digestStartIndex := strings.Index(imageName, "@")
imageName = imageName[:tagStartIndex] + imageName[digestStartIndex:]
}
filters := filters.NewArgs()
filters.Add("reference", imageName)
images, err := client.ImageList(ctx, types.ImageListOptions{
Filters: filters,
})
if err != nil {
return err
}
if len(images) == 0 {
return fmt.Errorf("did not find any image with name '%s' to delete", imageName)
}
for _, image := range images {
_, err := client.ImageRemove(ctx, image.ID, types.ImageRemoveOptions{
Force: true,
})
if err != nil {
return fmt.Errorf("failed to remove image with ID '%s'", image.ID)
}
}
return nil
}