github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/aws/resource_aws_dynamodb_table_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/aws/aws-sdk-go/aws"
     8  	"github.com/aws/aws-sdk-go/aws/awserr"
     9  	"github.com/aws/aws-sdk-go/service/dynamodb"
    10  	"github.com/hashicorp/terraform/helper/resource"
    11  	"github.com/hashicorp/terraform/terraform"
    12  )
    13  
    14  func TestAccAWSDynamoDbTable(t *testing.T) {
    15  	resource.Test(t, resource.TestCase{
    16  		PreCheck:     func() { testAccPreCheck(t) },
    17  		Providers:    testAccProviders,
    18  		CheckDestroy: testAccCheckAWSDynamoDbTableDestroy,
    19  		Steps: []resource.TestStep{
    20  			resource.TestStep{
    21  				Config: testAccAWSDynamoDbConfigInitialState,
    22  				Check: resource.ComposeTestCheckFunc(
    23  					testAccCheckInitialAWSDynamoDbTableExists("aws_dynamodb_table.basic-dynamodb-table"),
    24  				),
    25  			},
    26  			resource.TestStep{
    27  				Config: testAccAWSDynamoDbConfigAddSecondaryGSI,
    28  				Check: resource.ComposeTestCheckFunc(
    29  					testAccCheckDynamoDbTableWasUpdated("aws_dynamodb_table.basic-dynamodb-table"),
    30  				),
    31  			},
    32  		},
    33  	})
    34  }
    35  
    36  func testAccCheckAWSDynamoDbTableDestroy(s *terraform.State) error {
    37  	conn := testAccProvider.Meta().(*AWSClient).dynamodbconn
    38  
    39  	for _, rs := range s.RootModule().Resources {
    40  		if rs.Type != "aws_dynamodb_table" {
    41  			continue
    42  		}
    43  
    44  		fmt.Printf("[DEBUG] Checking if DynamoDB table %s exists", rs.Primary.ID)
    45  		// Check if queue exists by checking for its attributes
    46  		params := &dynamodb.DescribeTableInput{
    47  			TableName: aws.String(rs.Primary.ID),
    48  		}
    49  		_, err := conn.DescribeTable(params)
    50  		if err == nil {
    51  			return fmt.Errorf("DynamoDB table %s still exists. Failing!", rs.Primary.ID)
    52  		}
    53  
    54  		// Verify the error is what we want
    55  		_, ok := err.(awserr.Error)
    56  		if !ok {
    57  			return err
    58  		}
    59  	}
    60  
    61  	return nil
    62  }
    63  
    64  func testAccCheckInitialAWSDynamoDbTableExists(n string) resource.TestCheckFunc {
    65  	return func(s *terraform.State) error {
    66  		fmt.Printf("[DEBUG] Trying to create initial table state!")
    67  		rs, ok := s.RootModule().Resources[n]
    68  		if !ok {
    69  			return fmt.Errorf("Not found: %s", n)
    70  		}
    71  
    72  		if rs.Primary.ID == "" {
    73  			return fmt.Errorf("No DynamoDB table name specified!")
    74  		}
    75  
    76  		conn := testAccProvider.Meta().(*AWSClient).dynamodbconn
    77  
    78  		params := &dynamodb.DescribeTableInput{
    79  			TableName: aws.String(rs.Primary.ID),
    80  		}
    81  
    82  		resp, err := conn.DescribeTable(params)
    83  
    84  		if err != nil {
    85  			fmt.Printf("[ERROR] Problem describing table '%s': %s", rs.Primary.ID, err)
    86  			return err
    87  		}
    88  
    89  		table := resp.Table
    90  
    91  		fmt.Printf("[DEBUG] Checking on table %s", rs.Primary.ID)
    92  
    93  		if *table.ProvisionedThroughput.WriteCapacityUnits != 20 {
    94  			return fmt.Errorf("Provisioned write capacity was %d, not 20!", table.ProvisionedThroughput.WriteCapacityUnits)
    95  		}
    96  
    97  		if *table.ProvisionedThroughput.ReadCapacityUnits != 10 {
    98  			return fmt.Errorf("Provisioned read capacity was %d, not 10!", table.ProvisionedThroughput.ReadCapacityUnits)
    99  		}
   100  
   101  		attrCount := len(table.AttributeDefinitions)
   102  		gsiCount := len(table.GlobalSecondaryIndexes)
   103  		lsiCount := len(table.LocalSecondaryIndexes)
   104  
   105  		if attrCount != 4 {
   106  			return fmt.Errorf("There were %d attributes, not 4 like there should have been!", attrCount)
   107  		}
   108  
   109  		if gsiCount != 1 {
   110  			return fmt.Errorf("There were %d GSIs, not 1 like there should have been!", gsiCount)
   111  		}
   112  
   113  		if lsiCount != 1 {
   114  			return fmt.Errorf("There were %d LSIs, not 1 like there should have been!", lsiCount)
   115  		}
   116  
   117  		attrmap := dynamoDbAttributesToMap(&table.AttributeDefinitions)
   118  		if attrmap["TestTableHashKey"] != "S" {
   119  			return fmt.Errorf("Test table hash key was of type %s instead of S!", attrmap["TestTableHashKey"])
   120  		}
   121  		if attrmap["TestTableRangeKey"] != "S" {
   122  			return fmt.Errorf("Test table range key was of type %s instead of S!", attrmap["TestTableRangeKey"])
   123  		}
   124  		if attrmap["TestLSIRangeKey"] != "N" {
   125  			return fmt.Errorf("Test table LSI range key was of type %s instead of N!", attrmap["TestLSIRangeKey"])
   126  		}
   127  		if attrmap["TestGSIRangeKey"] != "S" {
   128  			return fmt.Errorf("Test table GSI range key was of type %s instead of S!", attrmap["TestGSIRangeKey"])
   129  		}
   130  
   131  		return nil
   132  	}
   133  }
   134  
   135  func testAccCheckDynamoDbTableWasUpdated(n string) resource.TestCheckFunc {
   136  	return func(s *terraform.State) error {
   137  		rs, ok := s.RootModule().Resources[n]
   138  		if !ok {
   139  			return fmt.Errorf("Not found: %s", n)
   140  		}
   141  
   142  		if rs.Primary.ID == "" {
   143  			return fmt.Errorf("No DynamoDB table name specified!")
   144  		}
   145  
   146  		conn := testAccProvider.Meta().(*AWSClient).dynamodbconn
   147  
   148  		params := &dynamodb.DescribeTableInput{
   149  			TableName: aws.String(rs.Primary.ID),
   150  		}
   151  		resp, err := conn.DescribeTable(params)
   152  		table := resp.Table
   153  
   154  		if err != nil {
   155  			return err
   156  		}
   157  
   158  		attrCount := len(table.AttributeDefinitions)
   159  		gsiCount := len(table.GlobalSecondaryIndexes)
   160  		lsiCount := len(table.LocalSecondaryIndexes)
   161  
   162  		if attrCount != 4 {
   163  			return fmt.Errorf("There were %d attributes, not 4 like there should have been!", attrCount)
   164  		}
   165  
   166  		if gsiCount != 1 {
   167  			return fmt.Errorf("There were %d GSIs, not 1 like there should have been!", gsiCount)
   168  		}
   169  
   170  		if lsiCount != 1 {
   171  			return fmt.Errorf("There were %d LSIs, not 1 like there should have been!", lsiCount)
   172  		}
   173  
   174  		if dynamoDbGetGSIIndex(&table.GlobalSecondaryIndexes, "ReplacementTestTableGSI") == -1 {
   175  			return fmt.Errorf("Could not find GSI named 'ReplacementTestTableGSI' in the table!")
   176  		}
   177  
   178  		if dynamoDbGetGSIIndex(&table.GlobalSecondaryIndexes, "InitialTestTableGSI") != -1 {
   179  			return fmt.Errorf("Should have removed 'InitialTestTableGSI' but it still exists!")
   180  		}
   181  
   182  		attrmap := dynamoDbAttributesToMap(&table.AttributeDefinitions)
   183  		if attrmap["TestTableHashKey"] != "S" {
   184  			return fmt.Errorf("Test table hash key was of type %s instead of S!", attrmap["TestTableHashKey"])
   185  		}
   186  		if attrmap["TestTableRangeKey"] != "S" {
   187  			return fmt.Errorf("Test table range key was of type %s instead of S!", attrmap["TestTableRangeKey"])
   188  		}
   189  		if attrmap["TestLSIRangeKey"] != "N" {
   190  			return fmt.Errorf("Test table LSI range key was of type %s instead of N!", attrmap["TestLSIRangeKey"])
   191  		}
   192  		if attrmap["ReplacementGSIRangeKey"] != "N" {
   193  			return fmt.Errorf("Test table replacement GSI range key was of type %s instead of N!", attrmap["ReplacementGSIRangeKey"])
   194  		}
   195  
   196  		return nil
   197  	}
   198  }
   199  
   200  func dynamoDbGetGSIIndex(gsiList *[]*dynamodb.GlobalSecondaryIndexDescription, target string) int {
   201  	for idx, gsiObject := range *gsiList {
   202  		if *gsiObject.IndexName == target {
   203  			return idx
   204  		}
   205  	}
   206  
   207  	return -1
   208  }
   209  
   210  func dynamoDbAttributesToMap(attributes *[]*dynamodb.AttributeDefinition) map[string]string {
   211  	attrmap := make(map[string]string)
   212  
   213  	for _, attrdef := range *attributes {
   214  		attrmap[*attrdef.AttributeName] = *attrdef.AttributeType
   215  	}
   216  
   217  	return attrmap
   218  }
   219  
   220  const testAccAWSDynamoDbConfigInitialState = `
   221  resource "aws_dynamodb_table" "basic-dynamodb-table" {
   222      name = "TerraformTestTable"
   223  		read_capacity = 10
   224  		write_capacity = 20
   225  		hash_key = "TestTableHashKey"
   226  		range_key = "TestTableRangeKey"
   227  		attribute {
   228  			name = "TestTableHashKey"
   229  			type = "S"
   230  		}
   231  		attribute {
   232  			name = "TestTableRangeKey"
   233  			type = "S"
   234  		}
   235  		attribute {
   236  			name = "TestLSIRangeKey"
   237  			type = "N"
   238  		}
   239  		attribute {
   240  			name = "TestGSIRangeKey"
   241  			type = "S"
   242  		}
   243  		local_secondary_index {
   244  			name = "TestTableLSI"
   245  			range_key = "TestLSIRangeKey"
   246  			projection_type = "ALL"
   247  		}
   248  		global_secondary_index {
   249  			name = "InitialTestTableGSI"
   250  			hash_key = "TestTableHashKey"
   251  			range_key = "TestGSIRangeKey"
   252  			write_capacity = 10
   253  			read_capacity = 10
   254  			projection_type = "KEYS_ONLY"
   255  		}
   256  }
   257  `
   258  
   259  const testAccAWSDynamoDbConfigAddSecondaryGSI = `
   260  resource "aws_dynamodb_table" "basic-dynamodb-table" {
   261      name = "TerraformTestTable"
   262  		read_capacity = 20
   263  		write_capacity = 20
   264  		hash_key = "TestTableHashKey"
   265  		range_key = "TestTableRangeKey"
   266  		attribute {
   267  			name = "TestTableHashKey"
   268  			type = "S"
   269  		}
   270  		attribute {
   271  			name = "TestTableRangeKey"
   272  			type = "S"
   273  		}
   274  		attribute {
   275  			name = "TestLSIRangeKey"
   276  			type = "N"
   277  		}
   278  		attribute {
   279  			name = "ReplacementGSIRangeKey"
   280  			type = "N"
   281  		}
   282  		local_secondary_index {
   283  			name = "TestTableLSI"
   284  			range_key = "TestLSIRangeKey"
   285  			projection_type = "ALL"
   286  		}
   287  		global_secondary_index {
   288  			name = "ReplacementTestTableGSI"
   289  			hash_key = "TestTableHashKey"
   290  			range_key = "ReplacementGSIRangeKey"
   291  			write_capacity = 5
   292  			read_capacity = 5
   293  			projection_type = "INCLUDE"
   294  			non_key_attributes = ["TestNonKeyAttribute"]
   295  		}
   296  }
   297  `