github.com/jsoriano/terraform@v0.6.7-0.20151026070445-8b70867fdd95/builtin/providers/aws/resource_aws_spot_instance_request_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/ec2"
    10  	"github.com/hashicorp/terraform/helper/resource"
    11  	"github.com/hashicorp/terraform/terraform"
    12  )
    13  
    14  func TestAccAWSSpotInstanceRequest_basic(t *testing.T) {
    15  	var sir ec2.SpotInstanceRequest
    16  
    17  	resource.Test(t, resource.TestCase{
    18  		PreCheck:     func() { testAccPreCheck(t) },
    19  		Providers:    testAccProviders,
    20  		CheckDestroy: testAccCheckAWSSpotInstanceRequestDestroy,
    21  		Steps: []resource.TestStep{
    22  			resource.TestStep{
    23  				Config: testAccAWSSpotInstanceRequestConfig,
    24  				Check: resource.ComposeTestCheckFunc(
    25  					testAccCheckAWSSpotInstanceRequestExists(
    26  						"aws_spot_instance_request.foo", &sir),
    27  					testAccCheckAWSSpotInstanceRequestAttributes(&sir),
    28  					testCheckKeyPair("tmp-key", &sir),
    29  					resource.TestCheckResourceAttr(
    30  						"aws_spot_instance_request.foo", "spot_bid_status", "fulfilled"),
    31  					resource.TestCheckResourceAttr(
    32  						"aws_spot_instance_request.foo", "spot_request_state", "active"),
    33  				),
    34  			},
    35  		},
    36  	})
    37  }
    38  
    39  func TestAccAWSSpotInstanceRequest_vpc(t *testing.T) {
    40  	var sir ec2.SpotInstanceRequest
    41  
    42  	resource.Test(t, resource.TestCase{
    43  		PreCheck:     func() { testAccPreCheck(t) },
    44  		Providers:    testAccProviders,
    45  		CheckDestroy: testAccCheckAWSSpotInstanceRequestDestroy,
    46  		Steps: []resource.TestStep{
    47  			resource.TestStep{
    48  				Config: testAccAWSSpotInstanceRequestConfigVPC,
    49  				Check: resource.ComposeTestCheckFunc(
    50  					testAccCheckAWSSpotInstanceRequestExists(
    51  						"aws_spot_instance_request.foo_VPC", &sir),
    52  					testAccCheckAWSSpotInstanceRequestAttributes(&sir),
    53  					testCheckKeyPair("tmp-key", &sir),
    54  					testAccCheckAWSSpotInstanceRequestAttributesVPC(&sir),
    55  					resource.TestCheckResourceAttr(
    56  						"aws_spot_instance_request.foo_VPC", "spot_bid_status", "fulfilled"),
    57  					resource.TestCheckResourceAttr(
    58  						"aws_spot_instance_request.foo_VPC", "spot_request_state", "active"),
    59  				),
    60  			},
    61  		},
    62  	})
    63  }
    64  
    65  func testCheckKeyPair(keyName string, sir *ec2.SpotInstanceRequest) resource.TestCheckFunc {
    66  	return func(*terraform.State) error {
    67  		if sir.LaunchSpecification.KeyName == nil {
    68  			return fmt.Errorf("No Key Pair found, expected(%s)", keyName)
    69  		}
    70  		if sir.LaunchSpecification.KeyName != nil && *sir.LaunchSpecification.KeyName != keyName {
    71  			return fmt.Errorf("Bad key name, expected (%s), got (%s)", keyName, *sir.LaunchSpecification.KeyName)
    72  		}
    73  
    74  		return nil
    75  	}
    76  }
    77  
    78  func testAccCheckAWSSpotInstanceRequestDestroy(s *terraform.State) error {
    79  	conn := testAccProvider.Meta().(*AWSClient).ec2conn
    80  
    81  	for _, rs := range s.RootModule().Resources {
    82  		if rs.Type != "aws_spot_instance_request" {
    83  			continue
    84  		}
    85  
    86  		req := &ec2.DescribeSpotInstanceRequestsInput{
    87  			SpotInstanceRequestIds: []*string{aws.String(rs.Primary.ID)},
    88  		}
    89  
    90  		resp, err := conn.DescribeSpotInstanceRequests(req)
    91  		if err == nil {
    92  			if len(resp.SpotInstanceRequests) > 0 {
    93  				return fmt.Errorf("Spot instance request is still here.")
    94  			}
    95  		}
    96  
    97  		// Verify the error is what we expect
    98  		ec2err, ok := err.(awserr.Error)
    99  		if !ok {
   100  			return err
   101  		}
   102  		if ec2err.Code() != "InvalidSpotInstanceRequestID.NotFound" {
   103  			return err
   104  		}
   105  
   106  		// Now check if the associated Spot Instance was also destroyed
   107  		instId := rs.Primary.Attributes["spot_instance_id"]
   108  		instResp, instErr := conn.DescribeInstances(&ec2.DescribeInstancesInput{
   109  			InstanceIds: []*string{aws.String(instId)},
   110  		})
   111  		if instErr == nil {
   112  			if len(instResp.Reservations) > 0 {
   113  				return fmt.Errorf("Instance still exists.")
   114  			}
   115  
   116  			return nil
   117  		}
   118  
   119  		// Verify the error is what we expect
   120  		ec2err, ok = err.(awserr.Error)
   121  		if !ok {
   122  			return err
   123  		}
   124  		if ec2err.Code() != "InvalidInstanceID.NotFound" {
   125  			return err
   126  		}
   127  	}
   128  
   129  	return nil
   130  }
   131  
   132  func testAccCheckAWSSpotInstanceRequestExists(
   133  	n string, sir *ec2.SpotInstanceRequest) resource.TestCheckFunc {
   134  	return func(s *terraform.State) error {
   135  		rs, ok := s.RootModule().Resources[n]
   136  		if !ok {
   137  			return fmt.Errorf("Not found: %s", n)
   138  		}
   139  
   140  		if rs.Primary.ID == "" {
   141  			return fmt.Errorf("No SNS subscription with that ARN exists")
   142  		}
   143  
   144  		conn := testAccProvider.Meta().(*AWSClient).ec2conn
   145  
   146  		params := &ec2.DescribeSpotInstanceRequestsInput{
   147  			SpotInstanceRequestIds: []*string{&rs.Primary.ID},
   148  		}
   149  		resp, err := conn.DescribeSpotInstanceRequests(params)
   150  
   151  		if err != nil {
   152  			return err
   153  		}
   154  
   155  		if v := len(resp.SpotInstanceRequests); v != 1 {
   156  			return fmt.Errorf("Expected 1 request returned, got %d", v)
   157  		}
   158  
   159  		*sir = *resp.SpotInstanceRequests[0]
   160  
   161  		return nil
   162  	}
   163  }
   164  
   165  func testAccCheckAWSSpotInstanceRequestAttributes(
   166  	sir *ec2.SpotInstanceRequest) resource.TestCheckFunc {
   167  	return func(s *terraform.State) error {
   168  		if *sir.SpotPrice != "0.050000" {
   169  			return fmt.Errorf("Unexpected spot price: %s", *sir.SpotPrice)
   170  		}
   171  		if *sir.State != "active" {
   172  			return fmt.Errorf("Unexpected request state: %s", *sir.State)
   173  		}
   174  		if *sir.Status.Code != "fulfilled" {
   175  			return fmt.Errorf("Unexpected bid status: %s", *sir.State)
   176  		}
   177  		return nil
   178  	}
   179  }
   180  
   181  func testAccCheckAWSSpotInstanceRequestAttributesVPC(
   182  	sir *ec2.SpotInstanceRequest) resource.TestCheckFunc {
   183  	return func(s *terraform.State) error {
   184  		if sir.LaunchSpecification.SubnetId == nil {
   185  			return fmt.Errorf("SubnetID was not passed, but should have been for this instance to belong to a VPC")
   186  		}
   187  		return nil
   188  	}
   189  }
   190  
   191  const testAccAWSSpotInstanceRequestConfig = `
   192  resource "aws_key_pair" "debugging" {
   193  	key_name = "tmp-key"
   194  	public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com"
   195  }
   196  
   197  resource "aws_spot_instance_request" "foo" {
   198  	ami = "ami-4fccb37f"
   199  	instance_type = "m1.small"
   200  	key_name = "${aws_key_pair.debugging.key_name}"
   201  
   202  	// base price is $0.044 hourly, so bidding above that should theoretically
   203  	// always fulfill
   204  	spot_price = "0.05"
   205  
   206  	// we wait for fulfillment because we want to inspect the launched instance
   207  	// and verify termination behavior
   208  	wait_for_fulfillment = true
   209  
   210  	tags {
   211  		Name = "terraform-test"
   212  	}
   213  }
   214  `
   215  
   216  const testAccAWSSpotInstanceRequestConfigVPC = `
   217  resource "aws_vpc" "foo_VPC" {
   218  	cidr_block = "10.1.0.0/16"
   219  }
   220  
   221  resource "aws_subnet" "foo_VPC" {
   222  	cidr_block = "10.1.1.0/24"
   223  	vpc_id = "${aws_vpc.foo_VPC.id}"
   224  }
   225  
   226  resource "aws_key_pair" "debugging" {
   227  	key_name = "tmp-key"
   228  	public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com"
   229  }
   230  
   231  resource "aws_spot_instance_request" "foo_VPC" {
   232  	ami = "ami-4fccb37f"
   233  	instance_type = "m1.small"
   234  	key_name = "${aws_key_pair.debugging.key_name}"
   235  
   236  	// base price is $0.044 hourly, so bidding above that should theoretically
   237  	// always fulfill
   238  	spot_price = "0.05"
   239  
   240  	// VPC settings
   241  	subnet_id = "${aws_subnet.foo_VPC.id}"
   242  
   243  	// we wait for fulfillment because we want to inspect the launched instance
   244  	// and verify termination behavior
   245  	wait_for_fulfillment = true
   246  
   247  	tags {
   248  		Name = "terraform-test-VPC"
   249  	}
   250  }
   251  `