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  }