2019-03-07 11:31:36 +01:00
package oss
import (
"fmt"
"os"
"testing"
"time"
2019-09-26 17:30:52 +02:00
"strings"
2019-03-07 11:31:36 +01:00
"github.com/aliyun/aliyun-oss-go-sdk/oss"
2019-04-11 01:11:10 +02:00
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore"
2021-05-17 17:42:17 +02:00
"github.com/hashicorp/terraform/internal/backend"
2021-05-17 21:17:09 +02:00
"github.com/hashicorp/terraform/internal/configs/hcl2shim"
2019-03-07 11:31:36 +01:00
)
// 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 ( )
}
2019-09-26 17:30:52 +02:00
if skip {
t . Fatal ( "oss backend tests require setting ALICLOUD_ACCESS_KEY or ALICLOUD_ACCESS_KEY_ID" )
}
2019-03-07 11:31:36 +01:00
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 { } {
2019-04-11 01:11:10 +02:00
"region" : "cn-beijing" ,
"bucket" : "terraform-backend-oss-test" ,
"prefix" : "mystate" ,
"key" : "first.tfstate" ,
"tablestore_endpoint" : "https://terraformstate.cn-beijing.ots.aliyuncs.com" ,
"tablestore_table" : "TableStore" ,
2019-03-07 11:31:36 +01:00
}
b := backend . TestBackendConfig ( t , New ( ) , backend . TestWrapConfig ( config ) ) . ( * Backend )
2019-08-06 04:35:51 +02:00
if ! strings . HasPrefix ( b . ossClient . Config . Endpoint , "https://oss-cn-beijing" ) {
2020-07-21 05:18:00 +02:00
t . Fatalf ( "Incorrect region was provided" )
}
if b . bucketName != "terraform-backend-oss-test" {
t . Fatalf ( "Incorrect bucketName was provided" )
}
if b . statePrefix != "mystate" {
t . Fatalf ( "Incorrect state file path was provided" )
}
if b . stateKey != "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 TestBackendConfigWorkSpace ( t * testing . T ) {
testACC ( t )
config := map [ string ] interface { } {
"region" : "cn-beijing" ,
"bucket" : "terraform-backend-oss-test" ,
"prefix" : "mystate" ,
"key" : "first.tfstate" ,
"tablestore_endpoint" : "https://terraformstate.cn-beijing.ots.aliyuncs.com" ,
"tablestore_table" : "TableStore" ,
}
b := backend . TestBackendConfig ( t , New ( ) , backend . TestWrapConfig ( config ) ) . ( * Backend )
createOSSBucket ( t , b . ossClient , "terraform-backend-oss-test" )
defer deleteOSSBucket ( t , b . ossClient , "terraform-backend-oss-test" )
if _ , err := b . Workspaces ( ) ; err != nil {
t . Fatal ( err . Error ( ) )
}
if ! strings . HasPrefix ( b . ossClient . Config . Endpoint , "https://oss-cn-beijing" ) {
2019-08-06 04:35:51 +02:00
t . Fatalf ( "Incorrect region was provided" )
}
if b . bucketName != "terraform-backend-oss-test" {
t . Fatalf ( "Incorrect bucketName was provided" )
}
if b . statePrefix != "mystate" {
t . Fatalf ( "Incorrect state file path was provided" )
}
if b . stateKey != "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 TestBackendConfigProfile ( t * testing . T ) {
testACC ( t )
config := map [ string ] interface { } {
"region" : "cn-beijing" ,
"bucket" : "terraform-backend-oss-test" ,
"prefix" : "mystate" ,
"key" : "first.tfstate" ,
"tablestore_endpoint" : "https://terraformstate.cn-beijing.ots.aliyuncs.com" ,
"tablestore_table" : "TableStore" ,
"profile" : "default" ,
}
b := backend . TestBackendConfig ( t , New ( ) , backend . TestWrapConfig ( config ) ) . ( * Backend )
2019-03-07 11:31:36 +01:00
2019-04-11 01:11:10 +02:00
if ! strings . HasPrefix ( b . ossClient . Config . Endpoint , "https://oss-cn-beijing" ) {
2019-03-07 11:31:36 +01:00
t . Fatalf ( "Incorrect region was provided" )
}
if b . bucketName != "terraform-backend-oss-test" {
t . Fatalf ( "Incorrect bucketName was provided" )
}
2019-04-11 01:11:10 +02:00
if b . statePrefix != "mystate" {
2019-03-07 11:31:36 +01:00
t . Fatalf ( "Incorrect state file path was provided" )
}
2019-04-11 01:11:10 +02:00
if b . stateKey != "first.tfstate" {
2019-03-07 11:31:36 +01:00
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 { } {
2019-04-11 01:11:10 +02:00
"region" : "cn-beijing" ,
"bucket" : "terraform-backend-oss-test" ,
"prefix" : "/leading-slash" ,
"name" : "/test.tfstate" ,
"tablestore_endpoint" : "https://terraformstate.cn-beijing.ots.aliyuncs.com" ,
"tablestore_table" : "TableStore" ,
2019-03-07 11:31:36 +01:00
} )
_ , 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 ( ) )
2019-04-11 01:11:10 +02:00
statePrefix := "multi/level/path/"
2019-03-07 11:31:36 +01:00
b1 := backend . TestBackendConfig ( t , New ( ) , backend . TestWrapConfig ( map [ string ] interface { } {
"bucket" : bucketName ,
2019-04-11 01:11:10 +02:00
"prefix" : statePrefix ,
2019-03-07 11:31:36 +01:00
} ) ) . ( * Backend )
b2 := backend . TestBackendConfig ( t , New ( ) , backend . TestWrapConfig ( map [ string ] interface { } {
"bucket" : bucketName ,
2019-04-11 01:11:10 +02:00
"prefix" : statePrefix ,
2019-03-07 11:31:36 +01:00
} ) ) . ( * 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 ) {
2019-07-30 17:26:51 +02:00
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)"
2019-03-07 11:31:36 +01:00
// 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 )
}
}
2019-04-11 01:11:10 +02:00
2020-02-18 14:45:06 +01:00
// create the tablestore table, and wait until we can query it.
2019-04-11 01:11:10 +02:00
func createTablestoreTable ( t * testing . T , otsClient * tablestore . TableStoreClient , tableName string ) {
tableMeta := new ( tablestore . TableMeta )
tableMeta . TableName = tableName
2020-02-18 18:47:15 +01:00
tableMeta . AddPrimaryKeyColumn ( pkName , tablestore . PrimaryKeyType_STRING )
2019-04-11 01:11:10 +02:00
tableOption := new ( tablestore . TableOption )
tableOption . TimeToAlive = - 1
tableOption . MaxVersion = 1
reservedThroughput := new ( tablestore . ReservedThroughput )
_ , err := otsClient . CreateTable ( & tablestore . CreateTableRequest {
TableMeta : tableMeta ,
TableOption : tableOption ,
ReservedThroughput : reservedThroughput ,
} )
if err != nil {
t . Fatal ( err )
}
}
func deleteTablestoreTable ( t * testing . T , otsClient * tablestore . TableStoreClient , tableName string ) {
params := & tablestore . DeleteTableRequest {
TableName : tableName ,
}
_ , err := otsClient . DeleteTable ( params )
if err != nil {
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 )
}
}