github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/backend/remote-state/cos/backend_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package cos
     5  
     6  import (
     7  	"crypto/md5"
     8  	"fmt"
     9  	"os"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/terramate-io/tf/backend"
    14  	"github.com/terramate-io/tf/states/remote"
    15  )
    16  
    17  const (
    18  	defaultPrefix = ""
    19  	defaultKey    = "terraform.tfstate"
    20  )
    21  
    22  // Testing Thanks to GCS
    23  
    24  func TestStateFile(t *testing.T) {
    25  	t.Parallel()
    26  
    27  	cases := []struct {
    28  		prefix        string
    29  		stateName     string
    30  		key           string
    31  		wantStateFile string
    32  		wantLockFile  string
    33  	}{
    34  		{"", "default", "default.tfstate", "default.tfstate", "default.tfstate.tflock"},
    35  		{"", "default", "test.tfstate", "test.tfstate", "test.tfstate.tflock"},
    36  		{"", "dev", "test.tfstate", "dev/test.tfstate", "dev/test.tfstate.tflock"},
    37  		{"terraform/test", "default", "default.tfstate", "terraform/test/default.tfstate", "terraform/test/default.tfstate.tflock"},
    38  		{"terraform/test", "default", "test.tfstate", "terraform/test/test.tfstate", "terraform/test/test.tfstate.tflock"},
    39  		{"terraform/test", "dev", "test.tfstate", "terraform/test/dev/test.tfstate", "terraform/test/dev/test.tfstate.tflock"},
    40  	}
    41  
    42  	for _, c := range cases {
    43  		t.Run(fmt.Sprintf("%s %s %s", c.prefix, c.key, c.stateName), func(t *testing.T) {
    44  			b := &Backend{
    45  				prefix: c.prefix,
    46  				key:    c.key,
    47  			}
    48  			if got, want := b.stateFile(c.stateName), c.wantStateFile; got != want {
    49  				t.Errorf("wrong state file name\ngot:  %s\nwant: %s", got, want)
    50  			}
    51  			if got, want := b.lockFile(c.stateName), c.wantLockFile; got != want {
    52  				t.Errorf("wrong lock file name\ngot:  %s\nwant: %s", got, want)
    53  			}
    54  		})
    55  	}
    56  }
    57  
    58  func TestRemoteClient(t *testing.T) {
    59  	t.Parallel()
    60  
    61  	bucket := bucketName(t)
    62  
    63  	be := setupBackend(t, bucket, defaultPrefix, defaultKey, false)
    64  	defer teardownBackend(t, be)
    65  
    66  	ss, err := be.StateMgr(backend.DefaultStateName)
    67  	if err != nil {
    68  		t.Fatalf("unexpected error: %s", err)
    69  	}
    70  
    71  	rs, ok := ss.(*remote.State)
    72  	if !ok {
    73  		t.Fatalf("wrong state manager type\ngot:  %T\nwant: %T", ss, rs)
    74  	}
    75  
    76  	remote.TestClient(t, rs.Client)
    77  }
    78  
    79  func TestRemoteClientWithPrefix(t *testing.T) {
    80  	t.Parallel()
    81  
    82  	prefix := "prefix/test"
    83  	bucket := bucketName(t)
    84  
    85  	be := setupBackend(t, bucket, prefix, defaultKey, false)
    86  	defer teardownBackend(t, be)
    87  
    88  	ss, err := be.StateMgr(backend.DefaultStateName)
    89  	if err != nil {
    90  		t.Fatalf("unexpected error: %s", err)
    91  	}
    92  
    93  	rs, ok := ss.(*remote.State)
    94  	if !ok {
    95  		t.Fatalf("wrong state manager type\ngot:  %T\nwant: %T", ss, rs)
    96  	}
    97  
    98  	remote.TestClient(t, rs.Client)
    99  }
   100  
   101  func TestRemoteClientWithEncryption(t *testing.T) {
   102  	t.Parallel()
   103  
   104  	bucket := bucketName(t)
   105  
   106  	be := setupBackend(t, bucket, defaultPrefix, defaultKey, true)
   107  	defer teardownBackend(t, be)
   108  
   109  	ss, err := be.StateMgr(backend.DefaultStateName)
   110  	if err != nil {
   111  		t.Fatalf("unexpected error: %s", err)
   112  	}
   113  
   114  	rs, ok := ss.(*remote.State)
   115  	if !ok {
   116  		t.Fatalf("wrong state manager type\ngot:  %T\nwant: %T", ss, rs)
   117  	}
   118  
   119  	remote.TestClient(t, rs.Client)
   120  }
   121  
   122  func TestRemoteLocks(t *testing.T) {
   123  	t.Parallel()
   124  
   125  	bucket := bucketName(t)
   126  
   127  	be := setupBackend(t, bucket, defaultPrefix, defaultKey, false)
   128  	defer teardownBackend(t, be)
   129  
   130  	remoteClient := func() (remote.Client, error) {
   131  		ss, err := be.StateMgr(backend.DefaultStateName)
   132  		if err != nil {
   133  			return nil, err
   134  		}
   135  
   136  		rs, ok := ss.(*remote.State)
   137  		if !ok {
   138  			return nil, fmt.Errorf("be.StateMgr(): got a %T, want a *remote.State", ss)
   139  		}
   140  
   141  		return rs.Client, nil
   142  	}
   143  
   144  	c0, err := remoteClient()
   145  	if err != nil {
   146  		t.Fatalf("unexpected error: %s", err)
   147  	}
   148  
   149  	c1, err := remoteClient()
   150  	if err != nil {
   151  		t.Fatalf("unexpected error: %s", err)
   152  	}
   153  
   154  	remote.TestRemoteLocks(t, c0, c1)
   155  }
   156  
   157  func TestBackend(t *testing.T) {
   158  	t.Parallel()
   159  
   160  	bucket := bucketName(t)
   161  
   162  	be0 := setupBackend(t, bucket, defaultPrefix, defaultKey, false)
   163  	defer teardownBackend(t, be0)
   164  
   165  	be1 := setupBackend(t, bucket, defaultPrefix, defaultKey, false)
   166  	defer teardownBackend(t, be1)
   167  
   168  	backend.TestBackendStates(t, be0)
   169  	backend.TestBackendStateLocks(t, be0, be1)
   170  	backend.TestBackendStateForceUnlock(t, be0, be1)
   171  }
   172  
   173  func TestBackendWithPrefix(t *testing.T) {
   174  	t.Parallel()
   175  
   176  	prefix := "prefix/test"
   177  	bucket := bucketName(t)
   178  
   179  	be0 := setupBackend(t, bucket, prefix, defaultKey, false)
   180  	defer teardownBackend(t, be0)
   181  
   182  	be1 := setupBackend(t, bucket, prefix+"/", defaultKey, false)
   183  	defer teardownBackend(t, be1)
   184  
   185  	backend.TestBackendStates(t, be0)
   186  	backend.TestBackendStateLocks(t, be0, be1)
   187  }
   188  
   189  func TestBackendWithEncryption(t *testing.T) {
   190  	t.Parallel()
   191  
   192  	bucket := bucketName(t)
   193  
   194  	be0 := setupBackend(t, bucket, defaultPrefix, defaultKey, true)
   195  	defer teardownBackend(t, be0)
   196  
   197  	be1 := setupBackend(t, bucket, defaultPrefix, defaultKey, true)
   198  	defer teardownBackend(t, be1)
   199  
   200  	backend.TestBackendStates(t, be0)
   201  	backend.TestBackendStateLocks(t, be0, be1)
   202  }
   203  
   204  func setupBackend(t *testing.T, bucket, prefix, key string, encrypt bool) backend.Backend {
   205  	t.Helper()
   206  
   207  	skip := os.Getenv("TF_COS_APPID") == ""
   208  	if skip {
   209  		t.Skip("This test require setting TF_COS_APPID environment variables")
   210  	}
   211  
   212  	if os.Getenv(PROVIDER_REGION) == "" {
   213  		os.Setenv(PROVIDER_REGION, "ap-guangzhou")
   214  	}
   215  
   216  	appId := os.Getenv("TF_COS_APPID")
   217  	region := os.Getenv(PROVIDER_REGION)
   218  
   219  	config := map[string]interface{}{
   220  		"region": region,
   221  		"bucket": bucket + appId,
   222  		"prefix": prefix,
   223  		"key":    key,
   224  	}
   225  
   226  	b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(config))
   227  	be := b.(*Backend)
   228  
   229  	c, err := be.client("tencentcloud")
   230  	if err != nil {
   231  		t.Fatalf("unexpected error: %s", err)
   232  	}
   233  
   234  	err = c.putBucket()
   235  	if err != nil {
   236  		t.Fatalf("unexpected error: %s", err)
   237  	}
   238  
   239  	return b
   240  }
   241  
   242  func teardownBackend(t *testing.T, b backend.Backend) {
   243  	t.Helper()
   244  
   245  	c, err := b.(*Backend).client("tencentcloud")
   246  	if err != nil {
   247  		t.Fatalf("unexpected error: %s", err)
   248  	}
   249  
   250  	err = c.deleteBucket(true)
   251  	if err != nil {
   252  		t.Fatalf("unexpected error: %s", err)
   253  	}
   254  }
   255  
   256  func bucketName(t *testing.T) string {
   257  	unique := fmt.Sprintf("%s-%x", t.Name(), time.Now().UnixNano())
   258  	return fmt.Sprintf("terraform-test-%s-%s", fmt.Sprintf("%x", md5.Sum([]byte(unique)))[:10], "")
   259  }