From 4de4590147c743ab2c6ac6e971a342e07da79f49 Mon Sep 17 00:00:00 2001 From: Paul Stack Date: Tue, 16 Aug 2016 20:42:06 +0100 Subject: [PATCH] provider/aws: Adds acceptance tests for `aws_gateway_*` manual deletions causing non-empty plans (#7879) * provider/aws: Adds an acceptance test that makes sure that manual deletions mean a non-empty plan * provider/aws: Adds an acceptance test to prove that manual deletion causes a non-empty plan --- .../aws/resource_aws_customer_gateway_test.go | 75 +++++++++++++++--- .../aws/resource_aws_vpn_gateway_test.go | 77 +++++++++++++++++++ 2 files changed, 141 insertions(+), 11 deletions(-) diff --git a/builtin/providers/aws/resource_aws_customer_gateway_test.go b/builtin/providers/aws/resource_aws_customer_gateway_test.go index 3009e9714..311fe746d 100644 --- a/builtin/providers/aws/resource_aws_customer_gateway_test.go +++ b/builtin/providers/aws/resource_aws_customer_gateway_test.go @@ -3,6 +3,7 @@ package aws import ( "fmt" "testing" + "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" @@ -13,6 +14,7 @@ import ( ) func TestAccAWSCustomerGateway_basic(t *testing.T) { + var gateway ec2.CustomerGateway resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, IDRefreshName: "aws_customer_gateway.foo", @@ -22,31 +24,75 @@ func TestAccAWSCustomerGateway_basic(t *testing.T) { resource.TestStep{ Config: testAccCustomerGatewayConfig, Check: resource.ComposeTestCheckFunc( - testAccCheckCustomerGateway( - "aws_customer_gateway.foo", - ), + testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway), ), }, resource.TestStep{ Config: testAccCustomerGatewayConfigUpdateTags, Check: resource.ComposeTestCheckFunc( - testAccCheckCustomerGateway( - "aws_customer_gateway.foo", - ), + testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway), ), }, resource.TestStep{ Config: testAccCustomerGatewayConfigForceReplace, Check: resource.ComposeTestCheckFunc( - testAccCheckCustomerGateway( - "aws_customer_gateway.foo", - ), + testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway), ), }, }, }) } +func TestAccAWSCustomerGateway_disappears(t *testing.T) { + var gateway ec2.CustomerGateway + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCustomerGatewayDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCustomerGatewayConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway), + testAccAWSCustomerGatewayDisappears(&gateway), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccAWSCustomerGatewayDisappears(gateway *ec2.CustomerGateway) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).ec2conn + opts := &ec2.DeleteCustomerGatewayInput{ + CustomerGatewayId: gateway.CustomerGatewayId, + } + if _, err := conn.DeleteCustomerGateway(opts); err != nil { + return err + } + return resource.Retry(40*time.Minute, func() *resource.RetryError { + opts := &ec2.DescribeCustomerGatewaysInput{ + CustomerGatewayIds: []*string{gateway.CustomerGatewayId}, + } + resp, err := conn.DescribeCustomerGateways(opts) + if err != nil { + cgw, ok := err.(awserr.Error) + if ok && cgw.Code() == "InvalidCustomerGatewayID.NotFound" { + return nil + } + return resource.NonRetryableError( + fmt.Errorf("Error retrieving Customer Gateway: %s", err)) + } + if *resp.CustomerGateways[0].State == "deleted" { + return nil + } + return resource.RetryableError(fmt.Errorf( + "Waiting for Customer Gateway: %v", gateway.CustomerGatewayId)) + }) + } +} + func testAccCheckCustomerGatewayDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).ec2conn @@ -72,6 +118,10 @@ func testAccCheckCustomerGatewayDestroy(s *terraform.State) error { if len(resp.CustomerGateways) > 0 { return fmt.Errorf("Customer gateway still exists: %v", resp.CustomerGateways) } + + if *resp.CustomerGateways[0].State == "deleted" { + continue + } } return err @@ -80,7 +130,7 @@ func testAccCheckCustomerGatewayDestroy(s *terraform.State) error { return nil } -func testAccCheckCustomerGateway(gatewayResource string) resource.TestCheckFunc { +func testAccCheckCustomerGateway(gatewayResource string, cgw *ec2.CustomerGateway) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[gatewayResource] if !ok { @@ -102,7 +152,7 @@ func testAccCheckCustomerGateway(gatewayResource string) resource.TestCheckFunc Values: []*string{aws.String(gateway.Primary.ID)}, } - _, err := ec2conn.DescribeCustomerGateways(&ec2.DescribeCustomerGatewaysInput{ + resp, err := ec2conn.DescribeCustomerGateways(&ec2.DescribeCustomerGatewaysInput{ Filters: []*ec2.Filter{gatewayFilter}, }) @@ -110,6 +160,9 @@ func testAccCheckCustomerGateway(gatewayResource string) resource.TestCheckFunc return err } + respGateway := resp.CustomerGateways[0] + *cgw = *respGateway + return nil } } diff --git a/builtin/providers/aws/resource_aws_vpn_gateway_test.go b/builtin/providers/aws/resource_aws_vpn_gateway_test.go index c9d2d921a..ce74c06fe 100644 --- a/builtin/providers/aws/resource_aws_vpn_gateway_test.go +++ b/builtin/providers/aws/resource_aws_vpn_gateway_test.go @@ -3,6 +3,7 @@ package aws import ( "fmt" "testing" + "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" @@ -57,6 +58,27 @@ func TestAccAWSVpnGateway_basic(t *testing.T) { }) } +func TestAccAWSVpnGateway_disappears(t *testing.T) { + var v ec2.VpnGateway + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_vpn_gateway.foo", + Providers: testAccProviders, + CheckDestroy: testAccCheckVpnGatewayDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccVpnGatewayConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckVpnGatewayExists("aws_vpn_gateway.foo", &v), + testAccAWSVpnGatewayDisappears(&v), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + func TestAccAWSVpnGateway_reattach(t *testing.T) { var vpc1, vpc2 ec2.Vpc var vgw1, vgw2 ec2.VpnGateway @@ -200,6 +222,61 @@ func TestAccAWSVpnGateway_tags(t *testing.T) { }) } +func testAccAWSVpnGatewayDisappears(gateway *ec2.VpnGateway) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).ec2conn + + _, err := conn.DetachVpnGateway(&ec2.DetachVpnGatewayInput{ + VpnGatewayId: gateway.VpnGatewayId, + VpcId: gateway.VpcAttachments[0].VpcId, + }) + if err != nil { + ec2err, ok := err.(awserr.Error) + if ok { + if ec2err.Code() == "InvalidVpnGatewayID.NotFound" { + return nil + } else if ec2err.Code() == "InvalidVpnGatewayAttachment.NotFound" { + return nil + } + } + + if err != nil { + return err + } + } + + opts := &ec2.DeleteVpnGatewayInput{ + VpnGatewayId: gateway.VpnGatewayId, + } + if _, err := conn.DeleteVpnGateway(opts); err != nil { + return err + } + return resource.Retry(40*time.Minute, func() *resource.RetryError { + opts := &ec2.DescribeVpnGatewaysInput{ + VpnGatewayIds: []*string{gateway.VpnGatewayId}, + } + resp, err := conn.DescribeVpnGateways(opts) + if err != nil { + cgw, ok := err.(awserr.Error) + if ok && cgw.Code() == "InvalidVpnGatewayID.NotFound" { + return nil + } + if ok && cgw.Code() == "IncorrectState" { + return resource.RetryableError(fmt.Errorf( + "Waiting for VPN Gateway to be in the correct state: %v", gateway.VpnGatewayId)) + } + return resource.NonRetryableError( + fmt.Errorf("Error retrieving VPN Gateway: %s", err)) + } + if *resp.VpnGateways[0].State == "deleted" { + return nil + } + return resource.RetryableError(fmt.Errorf( + "Waiting for VPN Gateway: %v", gateway.VpnGatewayId)) + }) + } +} + func testAccCheckVpnGatewayDestroy(s *terraform.State) error { ec2conn := testAccProvider.Meta().(*AWSClient).ec2conn