terraform/backend/remote-state/oss/backend_test.go

135 lines
3.6 KiB
Go

package oss
import (
"fmt"
"os"
"testing"
"time"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/config/hcl2shim"
"strings"
)
// verify that we are doing ACC tests or the OSS tests specifically
func testACC(t *testing.T) {
skip := os.Getenv("TF_ACC") == "" && os.Getenv("TF_OSS_TEST") == ""
if skip {
t.Log("oss backend tests require setting TF_ACC or TF_OSS_TEST")
t.Skip()
}
if os.Getenv("ALICLOUD_REGION") == "" {
os.Setenv("ALICLOUD_REGION", "cn-beijing")
}
}
func TestBackend_impl(t *testing.T) {
var _ backend.Backend = new(Backend)
}
func TestBackendConfig(t *testing.T) {
testACC(t)
config := map[string]interface{}{
"region": "cn-beijing",
"bucket": "terraform-backend-oss-test",
"path": "mystate",
"name": "first.tfstate",
}
b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(config)).(*Backend)
if !strings.HasPrefix(b.ossClient.Config.Endpoint, "http://oss-cn-beijing") {
t.Fatalf("Incorrect region was provided")
}
if b.bucketName != "terraform-backend-oss-test" {
t.Fatalf("Incorrect bucketName was provided")
}
if b.statePath != "mystate" {
t.Fatalf("Incorrect state file path was provided")
}
if b.stateName != "first.tfstate" {
t.Fatalf("Incorrect keyName was provided")
}
if b.ossClient.Config.AccessKeyID == "" {
t.Fatalf("No Access Key Id was provided")
}
if b.ossClient.Config.AccessKeySecret == "" {
t.Fatalf("No Secret Access Key was provided")
}
}
func TestBackendConfig_invalidKey(t *testing.T) {
testACC(t)
cfg := hcl2shim.HCL2ValueFromConfigValue(map[string]interface{}{
"region": "cn-beijing",
"bucket": "terraform-backend-oss-test",
"path": "/leading-slash",
"name": "/test.tfstate",
})
_, results := New().PrepareConfig(cfg)
if !results.HasErrors() {
t.Fatal("expected config validation error")
}
}
func TestBackend(t *testing.T) {
testACC(t)
bucketName := fmt.Sprintf("terraform-remote-oss-test-%x", time.Now().Unix())
statePath := "multi/level/path/"
b1 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
"bucket": bucketName,
"path": statePath,
})).(*Backend)
b2 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
"bucket": bucketName,
"path": statePath,
})).(*Backend)
createOSSBucket(t, b1.ossClient, bucketName)
defer deleteOSSBucket(t, b1.ossClient, bucketName)
backend.TestBackendStates(t, b1)
backend.TestBackendStateLocks(t, b1, b2)
backend.TestBackendStateForceUnlock(t, b1, b2)
}
func createOSSBucket(t *testing.T, ossClient *oss.Client, bucketName string) {
// Be clear about what we're doing in case the user needs to clean this up later.
if err := ossClient.CreateBucket(bucketName); err != nil {
t.Fatal("failed to create test OSS bucket:", err)
}
}
func deleteOSSBucket(t *testing.T, ossClient *oss.Client, bucketName string) {
warning := "WARNING: Failed to delete the test OSS bucket. It may have been left in your Alicloud account and may incur storage charges. (error was %s)"
// first we have to get rid of the env objects, or we can't delete the bucket
bucket, err := ossClient.Bucket(bucketName)
if err != nil {
t.Fatal("Error getting bucket:", err)
return
}
objects, err := bucket.ListObjects()
if err != nil {
t.Logf(warning, err)
return
}
for _, obj := range objects.Objects {
if err := bucket.DeleteObject(obj.Key); err != nil {
// this will need cleanup no matter what, so just warn and exit
t.Logf(warning, err)
return
}
}
if err := ossClient.DeleteBucket(bucketName); err != nil {
t.Logf(warning, err)
}
}