terraform-provider-docker/internal/provider/resource_docker_plugin_test.go
Manuel Vogel 0588c2071b
chore/refactor tests (#201)
* chore: format test configs for datasources

* chore: outlines load test config helper and structure

* docs(contributing): add command for resouce tests

to have an example of the regex

* refactor: move container test configs into separate files

* fix: add insecure_skip_verify for image pulls

to fix the local test setup with invalid certs

* chore(ci): remove insecure registry adaption

* chore: regenerate website

* chore: update gitignore for scipts/testing dir

* fix: replace nodejs services with go versions

* fix: move testing program versions in separate files

* test: reactivate flaky test from travis

* chore: fix linter on all go files

* fix(linter): testing go servers

* chore(ci): add env for go version

* chore(ci): name workflow steps

also moves description of available docker versions in to acc dockerfile

* Revert "test: reactivate flaky test from travis"

This reverts commit b02654acc4d6b7d02c8f3ba090e6a3f248741b10.

* docs: fix provider-ssh example

* chore: use alpine als final image for tests

* refactor: move test configs from folder into testname.tf files

* refactor: image delete log is now debug and indented

* refactor: image test config into seprate files

* refactor: move network test config into seperate files

* refactor: move plugin test config into seperate files

* chore: rename registry image test file

* refactor: move registry_image test config into seperate files

* chore: format secret test configs

* refactor: inline volume test configs

* fix: remove unused volume label test function

* refactor: move service test configs into seperate files

* test: reactivate and fix service test

* chore: simplify insecure skip verify add to http client

* chore(ci): debug into service test

* chore(ci): add testacc setup

* chore: format tf config for provider test

* chore(ci): add debug output for config.json

* fix: check service auth for emptyness

* fix: remove re-read of provider auth config

because the bug occured only in CI as the meta object might be GCd

* test: pass auth to service instead of provider

* chore: reactivate all acc tests

* test: outlines service inspect json check for full spec

* test: add service inspect json checks

* test: finish service inspect json checks

* chore(service): move test helper to end to of the file

* chore: move mapEquals to test helpers

* test: add json inspect for config

* chore: add debug inspect log for plugin, secret and volume

* test: add json inspect for secret

* test: add json inspect for image

* test: add json inspect for network

* test: add json inspect for plugin

* test: add json inspect for volume

* test: inline ds plugin test configs

* test: inline network configs

* test: move ds reg image configs into separate files

* test: reactivates container upload checks

* chore: adapt issues ref from old to new xw repo

* fix: reactivate network ingress test

and provide helpers for removing the default ingress network and leaving the swamr

* docs: rerun website gen

* test: fix reg image build and keep test

* chore: add name to todo

* chore: move ds network and plugin specs to file

* chore: format provider test spec

* chore: use simpler error message for empty strings
2021-05-31 16:11:49 +09:00

409 lines
12 KiB
Go

package provider
import (
"context"
"fmt"
"reflect"
"testing"
"github.com/docker/docker/api/types"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)
func Test_getDockerPluginEnv(t *testing.T) {
t.Parallel()
data := []struct {
title string
src interface{}
exp []string
}{
{
title: "nil",
},
{
title: "basic",
src: schema.NewSet(schema.HashString, []interface{}{"DEBUG=1"}),
exp: []string{"DEBUG=1"},
},
}
for _, d := range data {
d := d
t.Run(d.title, func(t *testing.T) {
t.Parallel()
envs := getDockerPluginEnv(d.src)
if !reflect.DeepEqual(d.exp, envs) {
t.Fatalf("want %v, got %v", d.exp, envs)
}
})
}
}
func Test_complementTag(t *testing.T) {
t.Parallel()
data := []struct {
title string
image string
exp string
}{
{
title: "alpine:3.11.6",
image: "alpine:3.11.6",
exp: "alpine:3.11.6",
},
{
title: "alpine",
image: "alpine",
exp: "alpine:latest",
},
}
for _, d := range data {
d := d
t.Run(d.title, func(t *testing.T) {
t.Parallel()
image := complementTag(d.image)
if image != d.exp {
t.Fatalf("want %v, got %v", d.exp, image)
}
})
}
}
func Test_normalizePluginName(t *testing.T) {
t.Parallel()
data := []struct {
title string
image string
isErr bool
exp string
}{
{
title: "alpine:3.11.6",
image: "alpine:3.11.6",
exp: "docker.io/library/alpine:3.11.6",
},
{
title: "alpine",
image: "alpine",
exp: "docker.io/library/alpine:latest",
},
{
title: "vieux/sshfs",
image: "vieux/sshfs",
exp: "docker.io/vieux/sshfs:latest",
},
{
title: "docker.io/vieux/sshfs:latest",
image: "docker.io/vieux/sshfs:latest",
exp: "docker.io/vieux/sshfs:latest",
},
{
title: "docker.io/vieux/sshfs",
image: "docker.io/vieux/sshfs",
exp: "docker.io/vieux/sshfs:latest",
},
}
for _, d := range data {
d := d
t.Run(d.title, func(t *testing.T) {
t.Parallel()
image, err := normalizePluginName(d.image)
if d.isErr {
if err == nil {
t.Fatal("error should be returned")
}
return
}
if err != nil {
t.Fatal(err)
}
if image != d.exp {
t.Fatalf("want %v, got %v", d.exp, image)
}
})
}
}
func Test_getDockerPluginGrantPermissions(t *testing.T) {
t.Parallel()
data := []struct {
title string
src interface{}
privileges types.PluginPrivileges
exp bool
isErr bool
}{
{
title: "no privilege",
src: schema.NewSet(dockerPluginGrantPermissionsSetFunc, []interface{}{
map[string]interface{}{
"name": "network",
"value": schema.NewSet(schema.HashString, []interface{}{"host"}),
},
}),
exp: true,
},
{
title: "basic",
src: schema.NewSet(dockerPluginGrantPermissionsSetFunc, []interface{}{
map[string]interface{}{
"name": "network",
"value": schema.NewSet(schema.HashString, []interface{}{"host"}),
},
}),
privileges: types.PluginPrivileges{
{
Name: "network",
Value: []string{"host"},
},
},
exp: true,
},
{
title: "permission denied 1",
src: schema.NewSet(dockerPluginGrantPermissionsSetFunc, []interface{}{
map[string]interface{}{
"name": "network",
"value": schema.NewSet(schema.HashString, []interface{}{
"host",
}),
},
}),
privileges: types.PluginPrivileges{
{
Name: "device",
Value: []string{"/dev/fuse"},
},
},
exp: false,
},
{
title: "permission denied 2",
src: schema.NewSet(dockerPluginGrantPermissionsSetFunc, []interface{}{
map[string]interface{}{
"name": "network",
"value": schema.NewSet(schema.HashString, []interface{}{
"host",
}),
},
map[string]interface{}{
"name": "mount",
"value": schema.NewSet(schema.HashString, []interface{}{
"/var/lib/docker/plugins/",
}),
},
}),
privileges: types.PluginPrivileges{
{
Name: "network",
Value: []string{"host"},
},
{
Name: "mount",
Value: []string{"", "/var/lib/docker/plugins/"},
},
},
exp: false,
},
}
for _, d := range data {
d := d
t.Run(d.title, func(t *testing.T) {
t.Parallel()
f := getDockerPluginGrantPermissions(d.src)
b, err := f(d.privileges)
if d.isErr {
if err == nil {
t.Fatal("error must be returned")
}
return
}
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(d.exp, b) {
t.Fatalf("want %v, got %v", d.exp, b)
}
})
}
}
func TestAccDockerPlugin_basic(t *testing.T) {
const resourceName = "docker_plugin.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
ResourceName: resourceName,
Config: loadTestConfiguration(t, RESOURCE, "docker_plugin", "testAccDockerPluginMinimum"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "name", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "plugin_reference", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "alias", "tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "enabled", "true"),
),
},
{
ResourceName: resourceName,
Config: loadTestConfiguration(t, RESOURCE, "docker_plugin", "testAccDockerPluginAlias"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "name", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "plugin_reference", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "alias", "sample:latest"),
resource.TestCheckResourceAttr(resourceName, "enabled", "true"),
),
},
{
ResourceName: resourceName,
Config: loadTestConfiguration(t, RESOURCE, "docker_plugin", "testAccDockerPluginDisableWhenSet"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "name", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "plugin_reference", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "alias", "sample:latest"),
resource.TestCheckResourceAttr(resourceName, "enabled", "true"),
resource.TestCheckResourceAttr(resourceName, "grant_all_permissions", "true"),
resource.TestCheckResourceAttr(resourceName, "force_destroy", "true"),
resource.TestCheckResourceAttr(resourceName, "enable_timeout", "60"),
),
},
{
ResourceName: resourceName,
Config: loadTestConfiguration(t, RESOURCE, "docker_plugin", "testAccDockerPluginDisabled"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "name", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "plugin_reference", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "alias", "sample:latest"),
resource.TestCheckResourceAttr(resourceName, "enabled", "false"),
resource.TestCheckResourceAttr(resourceName, "grant_all_permissions", "true"),
resource.TestCheckResourceAttr(resourceName, "force_destroy", "true"),
resource.TestCheckResourceAttr(resourceName, "enable_timeout", "60"),
resource.TestCheckResourceAttr(resourceName, "force_disable", "true"),
),
},
{
ResourceName: resourceName,
ImportState: true,
},
},
})
}
func TestAccDockerPlugin_full(t *testing.T) {
const resourceName = "docker_plugin.test"
var p types.Plugin
testCheckPluginInspect := func(*terraform.State) error {
if p.Enabled != false {
return fmt.Errorf("Plugin Enabled is wrong: %v", p.Enabled)
}
return nil
}
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
ResourceName: resourceName,
Config: loadTestConfiguration(t, RESOURCE, "docker_plugin", "testAccDockerPluginFull"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "name", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "plugin_reference", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "alias", "sample:latest"),
resource.TestCheckResourceAttr(resourceName, "enabled", "false"),
resource.TestCheckResourceAttr(resourceName, "force_destroy", "true"),
resource.TestCheckResourceAttr(resourceName, "enable_timeout", "60"),
resource.TestCheckResourceAttr(resourceName, "force_disable", "true"),
resource.TestCheckResourceAttr(resourceName, "env.#", "1"),
resource.TestCheckResourceAttr(resourceName, "env.0", "DEBUG=1"),
resource.TestCheckResourceAttr(resourceName, "grant_permissions.#", "1"),
resource.TestCheckResourceAttr(resourceName, "grant_permissions.0.name", "network"),
resource.TestCheckResourceAttr(resourceName, "grant_permissions.0.value.#", "1"),
resource.TestCheckResourceAttr(resourceName, "grant_permissions.0.value.0", "host"),
testAccPluginCreated(resourceName, &p),
testCheckPluginInspect,
),
},
{
ResourceName: resourceName,
ImportState: true,
},
},
})
}
func TestAccDockerPlugin_grantAllPermissions(t *testing.T) {
const resourceName = "docker_plugin.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
ResourceName: resourceName,
Config: loadTestConfiguration(t, RESOURCE, "docker_plugin", "testAccDockerPluginGrantAllPermissions"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "name", "docker.io/vieux/sshfs:latest"),
resource.TestCheckResourceAttr(resourceName, "plugin_reference", "docker.io/vieux/sshfs:latest"),
resource.TestCheckResourceAttr(resourceName, "alias", "vieux/sshfs:latest"),
resource.TestCheckResourceAttr(resourceName, "grant_all_permissions", "true"),
),
},
{
ResourceName: resourceName,
ImportState: true,
},
},
})
}
func TestAccDockerPlugin_grantPermissions(t *testing.T) {
const resourceName = "docker_plugin.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
ResourceName: resourceName,
Config: loadTestConfiguration(t, RESOURCE, "docker_plugin", "testAccDockerPluginGrantPermissions"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "name", "docker.io/vieux/sshfs:latest"),
resource.TestCheckResourceAttr(resourceName, "plugin_reference", "docker.io/vieux/sshfs:latest"),
resource.TestCheckResourceAttr(resourceName, "alias", "vieux/sshfs:latest"),
),
},
{
ResourceName: resourceName,
ImportState: true,
},
},
})
}
func testAccPluginCreated(resourceName string, plugin *types.Plugin) resource.TestCheckFunc {
return func(s *terraform.State) error {
ctx := context.Background()
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return fmt.Errorf("Resource with name '%s' not found in state", resourceName)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No ID is set")
}
client := testAccProvider.Meta().(*ProviderConfig).DockerClient
inspectedPlugin, _, err := client.PluginInspectWithRaw(ctx, rs.Primary.ID)
if err != nil {
return fmt.Errorf("Plugin with ID '%s': %w", rs.Primary.ID, err)
}
// we set the value to the pointer to be able to use the value
// outside of the function
plugin = inspectedPlugin
return nil
}
}