github.com/sathiyas/terraform@v0.6.9-0.20151210233947-3330da00b997/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 TestAccAWSDynamoDbTable_streamSpecification(t *testing.T) {
    37  	resource.Test(t, resource.TestCase{
    38  		PreCheck:     func() { testAccPreCheck(t) },
    39  		Providers:    testAccProviders,
    40  		CheckDestroy: testAccCheckAWSDynamoDbTableDestroy,
    41  		Steps: []resource.TestStep{
    42  			resource.TestStep{
    43  				Config: testAccAWSDynamoDbConfigStreamSpecification,
    44  				Check: resource.ComposeTestCheckFunc(
    45  					testAccCheckInitialAWSDynamoDbTableExists("aws_dynamodb_table.basic-dynamodb-table"),
    46  					resource.TestCheckResourceAttr(
    47  						"aws_dynamodb_table.basic-dynamodb-table", "stream_enabled", "true"),
    48  					resource.TestCheckResourceAttr(
    49  						"aws_dynamodb_table.basic-dynamodb-table", "stream_view_type", "KEYS_ONLY"),
    50  				),
    51  			},
    52  		},
    53  	})
    54  }
    55  
    56  func TestResourceAWSDynamoDbTableStreamViewType_validation(t *testing.T) {
    57  	cases := []struct {
    58  		Value    string
    59  		ErrCount int
    60  	}{
    61  		{
    62  			Value:    "KEYS-ONLY",
    63  			ErrCount: 1,
    64  		},
    65  		{
    66  			Value:    "RANDOM-STRING",
    67  			ErrCount: 1,
    68  		},
    69  		{
    70  			Value:    "KEYS_ONLY",
    71  			ErrCount: 0,
    72  		},
    73  		{
    74  			Value:    "NEW_AND_OLD_IMAGES",
    75  			ErrCount: 0,
    76  		},
    77  		{
    78  			Value:    "NEW_IMAGE",
    79  			ErrCount: 0,
    80  		},
    81  		{
    82  			Value:    "OLD_IMAGE",
    83  			ErrCount: 0,
    84  		},
    85  	}
    86  
    87  	for _, tc := range cases {
    88  		_, errors := validateStreamViewType(tc.Value, "aws_dynamodb_table_stream_view_type")
    89  
    90  		if len(errors) != tc.ErrCount {
    91  			t.Fatalf("Expected the DynamoDB stream_view_type to trigger a validation error")
    92  		}
    93  	}
    94  }
    95  
    96  func testAccCheckAWSDynamoDbTableDestroy(s *terraform.State) error {
    97  	conn := testAccProvider.Meta().(*AWSClient).dynamodbconn
    98  
    99  	for _, rs := range s.RootModule().Resources {
   100  		if rs.Type != "aws_dynamodb_table" {
   101  			continue
   102  		}
   103  
   104  		fmt.Printf("[DEBUG] Checking if DynamoDB table %s exists", rs.Primary.ID)
   105  		// Check if queue exists by checking for its attributes
   106  		params := &dynamodb.DescribeTableInput{
   107  			TableName: aws.String(rs.Primary.ID),
   108  		}
   109  		_, err := conn.DescribeTable(params)
   110  		if err == nil {
   111  			return fmt.Errorf("DynamoDB table %s still exists. Failing!", rs.Primary.ID)
   112  		}
   113  
   114  		// Verify the error is what we want
   115  		_, ok := err.(awserr.Error)
   116  		if !ok {
   117  			return err
   118  		}
   119  	}
   120  
   121  	return nil
   122  }
   123  
   124  func testAccCheckInitialAWSDynamoDbTableExists(n string) resource.TestCheckFunc {
   125  	return func(s *terraform.State) error {
   126  		fmt.Printf("[DEBUG] Trying to create initial table state!")
   127  		rs, ok := s.RootModule().Resources[n]
   128  		if !ok {
   129  			return fmt.Errorf("Not found: %s", n)
   130  		}
   131  
   132  		if rs.Primary.ID == "" {
   133  			return fmt.Errorf("No DynamoDB table name specified!")
   134  		}
   135  
   136  		conn := testAccProvider.Meta().(*AWSClient).dynamodbconn
   137  
   138  		params := &dynamodb.DescribeTableInput{
   139  			TableName: aws.String(rs.Primary.ID),
   140  		}
   141  
   142  		resp, err := conn.DescribeTable(params)
   143  
   144  		if err != nil {
   145  			fmt.Printf("[ERROR] Problem describing table '%s': %s", rs.Primary.ID, err)
   146  			return err
   147  		}
   148  
   149  		table := resp.Table
   150  
   151  		fmt.Printf("[DEBUG] Checking on table %s", rs.Primary.ID)
   152  
   153  		if *table.ProvisionedThroughput.WriteCapacityUnits != 20 {
   154  			return fmt.Errorf("Provisioned write capacity was %d, not 20!", table.ProvisionedThroughput.WriteCapacityUnits)
   155  		}
   156  
   157  		if *table.ProvisionedThroughput.ReadCapacityUnits != 10 {
   158  			return fmt.Errorf("Provisioned read capacity was %d, not 10!", table.ProvisionedThroughput.ReadCapacityUnits)
   159  		}
   160  
   161  		attrCount := len(table.AttributeDefinitions)
   162  		gsiCount := len(table.GlobalSecondaryIndexes)
   163  		lsiCount := len(table.LocalSecondaryIndexes)
   164  
   165  		if attrCount != 4 {
   166  			return fmt.Errorf("There were %d attributes, not 4 like there should have been!", attrCount)
   167  		}
   168  
   169  		if gsiCount != 1 {
   170  			return fmt.Errorf("There were %d GSIs, not 1 like there should have been!", gsiCount)
   171  		}
   172  
   173  		if lsiCount != 1 {
   174  			return fmt.Errorf("There were %d LSIs, not 1 like there should have been!", lsiCount)
   175  		}
   176  
   177  		attrmap := dynamoDbAttributesToMap(&table.AttributeDefinitions)
   178  		if attrmap["TestTableHashKey"] != "S" {
   179  			return fmt.Errorf("Test table hash key was of type %s instead of S!", attrmap["TestTableHashKey"])
   180  		}
   181  		if attrmap["TestTableRangeKey"] != "S" {
   182  			return fmt.Errorf("Test table range key was of type %s instead of S!", attrmap["TestTableRangeKey"])
   183  		}
   184  		if attrmap["TestLSIRangeKey"] != "N" {
   185  			return fmt.Errorf("Test table LSI range key was of type %s instead of N!", attrmap["TestLSIRangeKey"])
   186  		}
   187  		if attrmap["TestGSIRangeKey"] != "S" {
   188  			return fmt.Errorf("Test table GSI range key was of type %s instead of S!", attrmap["TestGSIRangeKey"])
   189  		}
   190  
   191  		return nil
   192  	}
   193  }
   194  
   195  func testAccCheckDynamoDbTableWasUpdated(n string) resource.TestCheckFunc {
   196  	return func(s *terraform.State) error {
   197  		rs, ok := s.RootModule().Resources[n]
   198  		if !ok {
   199  			return fmt.Errorf("Not found: %s", n)
   200  		}
   201  
   202  		if rs.Primary.ID == "" {
   203  			return fmt.Errorf("No DynamoDB table name specified!")
   204  		}
   205  
   206  		conn := testAccProvider.Meta().(*AWSClient).dynamodbconn
   207  
   208  		params := &dynamodb.DescribeTableInput{
   209  			TableName: aws.String(rs.Primary.ID),
   210  		}
   211  		resp, err := conn.DescribeTable(params)
   212  		table := resp.Table
   213  
   214  		if err != nil {
   215  			return err
   216  		}
   217  
   218  		attrCount := len(table.AttributeDefinitions)
   219  		gsiCount := len(table.GlobalSecondaryIndexes)
   220  		lsiCount := len(table.LocalSecondaryIndexes)
   221  
   222  		if attrCount != 4 {
   223  			return fmt.Errorf("There were %d attributes, not 4 like there should have been!", attrCount)
   224  		}
   225  
   226  		if gsiCount != 1 {
   227  			return fmt.Errorf("There were %d GSIs, not 1 like there should have been!", gsiCount)
   228  		}
   229  
   230  		if lsiCount != 1 {
   231  			return fmt.Errorf("There were %d LSIs, not 1 like there should have been!", lsiCount)
   232  		}
   233  
   234  		if dynamoDbGetGSIIndex(&table.GlobalSecondaryIndexes, "ReplacementTestTableGSI") == -1 {
   235  			return fmt.Errorf("Could not find GSI named 'ReplacementTestTableGSI' in the table!")
   236  		}
   237  
   238  		if dynamoDbGetGSIIndex(&table.GlobalSecondaryIndexes, "InitialTestTableGSI") != -1 {
   239  			return fmt.Errorf("Should have removed 'InitialTestTableGSI' but it still exists!")
   240  		}
   241  
   242  		attrmap := dynamoDbAttributesToMap(&table.AttributeDefinitions)
   243  		if attrmap["TestTableHashKey"] != "S" {
   244  			return fmt.Errorf("Test table hash key was of type %s instead of S!", attrmap["TestTableHashKey"])
   245  		}
   246  		if attrmap["TestTableRangeKey"] != "S" {
   247  			return fmt.Errorf("Test table range key was of type %s instead of S!", attrmap["TestTableRangeKey"])
   248  		}
   249  		if attrmap["TestLSIRangeKey"] != "N" {
   250  			return fmt.Errorf("Test table LSI range key was of type %s instead of N!", attrmap["TestLSIRangeKey"])
   251  		}
   252  		if attrmap["ReplacementGSIRangeKey"] != "N" {
   253  			return fmt.Errorf("Test table replacement GSI range key was of type %s instead of N!", attrmap["ReplacementGSIRangeKey"])
   254  		}
   255  
   256  		return nil
   257  	}
   258  }
   259  
   260  func dynamoDbGetGSIIndex(gsiList *[]*dynamodb.GlobalSecondaryIndexDescription, target string) int {
   261  	for idx, gsiObject := range *gsiList {
   262  		if *gsiObject.IndexName == target {
   263  			return idx
   264  		}
   265  	}
   266  
   267  	return -1
   268  }
   269  
   270  func dynamoDbAttributesToMap(attributes *[]*dynamodb.AttributeDefinition) map[string]string {
   271  	attrmap := make(map[string]string)
   272  
   273  	for _, attrdef := range *attributes {
   274  		attrmap[*attrdef.AttributeName] = *attrdef.AttributeType
   275  	}
   276  
   277  	return attrmap
   278  }
   279  
   280  const testAccAWSDynamoDbConfigInitialState = `
   281  resource "aws_dynamodb_table" "basic-dynamodb-table" {
   282      name = "TerraformTestTable"
   283  		read_capacity = 10
   284  		write_capacity = 20
   285  		hash_key = "TestTableHashKey"
   286  		range_key = "TestTableRangeKey"
   287  		attribute {
   288  			name = "TestTableHashKey"
   289  			type = "S"
   290  		}
   291  		attribute {
   292  			name = "TestTableRangeKey"
   293  			type = "S"
   294  		}
   295  		attribute {
   296  			name = "TestLSIRangeKey"
   297  			type = "N"
   298  		}
   299  		attribute {
   300  			name = "TestGSIRangeKey"
   301  			type = "S"
   302  		}
   303  		local_secondary_index {
   304  			name = "TestTableLSI"
   305  			range_key = "TestLSIRangeKey"
   306  			projection_type = "ALL"
   307  		}
   308  		global_secondary_index {
   309  			name = "InitialTestTableGSI"
   310  			hash_key = "TestTableHashKey"
   311  			range_key = "TestGSIRangeKey"
   312  			write_capacity = 10
   313  			read_capacity = 10
   314  			projection_type = "KEYS_ONLY"
   315  		}
   316  }
   317  `
   318  
   319  const testAccAWSDynamoDbConfigAddSecondaryGSI = `
   320  resource "aws_dynamodb_table" "basic-dynamodb-table" {
   321      name = "TerraformTestTable"
   322  		read_capacity = 20
   323  		write_capacity = 20
   324  		hash_key = "TestTableHashKey"
   325  		range_key = "TestTableRangeKey"
   326  		attribute {
   327  			name = "TestTableHashKey"
   328  			type = "S"
   329  		}
   330  		attribute {
   331  			name = "TestTableRangeKey"
   332  			type = "S"
   333  		}
   334  		attribute {
   335  			name = "TestLSIRangeKey"
   336  			type = "N"
   337  		}
   338  		attribute {
   339  			name = "ReplacementGSIRangeKey"
   340  			type = "N"
   341  		}
   342  		local_secondary_index {
   343  			name = "TestTableLSI"
   344  			range_key = "TestLSIRangeKey"
   345  			projection_type = "ALL"
   346  		}
   347  		global_secondary_index {
   348  			name = "ReplacementTestTableGSI"
   349  			hash_key = "TestTableHashKey"
   350  			range_key = "ReplacementGSIRangeKey"
   351  			write_capacity = 5
   352  			read_capacity = 5
   353  			projection_type = "INCLUDE"
   354  			non_key_attributes = ["TestNonKeyAttribute"]
   355  		}
   356  }
   357  `
   358  
   359  const testAccAWSDynamoDbConfigStreamSpecification = `
   360  resource "aws_dynamodb_table" "basic-dynamodb-table" {
   361      name = "TerraformTestStreamTable"
   362  	read_capacity = 10
   363  	write_capacity = 20
   364  	hash_key = "TestTableHashKey"
   365  	range_key = "TestTableRangeKey"
   366  	attribute {
   367  		name = "TestTableHashKey"
   368  		type = "S"
   369  	}
   370  	attribute {
   371  		name = "TestTableRangeKey"
   372  		type = "S"
   373  	}
   374  	attribute {
   375  		name = "TestLSIRangeKey"
   376  		type = "N"
   377  	}
   378  	attribute {
   379  		name = "TestGSIRangeKey"
   380  		type = "S"
   381  	}
   382  	local_secondary_index {
   383  		name = "TestTableLSI"
   384  		range_key = "TestLSIRangeKey"
   385  		projection_type = "ALL"
   386  	}
   387  	global_secondary_index {
   388  		name = "InitialTestTableGSI"
   389  		hash_key = "TestTableHashKey"
   390  		range_key = "TestGSIRangeKey"
   391  		write_capacity = 10
   392  		read_capacity = 10
   393  		projection_type = "KEYS_ONLY"
   394  	}
   395  	stream_enabled = true
   396  	stream_view_type = "KEYS_ONLY"
   397  }
   398  `