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 }