2015-04-30 18:21:49 +02:00
package remote
import (
"fmt"
"os"
"testing"
"time"
2017-01-12 22:55:42 +01:00
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/dynamodb"
2015-06-03 20:36:57 +02:00
"github.com/aws/aws-sdk-go/service/s3"
2015-04-30 18:21:49 +02:00
)
func TestS3Client_impl ( t * testing . T ) {
var _ Client = new ( S3Client )
}
func TestS3Factory ( t * testing . T ) {
// This test just instantiates the client. Shouldn't make any actual
// requests nor incur any costs.
config := make ( map [ string ] string )
// Empty config is an error
_ , err := s3Factory ( config )
if err == nil {
t . Fatalf ( "Empty config should be error" )
}
config [ "region" ] = "us-west-1"
config [ "bucket" ] = "foo"
config [ "key" ] = "bar"
2015-06-19 20:33:03 +02:00
config [ "encrypt" ] = "1"
2015-06-25 18:23:12 +02:00
2015-04-30 18:21:49 +02:00
// For this test we'll provide the credentials as config. The
// acceptance tests implicitly test passing credentials as
// environment variables.
config [ "access_key" ] = "bazkey"
config [ "secret_key" ] = "bazsecret"
client , err := s3Factory ( config )
if err != nil {
t . Fatalf ( "Error for valid config" )
}
s3Client := client . ( * S3Client )
2015-07-28 22:29:46 +02:00
if * s3Client . nativeClient . Config . Region != "us-west-1" {
2015-04-30 18:21:49 +02:00
t . Fatalf ( "Incorrect region was populated" )
}
if s3Client . bucketName != "foo" {
t . Fatalf ( "Incorrect bucketName was populated" )
}
if s3Client . keyName != "bar" {
t . Fatalf ( "Incorrect keyName was populated" )
}
2015-05-05 12:26:26 +02:00
credentials , err := s3Client . nativeClient . Config . Credentials . Get ( )
2015-04-30 18:21:49 +02:00
if err != nil {
t . Fatalf ( "Error when requesting credentials" )
}
if credentials . AccessKeyID != "bazkey" {
t . Fatalf ( "Incorrect Access Key Id was populated" )
}
if credentials . SecretAccessKey != "bazsecret" {
t . Fatalf ( "Incorrect Secret Access Key was populated" )
}
}
func TestS3Client ( t * testing . T ) {
// This test creates a bucket in S3 and populates it.
// It may incur costs, so it will only run if AWS credential environment
// variables are present.
accessKeyId := os . Getenv ( "AWS_ACCESS_KEY_ID" )
if accessKeyId == "" {
t . Skipf ( "skipping; AWS_ACCESS_KEY_ID must be set" )
}
regionName := os . Getenv ( "AWS_DEFAULT_REGION" )
if regionName == "" {
regionName = "us-west-2"
}
bucketName := fmt . Sprintf ( "terraform-remote-s3-test-%x" , time . Now ( ) . Unix ( ) )
keyName := "testState"
2015-06-19 20:33:03 +02:00
testData := [ ] byte ( ` testing data ` )
2015-04-30 18:21:49 +02:00
config := make ( map [ string ] string )
config [ "region" ] = regionName
config [ "bucket" ] = bucketName
config [ "key" ] = keyName
2015-06-19 20:33:03 +02:00
config [ "encrypt" ] = "1"
2015-04-30 18:21:49 +02:00
client , err := s3Factory ( config )
if err != nil {
t . Fatalf ( "Error for valid config" )
}
s3Client := client . ( * S3Client )
nativeClient := s3Client . nativeClient
createBucketReq := & s3 . CreateBucketInput {
Bucket : & bucketName ,
}
// Be clear about what we're doing in case the user needs to clean
// this up later.
t . Logf ( "Creating S3 bucket %s in %s" , bucketName , regionName )
_ , err = nativeClient . CreateBucket ( createBucketReq )
if err != nil {
t . Skipf ( "Failed to create test S3 bucket, so skipping" )
}
2015-06-19 20:33:03 +02:00
// Ensure we can perform a PUT request with the encryption header
err = s3Client . Put ( testData )
if err != nil {
t . Logf ( "WARNING: Failed to send test data to S3 bucket. (error was %s)" , err )
}
2015-05-05 12:26:26 +02:00
defer func ( ) {
2015-04-30 18:21:49 +02:00
deleteBucketReq := & s3 . DeleteBucketInput {
Bucket : & bucketName ,
}
_ , err := nativeClient . DeleteBucket ( deleteBucketReq )
if err != nil {
2017-01-12 22:55:42 +01:00
t . Logf ( "WARNING: Failed to delete the test S3 bucket. It may have been left in your AWS account and may incur storage charges. (error was %s)" , err )
2015-04-30 18:21:49 +02:00
}
} ( )
testClient ( t , client )
}
2017-01-12 22:55:42 +01:00
func TestS3ClientLocks ( t * testing . T ) {
// This test creates a DynamoDB table.
// It may incur costs, so it will only run if AWS credential environment
// variables are present.
accessKeyId := os . Getenv ( "AWS_ACCESS_KEY_ID" )
if accessKeyId == "" {
t . Skipf ( "skipping; AWS_ACCESS_KEY_ID must be set" )
}
regionName := os . Getenv ( "AWS_DEFAULT_REGION" )
if regionName == "" {
regionName = "us-west-2"
}
bucketName := fmt . Sprintf ( "terraform-remote-s3-lock-%x" , time . Now ( ) . Unix ( ) )
keyName := "testState"
config := make ( map [ string ] string )
config [ "region" ] = regionName
config [ "bucket" ] = bucketName
config [ "key" ] = keyName
config [ "encrypt" ] = "1"
config [ "lock_table" ] = bucketName
client , err := s3Factory ( config )
if err != nil {
t . Fatalf ( "Error for valid config" )
}
s3Client := client . ( * S3Client )
// set this up before we try to crate the table, in case we timeout creating it.
defer deleteDynaboDBTable ( t , s3Client , bucketName )
createDynamoDBTable ( t , s3Client , bucketName )
2017-02-07 16:33:05 +01:00
TestRemoteLocks ( t , client , client )
2017-01-12 22:55:42 +01:00
}
// create the dynamoDB table, and wait until we can query it.
func createDynamoDBTable ( t * testing . T , c * S3Client , tableName string ) {
createInput := & dynamodb . CreateTableInput {
AttributeDefinitions : [ ] * dynamodb . AttributeDefinition {
{
AttributeName : aws . String ( "LockID" ) ,
AttributeType : aws . String ( "S" ) ,
} ,
} ,
KeySchema : [ ] * dynamodb . KeySchemaElement {
{
AttributeName : aws . String ( "LockID" ) ,
KeyType : aws . String ( "HASH" ) ,
} ,
} ,
ProvisionedThroughput : & dynamodb . ProvisionedThroughput {
ReadCapacityUnits : aws . Int64 ( 5 ) ,
WriteCapacityUnits : aws . Int64 ( 5 ) ,
} ,
TableName : aws . String ( tableName ) ,
}
_ , err := c . dynClient . CreateTable ( createInput )
if err != nil {
t . Fatal ( err )
}
// now wait until it's ACTIVE
start := time . Now ( )
time . Sleep ( time . Second )
describeInput := & dynamodb . DescribeTableInput {
TableName : aws . String ( tableName ) ,
}
for {
resp , err := c . dynClient . DescribeTable ( describeInput )
if err != nil {
t . Fatal ( err )
}
if * resp . Table . TableStatus == "ACTIVE" {
return
}
if time . Since ( start ) > time . Minute {
t . Fatalf ( "timed out creating DynamoDB table %s" , tableName )
}
time . Sleep ( 3 * time . Second )
}
}
func deleteDynaboDBTable ( t * testing . T , c * S3Client , tableName string ) {
params := & dynamodb . DeleteTableInput {
TableName : aws . String ( tableName ) ,
}
_ , err := c . dynClient . DeleteTable ( params )
if err != nil {
t . Logf ( "WARNING: Failed to delete the test DynamoDB table %q. It has been left in your AWS account and may incur charges. (error was %s)" , tableName , err )
}
}