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 `