terraform/internal/backend/remote-state/cos/backend_test.go

257 lines
5.9 KiB
Go

package cos
import (
"crypto/md5"
"fmt"
"os"
"testing"
"time"
"github.com/hashicorp/terraform/internal/backend"
"github.com/hashicorp/terraform/internal/states/remote"
)
const (
defaultPrefix = ""
defaultKey = "terraform.tfstate"
)
// Testing Thanks to GCS
func TestStateFile(t *testing.T) {
t.Parallel()
cases := []struct {
prefix string
stateName string
key string
wantStateFile string
wantLockFile string
}{
{"", "default", "default.tfstate", "default.tfstate", "default.tfstate.tflock"},
{"", "default", "test.tfstate", "test.tfstate", "test.tfstate.tflock"},
{"", "dev", "test.tfstate", "dev/test.tfstate", "dev/test.tfstate.tflock"},
{"terraform/test", "default", "default.tfstate", "terraform/test/default.tfstate", "terraform/test/default.tfstate.tflock"},
{"terraform/test", "default", "test.tfstate", "terraform/test/test.tfstate", "terraform/test/test.tfstate.tflock"},
{"terraform/test", "dev", "test.tfstate", "terraform/test/dev/test.tfstate", "terraform/test/dev/test.tfstate.tflock"},
}
for _, c := range cases {
t.Run(fmt.Sprintf("%s %s %s", c.prefix, c.key, c.stateName), func(t *testing.T) {
b := &Backend{
prefix: c.prefix,
key: c.key,
}
if got, want := b.stateFile(c.stateName), c.wantStateFile; got != want {
t.Errorf("wrong state file name\ngot: %s\nwant: %s", got, want)
}
if got, want := b.lockFile(c.stateName), c.wantLockFile; got != want {
t.Errorf("wrong lock file name\ngot: %s\nwant: %s", got, want)
}
})
}
}
func TestRemoteClient(t *testing.T) {
t.Parallel()
bucket := bucketName(t)
be := setupBackend(t, bucket, defaultPrefix, defaultKey, false)
defer teardownBackend(t, be)
ss, err := be.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
rs, ok := ss.(*remote.State)
if !ok {
t.Fatalf("wrong state manager type\ngot: %T\nwant: %T", ss, rs)
}
remote.TestClient(t, rs.Client)
}
func TestRemoteClientWithPrefix(t *testing.T) {
t.Parallel()
prefix := "prefix/test"
bucket := bucketName(t)
be := setupBackend(t, bucket, prefix, defaultKey, false)
defer teardownBackend(t, be)
ss, err := be.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
rs, ok := ss.(*remote.State)
if !ok {
t.Fatalf("wrong state manager type\ngot: %T\nwant: %T", ss, rs)
}
remote.TestClient(t, rs.Client)
}
func TestRemoteClientWithEncryption(t *testing.T) {
t.Parallel()
bucket := bucketName(t)
be := setupBackend(t, bucket, defaultPrefix, defaultKey, true)
defer teardownBackend(t, be)
ss, err := be.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
rs, ok := ss.(*remote.State)
if !ok {
t.Fatalf("wrong state manager type\ngot: %T\nwant: %T", ss, rs)
}
remote.TestClient(t, rs.Client)
}
func TestRemoteLocks(t *testing.T) {
t.Parallel()
bucket := bucketName(t)
be := setupBackend(t, bucket, defaultPrefix, defaultKey, false)
defer teardownBackend(t, be)
remoteClient := func() (remote.Client, error) {
ss, err := be.StateMgr(backend.DefaultStateName)
if err != nil {
return nil, err
}
rs, ok := ss.(*remote.State)
if !ok {
return nil, fmt.Errorf("be.StateMgr(): got a %T, want a *remote.State", ss)
}
return rs.Client, nil
}
c0, err := remoteClient()
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
c1, err := remoteClient()
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
remote.TestRemoteLocks(t, c0, c1)
}
func TestBackend(t *testing.T) {
t.Parallel()
bucket := bucketName(t)
be0 := setupBackend(t, bucket, defaultPrefix, defaultKey, false)
defer teardownBackend(t, be0)
be1 := setupBackend(t, bucket, defaultPrefix, defaultKey, false)
defer teardownBackend(t, be1)
backend.TestBackendStates(t, be0)
backend.TestBackendStateLocks(t, be0, be1)
backend.TestBackendStateForceUnlock(t, be0, be1)
}
func TestBackendWithPrefix(t *testing.T) {
t.Parallel()
prefix := "prefix/test"
bucket := bucketName(t)
be0 := setupBackend(t, bucket, prefix, defaultKey, false)
defer teardownBackend(t, be0)
be1 := setupBackend(t, bucket, prefix+"/", defaultKey, false)
defer teardownBackend(t, be1)
backend.TestBackendStates(t, be0)
backend.TestBackendStateLocks(t, be0, be1)
}
func TestBackendWithEncryption(t *testing.T) {
t.Parallel()
bucket := bucketName(t)
be0 := setupBackend(t, bucket, defaultPrefix, defaultKey, true)
defer teardownBackend(t, be0)
be1 := setupBackend(t, bucket, defaultPrefix, defaultKey, true)
defer teardownBackend(t, be1)
backend.TestBackendStates(t, be0)
backend.TestBackendStateLocks(t, be0, be1)
}
func setupBackend(t *testing.T, bucket, prefix, key string, encrypt bool) backend.Backend {
t.Helper()
skip := os.Getenv("TF_COS_APPID") == ""
if skip {
t.Skip("This test require setting TF_COS_APPID environment variables")
}
if os.Getenv(PROVIDER_REGION) == "" {
os.Setenv(PROVIDER_REGION, "ap-guangzhou")
}
appId := os.Getenv("TF_COS_APPID")
region := os.Getenv(PROVIDER_REGION)
config := map[string]interface{}{
"region": region,
"bucket": bucket + appId,
"prefix": prefix,
"key": key,
}
b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(config))
be := b.(*Backend)
c, err := be.client("tencentcloud")
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
err = c.putBucket()
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
return b
}
func teardownBackend(t *testing.T, b backend.Backend) {
t.Helper()
c, err := b.(*Backend).client("tencentcloud")
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
err = c.deleteBucket(true)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
}
func bucketName(t *testing.T) string {
unique := fmt.Sprintf("%s-%x", t.Name(), time.Now().UnixNano())
return fmt.Sprintf("terraform-test-%s-%s", fmt.Sprintf("%x", md5.Sum([]byte(unique)))[:10], "")
}