github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/backend/remote-state/oss/backend_test.go (about) 1 package oss 2 3 import ( 4 "fmt" 5 "os" 6 "testing" 7 "time" 8 9 "strings" 10 11 "github.com/aliyun/aliyun-oss-go-sdk/oss" 12 "github.com/aliyun/aliyun-tablestore-go-sdk/tablestore" 13 "github.com/hashicorp/terraform/backend" 14 "github.com/hashicorp/terraform/configs/hcl2shim" 15 ) 16 17 // verify that we are doing ACC tests or the OSS tests specifically 18 func testACC(t *testing.T) { 19 skip := os.Getenv("TF_ACC") == "" && os.Getenv("TF_OSS_TEST") == "" 20 if skip { 21 t.Log("oss backend tests require setting TF_ACC or TF_OSS_TEST") 22 t.Skip() 23 } 24 if skip { 25 t.Fatal("oss backend tests require setting ALICLOUD_ACCESS_KEY or ALICLOUD_ACCESS_KEY_ID") 26 } 27 if os.Getenv("ALICLOUD_REGION") == "" { 28 os.Setenv("ALICLOUD_REGION", "cn-beijing") 29 } 30 } 31 32 func TestBackend_impl(t *testing.T) { 33 var _ backend.Backend = new(Backend) 34 } 35 36 func TestBackendConfig(t *testing.T) { 37 testACC(t) 38 config := map[string]interface{}{ 39 "region": "cn-beijing", 40 "bucket": "terraform-backend-oss-test", 41 "prefix": "mystate", 42 "key": "first.tfstate", 43 "tablestore_endpoint": "https://terraformstate.cn-beijing.ots.aliyuncs.com", 44 "tablestore_table": "TableStore", 45 } 46 47 b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(config)).(*Backend) 48 49 if !strings.HasPrefix(b.ossClient.Config.Endpoint, "https://oss-cn-beijing") { 50 t.Fatalf("Incorrect region was provided") 51 } 52 if b.bucketName != "terraform-backend-oss-test" { 53 t.Fatalf("Incorrect bucketName was provided") 54 } 55 if b.statePrefix != "mystate" { 56 t.Fatalf("Incorrect state file path was provided") 57 } 58 if b.stateKey != "first.tfstate" { 59 t.Fatalf("Incorrect keyName was provided") 60 } 61 62 if b.ossClient.Config.AccessKeyID == "" { 63 t.Fatalf("No Access Key Id was provided") 64 } 65 if b.ossClient.Config.AccessKeySecret == "" { 66 t.Fatalf("No Secret Access Key was provided") 67 } 68 } 69 70 func TestBackendConfigProfile(t *testing.T) { 71 testACC(t) 72 config := map[string]interface{}{ 73 "region": "cn-beijing", 74 "bucket": "terraform-backend-oss-test", 75 "prefix": "mystate", 76 "key": "first.tfstate", 77 "tablestore_endpoint": "https://terraformstate.cn-beijing.ots.aliyuncs.com", 78 "tablestore_table": "TableStore", 79 "profile": "default", 80 } 81 82 b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(config)).(*Backend) 83 84 if !strings.HasPrefix(b.ossClient.Config.Endpoint, "https://oss-cn-beijing") { 85 t.Fatalf("Incorrect region was provided") 86 } 87 if b.bucketName != "terraform-backend-oss-test" { 88 t.Fatalf("Incorrect bucketName was provided") 89 } 90 if b.statePrefix != "mystate" { 91 t.Fatalf("Incorrect state file path was provided") 92 } 93 if b.stateKey != "first.tfstate" { 94 t.Fatalf("Incorrect keyName was provided") 95 } 96 97 if b.ossClient.Config.AccessKeyID == "" { 98 t.Fatalf("No Access Key Id was provided") 99 } 100 if b.ossClient.Config.AccessKeySecret == "" { 101 t.Fatalf("No Secret Access Key was provided") 102 } 103 } 104 105 func TestBackendConfig_invalidKey(t *testing.T) { 106 testACC(t) 107 cfg := hcl2shim.HCL2ValueFromConfigValue(map[string]interface{}{ 108 "region": "cn-beijing", 109 "bucket": "terraform-backend-oss-test", 110 "prefix": "/leading-slash", 111 "name": "/test.tfstate", 112 "tablestore_endpoint": "https://terraformstate.cn-beijing.ots.aliyuncs.com", 113 "tablestore_table": "TableStore", 114 }) 115 116 _, results := New().PrepareConfig(cfg) 117 if !results.HasErrors() { 118 t.Fatal("expected config validation error") 119 } 120 } 121 122 func TestBackend(t *testing.T) { 123 testACC(t) 124 125 bucketName := fmt.Sprintf("terraform-remote-oss-test-%x", time.Now().Unix()) 126 statePrefix := "multi/level/path/" 127 128 b1 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{ 129 "bucket": bucketName, 130 "prefix": statePrefix, 131 })).(*Backend) 132 133 b2 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{ 134 "bucket": bucketName, 135 "prefix": statePrefix, 136 })).(*Backend) 137 138 createOSSBucket(t, b1.ossClient, bucketName) 139 defer deleteOSSBucket(t, b1.ossClient, bucketName) 140 141 backend.TestBackendStates(t, b1) 142 backend.TestBackendStateLocks(t, b1, b2) 143 backend.TestBackendStateForceUnlock(t, b1, b2) 144 } 145 146 func createOSSBucket(t *testing.T, ossClient *oss.Client, bucketName string) { 147 // Be clear about what we're doing in case the user needs to clean this up later. 148 if err := ossClient.CreateBucket(bucketName); err != nil { 149 t.Fatal("failed to create test OSS bucket:", err) 150 } 151 } 152 153 func deleteOSSBucket(t *testing.T, ossClient *oss.Client, bucketName string) { 154 warning := "WARNING: Failed to delete the test OSS bucket. It may have been left in your Alibaba Cloud account and may incur storage charges. (error was %s)" 155 156 // first we have to get rid of the env objects, or we can't delete the bucket 157 bucket, err := ossClient.Bucket(bucketName) 158 if err != nil { 159 t.Fatal("Error getting bucket:", err) 160 return 161 } 162 objects, err := bucket.ListObjects() 163 if err != nil { 164 t.Logf(warning, err) 165 return 166 } 167 for _, obj := range objects.Objects { 168 if err := bucket.DeleteObject(obj.Key); err != nil { 169 // this will need cleanup no matter what, so just warn and exit 170 t.Logf(warning, err) 171 return 172 } 173 } 174 175 if err := ossClient.DeleteBucket(bucketName); err != nil { 176 t.Logf(warning, err) 177 } 178 } 179 180 // create the dynamoDB table, and wait until we can query it. 181 func createTablestoreTable(t *testing.T, otsClient *tablestore.TableStoreClient, tableName string) { 182 tableMeta := new(tablestore.TableMeta) 183 tableMeta.TableName = tableName 184 tableMeta.AddPrimaryKeyColumn("testbackend", tablestore.PrimaryKeyType_STRING) 185 186 tableOption := new(tablestore.TableOption) 187 tableOption.TimeToAlive = -1 188 tableOption.MaxVersion = 1 189 190 reservedThroughput := new(tablestore.ReservedThroughput) 191 192 _, err := otsClient.CreateTable(&tablestore.CreateTableRequest{ 193 TableMeta: tableMeta, 194 TableOption: tableOption, 195 ReservedThroughput: reservedThroughput, 196 }) 197 if err != nil { 198 t.Fatal(err) 199 } 200 } 201 202 func deleteTablestoreTable(t *testing.T, otsClient *tablestore.TableStoreClient, tableName string) { 203 params := &tablestore.DeleteTableRequest{ 204 TableName: tableName, 205 } 206 _, err := otsClient.DeleteTable(params) 207 if err != nil { 208 t.Logf("WARNING: Failed to delete the test TableStore table %q. It has been left in your Alibaba Cloud account and may incur charges. (error was %s)", tableName, err) 209 } 210 }