diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceExpectTest.java index 1802e0d76f..33a91458c4 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceExpectTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceExpectTest.java @@ -18,14 +18,9 @@ */ package org.jclouds.ec2.compute; import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.blockUntilRunning; -import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; -import java.util.Properties; - -import javax.ws.rs.core.MediaType; - import org.jclouds.compute.ComputeService; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.ec2.compute.internal.BaseEC2ComputeServiceExpectTest; @@ -45,168 +40,6 @@ import com.google.common.collect.Iterables; @Test(groups = "unit", testName = "EC2ComputeServiceExpectTest") public class EC2ComputeServiceExpectTest extends BaseEC2ComputeServiceExpectTest { - static String region = "us-east-1"; - - @Override - protected Properties setupProperties() { - Properties properties = super.setupProperties(); - properties.setProperty(PROPERTY_REGIONS, region); - properties.setProperty(provider + ".template", "osDescriptionMatches=.*fedora.*"); - return properties; - } - - private HttpRequest describeAvailabilityZonesRequest; - private HttpResponse describeAvailabilityZonesResponse; - private HttpRequest describeImagesRequest; - private HttpResponse describeImagesResponse; - private HttpRequest createKeyPairRequest; - private HttpResponse createKeyPairResponse; - private HttpRequest createSecurityGroupRequest; - private HttpResponse createSecurityGroupResponse; - private HttpRequest describeSecurityGroupRequest; - private HttpResponse describeSecurityGroupResponse; - private HttpRequest authorizeSecurityGroupIngressRequest22; - private HttpResponse authorizeSecurityGroupIngressResponse; - private HttpRequest authorizeSecurityGroupIngressRequestGroup; - private HttpRequest runInstancesRequest; - private HttpResponse runInstancesResponse; - private HttpRequest describeInstanceRequest; - private HttpResponse describeInstanceResponse; - private HttpRequest describeImageRequest; - - public EC2ComputeServiceExpectTest() { - describeAvailabilityZonesRequest = - formSigner.filter(HttpRequest.builder() - .method("POST") - .endpoint("https://ec2." + region + ".amazonaws.com/") - .addHeader("Host", "ec2." + region + ".amazonaws.com") - .addFormParam("Action", "DescribeAvailabilityZones").build()); - - describeAvailabilityZonesResponse = - HttpResponse.builder().statusCode(200) - .payload(payloadFromResourceWithContentType( - "/availabilityZones-" + region + ".xml", MediaType.APPLICATION_XML)).build(); - describeImagesRequest = - formSigner.filter(HttpRequest.builder() - .method("POST") - .endpoint("https://ec2." + region + ".amazonaws.com/") - .addHeader("Host", "ec2." + region + ".amazonaws.com") - .addFormParam("Action", "DescribeImages").build()); - - describeImagesResponse = - HttpResponse.builder().statusCode(200) - .payload(payloadFromResourceWithContentType( - "/describe_images.xml", MediaType.APPLICATION_XML)).build(); - - createKeyPairRequest = - formSigner.filter(HttpRequest.builder() - .method("POST") - .endpoint("https://ec2." + region + ".amazonaws.com/") - .addHeader("Host", "ec2." + region + ".amazonaws.com") - .addFormParam("Action", "CreateKeyPair") - .addFormParam("KeyName", "jclouds#test#0").build()); - - createKeyPairResponse = - HttpResponse.builder().statusCode(200) - .payload(payloadFromResourceWithContentType( - "/create_keypair.xml", MediaType.APPLICATION_XML)).build(); - - createSecurityGroupRequest = - formSigner.filter(HttpRequest.builder() - .method("POST") - .endpoint("https://ec2." + region + ".amazonaws.com/") - .addHeader("Host", "ec2." + region + ".amazonaws.com") - .addFormParam("Action", "CreateSecurityGroup") - .addFormParam("GroupDescription", "jclouds#test") - .addFormParam("GroupName", "jclouds#test").build()); - - createSecurityGroupResponse = - HttpResponse.builder().statusCode(200) - .payload(payloadFromResourceWithContentType( - "/created_securitygroup.xml", MediaType.APPLICATION_XML)).build(); - - describeSecurityGroupRequest = - formSigner.filter(HttpRequest.builder() - .method("POST") - .endpoint("https://ec2." + region + ".amazonaws.com/") - .addHeader("Host", "ec2." + region + ".amazonaws.com") - .addFormParam("Action", "DescribeSecurityGroups") - .addFormParam("GroupName.1", "jclouds#test").build()); - - describeSecurityGroupResponse = - HttpResponse.builder().statusCode(200) - .payload(payloadFromResourceWithContentType( - "/new_securitygroup.xml", MediaType.APPLICATION_XML)).build(); - - authorizeSecurityGroupIngressRequest22 = - formSigner.filter(HttpRequest.builder() - .method("POST") - .endpoint("https://ec2." + region + ".amazonaws.com/") - .addHeader("Host", "ec2." + region + ".amazonaws.com") - .addFormParam("Action", "AuthorizeSecurityGroupIngress") - .addFormParam("CidrIp", "0.0.0.0/0") - .addFormParam("FromPort", "22") - .addFormParam("ToPort", "22") - .addFormParam("GroupName", "jclouds#test") - .addFormParam("IpProtocol", "tcp").build()); - - authorizeSecurityGroupIngressRequestGroup = - formSigner.filter(HttpRequest.builder() - .method("POST") - .endpoint("https://ec2." + region + ".amazonaws.com/") - .addHeader("Host", "ec2." + region + ".amazonaws.com") - .addFormParam("Action", "AuthorizeSecurityGroupIngress") - .addFormParam("SourceSecurityGroupName", "jclouds#test") - .addFormParam("SourceSecurityGroupOwnerId", "993194456877") - .addFormParam("GroupName", "jclouds#test").build()); - - authorizeSecurityGroupIngressResponse = - HttpResponse.builder().statusCode(200) - .payload(payloadFromResourceWithContentType( - "/authorize_securitygroup_ingress_response.xml", MediaType.APPLICATION_XML)).build(); - - - runInstancesRequest = - formSigner.filter(HttpRequest.builder() - .method("POST") - .endpoint("https://ec2." + region + ".amazonaws.com/") - .addHeader("Host", "ec2." + region + ".amazonaws.com") - .addFormParam("Action", "RunInstances") - .addFormParam("ImageId", "ami-be3adfd7") - .addFormParam("InstanceType", "m1.small") - .addFormParam("KeyName", "jclouds#test#0") - .addFormParam("MaxCount", "1") - .addFormParam("MinCount", "1") - .addFormParam("SecurityGroup.1", "jclouds#test").build()); - - runInstancesResponse = - HttpResponse.builder().statusCode(200) - .payload(payloadFromResourceWithContentType( - "/new_instance.xml", MediaType.APPLICATION_XML)).build(); - - describeInstanceRequest = - formSigner.filter(HttpRequest.builder() - .method("POST") - .endpoint("https://ec2." + region + ".amazonaws.com/") - .addHeader("Host", "ec2." + region + ".amazonaws.com") - .addFormParam("Action", "DescribeInstances") - .addFormParam("InstanceId.1", "i-2baa5550").build()); - - describeInstanceResponse = - HttpResponse.builder().statusCode(200) - .payload(payloadFromResourceWithContentType( - "/describe_instances_running-1.xml", MediaType.APPLICATION_XML)).build(); - - //TODO: duplicate.. shouldn't need this - describeImageRequest = - formSigner.filter(HttpRequest.builder() - .method("POST") - .endpoint("https://ec2." + region + ".amazonaws.com/") - .addHeader("Host", "ec2." + region + ".amazonaws.com") - .addFormParam("ImageId.1", "ami-aecd60c7") - .addFormParam("Action", "DescribeImages").build()); - } - public void testCreateNodeWithGeneratedKeyPairAndOverriddenLoginUser() throws Exception { Builder requestResponseMap = ImmutableMap. builder(); requestResponseMap.put(describeRegionsRequest, describeRegionsResponse); @@ -255,5 +88,4 @@ public class EC2ComputeServiceExpectTest extends BaseEC2ComputeServiceExpectTest assertNotNull(node.getCredentials().getPrivateKey()); } - } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceContextExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceContextExpectTest.java index fc1cb1419d..eae0ec5af5 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceContextExpectTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceContextExpectTest.java @@ -42,5 +42,4 @@ public abstract class BaseEC2ComputeServiceContextExpectTest extends BaseEC2C return createInjector(fn, module, props).getInstance(ComputeServiceContext.class); } - } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceExpectTest.java index c7a1ea294a..f18f71e7ed 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceExpectTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceExpectTest.java @@ -19,10 +19,186 @@ package org.jclouds.ec2.compute.internal; +import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; + +import java.util.Properties; + +import javax.ws.rs.core.MediaType; + import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.testng.annotations.BeforeClass; -public class BaseEC2ComputeServiceExpectTest extends BaseEC2ComputeServiceContextExpectTest { +public abstract class BaseEC2ComputeServiceExpectTest extends BaseEC2ComputeServiceContextExpectTest { + protected String region; + + @Override + protected Properties setupProperties() { + Properties properties = super.setupProperties(); + properties.setProperty(PROPERTY_REGIONS, region); + properties.setProperty(provider + ".template", "osDescriptionMatches=.*fedora.*"); + return properties; + } + + protected HttpRequest describeAvailabilityZonesRequest; + protected HttpResponse describeAvailabilityZonesResponse; + protected HttpRequest describeImagesRequest; + protected HttpResponse describeImagesResponse; + protected HttpRequest createKeyPairRequest; + protected HttpResponse createKeyPairResponse; + protected HttpRequest createSecurityGroupRequest; + protected HttpResponse createSecurityGroupResponse; + protected HttpRequest describeSecurityGroupRequest; + protected HttpResponse describeSecurityGroupResponse; + protected HttpRequest authorizeSecurityGroupIngressRequest22; + protected HttpResponse authorizeSecurityGroupIngressResponse; + protected HttpRequest authorizeSecurityGroupIngressRequestGroup; + protected HttpRequest runInstancesRequest; + protected HttpResponse runInstancesResponse; + protected HttpRequest describeInstanceRequest; + protected HttpResponse describeInstanceResponse; + protected HttpRequest describeImageRequest; + + public BaseEC2ComputeServiceExpectTest() { + region = "us-east-1"; + } + + @BeforeClass + @Override + protected void setupDefaultRequests() { + super.setupDefaultRequests(); + describeAvailabilityZonesRequest = + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("Action", "DescribeAvailabilityZones").build()); + + describeAvailabilityZonesResponse = + HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType( + "/availabilityZones-" + region + ".xml", MediaType.APPLICATION_XML)).build(); + describeImagesRequest = + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("Action", "DescribeImages").build()); + + describeImagesResponse = + HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType( + "/describe_images.xml", MediaType.APPLICATION_XML)).build(); + + createKeyPairRequest = + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("Action", "CreateKeyPair") + .addFormParam("KeyName", "jclouds#test#0").build()); + + createKeyPairResponse = + HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType( + "/create_keypair.xml", MediaType.APPLICATION_XML)).build(); + + createSecurityGroupRequest = + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("Action", "CreateSecurityGroup") + .addFormParam("GroupDescription", "jclouds#test") + .addFormParam("GroupName", "jclouds#test").build()); + + createSecurityGroupResponse = + HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType( + "/created_securitygroup.xml", MediaType.APPLICATION_XML)).build(); + + describeSecurityGroupRequest = + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("Action", "DescribeSecurityGroups") + .addFormParam("GroupName.1", "jclouds#test").build()); + + describeSecurityGroupResponse = + HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType( + "/new_securitygroup.xml", MediaType.APPLICATION_XML)).build(); + + authorizeSecurityGroupIngressRequest22 = + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("Action", "AuthorizeSecurityGroupIngress") + .addFormParam("CidrIp", "0.0.0.0/0") + .addFormParam("FromPort", "22") + .addFormParam("ToPort", "22") + .addFormParam("GroupName", "jclouds#test") + .addFormParam("IpProtocol", "tcp").build()); + + authorizeSecurityGroupIngressRequestGroup = + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("Action", "AuthorizeSecurityGroupIngress") + .addFormParam("SourceSecurityGroupName", "jclouds#test") + .addFormParam("SourceSecurityGroupOwnerId", "993194456877") + .addFormParam("GroupName", "jclouds#test").build()); + + authorizeSecurityGroupIngressResponse = + HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType( + "/authorize_securitygroup_ingress_response.xml", MediaType.APPLICATION_XML)).build(); + + runInstancesRequest = + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("Action", "RunInstances") + .addFormParam("ImageId", "ami-be3adfd7") + .addFormParam("InstanceType", "m1.small") + .addFormParam("KeyName", "jclouds#test#0") + .addFormParam("MaxCount", "1") + .addFormParam("MinCount", "1") + .addFormParam("SecurityGroup.1", "jclouds#test").build()); + + runInstancesResponse = + HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType( + "/new_instance.xml", MediaType.APPLICATION_XML)).build(); + + describeInstanceRequest = + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("Action", "DescribeInstances") + .addFormParam("InstanceId.1", "i-2baa5550").build()); + + describeInstanceResponse = + HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType( + "/describe_instances_running-1.xml", MediaType.APPLICATION_XML)).build(); + + //TODO: duplicate.. shouldn't need this + describeImageRequest = + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("ImageId.1", "ami-aecd60c7") + .addFormParam("Action", "DescribeImages").build()); + } @Override public ComputeService apply(ComputeServiceContext input) { diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/config/EC2RestClientModuleExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/config/EC2RestClientModuleExpectTest.java index 2d8630d03b..637e093144 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/config/EC2RestClientModuleExpectTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/config/EC2RestClientModuleExpectTest.java @@ -32,6 +32,7 @@ import org.jclouds.location.Region; import org.jclouds.location.Zone; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.location.functions.ZoneToEndpoint; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import com.google.common.base.Function; @@ -51,7 +52,10 @@ import com.google.inject.TypeLiteral; public class EC2RestClientModuleExpectTest extends BaseEC2ClientExpectTest { private Injector injector; - public EC2RestClientModuleExpectTest() { + @BeforeClass + @Override + protected void setupDefaultRequests() { + super.setupDefaultRequests(); Builder builder = ImmutableMap. builder(); builder.put(describeRegionsRequest, describeRegionsResponse); builder.putAll(describeAvailabilityZonesRequestResponse); diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/features/TagApiExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/features/TagApiExpectTest.java index 3e36be53b7..7364945a2c 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/features/TagApiExpectTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/features/TagApiExpectTest.java @@ -20,7 +20,6 @@ package org.jclouds.ec2.features; import static org.testng.Assert.assertEquals; import java.util.Properties; -import java.util.TimeZone; import org.jclouds.Constants; import org.jclouds.ec2.EC2Api; @@ -42,10 +41,6 @@ import com.google.common.collect.ImmutableSet; @Test(groups = "unit") public class TagApiExpectTest extends BaseEC2ApiExpectTest { - public TagApiExpectTest() { - TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); - } - /** * @see TagApi * @see SinceApiVersion diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/features/WindowsApiExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/features/WindowsApiExpectTest.java index 3a2de63247..4e5b6293ff 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/features/WindowsApiExpectTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/features/WindowsApiExpectTest.java @@ -21,8 +21,6 @@ package org.jclouds.ec2.features; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; -import java.util.TimeZone; - import org.jclouds.ec2.EC2Api; import org.jclouds.ec2.internal.BaseEC2ApiExpectTest; import org.jclouds.ec2.parse.GetPasswordDataResponseTest; @@ -36,10 +34,6 @@ import org.testng.annotations.Test; @Test(groups = "unit", testName = "WindowsApiExpectTest") public class WindowsApiExpectTest extends BaseEC2ApiExpectTest { - public WindowsApiExpectTest() { - TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); - } - HttpRequest get = HttpRequest.builder() .method("POST") .endpoint("https://ec2.us-east-1.amazonaws.com/") diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/internal/BaseEC2ClientExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/internal/BaseEC2ClientExpectTest.java index d0c5d8fe37..b7e9583a09 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/internal/BaseEC2ClientExpectTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/internal/BaseEC2ClientExpectTest.java @@ -39,7 +39,7 @@ public abstract class BaseEC2ClientExpectTest extends BaseEC2ExpectTest { @Override protected void configure() { super.configure(); - // predicatable node names + // predictable node names final AtomicInteger suffix = new AtomicInteger(); bind(new TypeLiteral>() { }).toInstance(new Supplier() { diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/internal/BaseEC2ExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/internal/BaseEC2ExpectTest.java index 9f447eed38..aa20db3fcd 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/internal/BaseEC2ExpectTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/internal/BaseEC2ExpectTest.java @@ -19,6 +19,7 @@ package org.jclouds.ec2.internal; import java.util.Map; +import java.util.TimeZone; import javax.ws.rs.core.MediaType; @@ -28,11 +29,13 @@ import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.rest.internal.BaseRestClientExpectTest; +import org.testng.annotations.BeforeClass; import com.google.common.base.Functions; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.ImmutableSet; +import com.google.inject.Injector; public abstract class BaseEC2ExpectTest extends BaseRestClientExpectTest { protected static final String CONSTANT_DATE = "2012-04-16T15:54:08.897Z"; @@ -41,25 +44,28 @@ public abstract class BaseEC2ExpectTest extends BaseRestClientExpectTest { protected FormSigner formSigner; - protected HttpRequest describeRegionsRequest = HttpRequest.builder() - .method("POST") - .endpoint("https://ec2.us-east-1.amazonaws.com/") - .addHeader("Host", "ec2.us-east-1.amazonaws.com") - .payload(payloadFromStringWithContentType( - "Action=DescribeRegions&Signature=s5OXKqaaeKhJW5FVrRntuMsUL4Ed5fjzgUWeukU96ko%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2012-04-16T15%3A54%3A08.897Z&Version=2010-06-15&AWSAccessKeyId=identity", - MediaType.APPLICATION_FORM_URLENCODED)).build(); + protected HttpRequest describeRegionsRequest; protected HttpResponse describeRegionsResponse = HttpResponse.builder().statusCode(200) .payload(payloadFromResourceWithContentType("/regionEndpoints-all.xml", MediaType.APPLICATION_XML)) .build(); - protected final Map describeAvailabilityZonesRequestResponse; - + protected Map describeAvailabilityZonesRequestResponse; public BaseEC2ExpectTest() { provider = "ec2"; - formSigner = createInjector(Functions.forMap(ImmutableMap. of()), - createModule(), setupProperties()).getInstance(FormSigner.class); + TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); + } + + @BeforeClass + protected void setupDefaultRequests() { + Injector injector = createInjector(Functions.forMap(ImmutableMap. of()), + createModule(), setupProperties()); + formSigner = injector.getInstance(FormSigner.class); + describeRegionsRequest = formSigner.filter(HttpRequest.builder().method("POST") + .endpoint("https://ec2.us-east-1.amazonaws.com/").addHeader("Host", "ec2.us-east-1.amazonaws.com") + .addFormParam("Action", "DescribeRegions").build()); + Builder builder = ImmutableMap. builder(); for (String region : ImmutableSet.of("ap-northeast-1", "ap-southeast-1", "eu-west-1", "sa-east-1", "us-east-1", "us-west-1", "us-west-2")){ builder.put( diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/binders/BindLaunchSpecificationToFormParams.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/binders/BindLaunchSpecificationToFormParams.java index 54c82975e8..588d8ab05c 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/binders/BindLaunchSpecificationToFormParams.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/binders/BindLaunchSpecificationToFormParams.java @@ -66,6 +66,8 @@ public class BindLaunchSpecificationToFormParams implements Binder, Function 0) options.withSecurityGroupIds(launchSpec.getSecurityGroupIds()); options.asType(checkNotNull(launchSpec.getInstanceType(), "instanceType")); + if (launchSpec.getSubnetId() != null) + options.withSubnetId(launchSpec.getSubnetId()); if (launchSpec.getKernelId() != null) options.withKernelId(launchSpec.getKernelId()); if (launchSpec.getKeyName() != null) diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2CreateNodesInGroupThenAddToSet.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2CreateNodesInGroupThenAddToSet.java index 05a86355d6..fdd3f0e85c 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2CreateNodesInGroupThenAddToSet.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2CreateNodesInGroupThenAddToSet.java @@ -96,9 +96,11 @@ public class AWSEC2CreateNodesInGroupThenAddToSet extends EC2CreateNodesInGroupT int count, Template template, RunInstancesOptions instanceOptions) { Float spotPrice = getSpotPriceOrNull(template.getOptions()); if (spotPrice != null) { + AWSEC2TemplateOptions awsOptions = AWSEC2TemplateOptions.class.cast(template.getOptions()); LaunchSpecification spec = AWSRunInstancesOptions.class.cast(instanceOptions).getLaunchSpecificationBuilder() - .imageId(template.getImage().getProviderId()).availabilityZone(zone).build(); - RequestSpotInstancesOptions options = AWSEC2TemplateOptions.class.cast(template.getOptions()).getSpotOptions(); + .imageId(template.getImage().getProviderId()).availabilityZone(zone).subnetId(awsOptions.getSubnetId()) + .build(); + RequestSpotInstancesOptions options = awsOptions.getSpotOptions(); if (logger.isDebugEnabled()) logger.debug(">> requesting %d spot instances region(%s) price(%f) spec(%s) options(%s)", count, region, spotPrice, spec, options); diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/LaunchSpecification.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/LaunchSpecification.java index 7b390b2150..de6c7ea822 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/LaunchSpecification.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/LaunchSpecification.java @@ -54,6 +54,7 @@ public class LaunchSpecification { protected String kernelId; protected String keyName; protected String availabilityZone; + protected String subnetId; protected String ramdiskId; protected Boolean monitoringEnabled; protected ImmutableSet.Builder blockDeviceMappings = ImmutableSet @@ -69,6 +70,7 @@ public class LaunchSpecification { kernelId = null; keyName = null; availabilityZone = null; + subnetId = null; ramdiskId = null; monitoringEnabled = false; blockDeviceMappings = ImmutableSet.builder(); @@ -117,7 +119,12 @@ public class LaunchSpecification { this.availabilityZone = availabilityZone; return this; } - + + public Builder subnetId(String subnetId) { + this.subnetId = subnetId; + return this; + } + public Builder ramdiskId(String ramdiskId) { this.ramdiskId = ramdiskId; return this; @@ -177,17 +184,18 @@ public class LaunchSpecification { } public LaunchSpecification build() { - return new LaunchSpecification(instanceType, imageId, kernelId, ramdiskId, availabilityZone, keyName, - securityGroupIdToNames.build(), blockDeviceMappings.build(), monitoringEnabled, + return new LaunchSpecification(instanceType, imageId, kernelId, ramdiskId, availabilityZone, subnetId, + keyName, securityGroupIdToNames.build(), blockDeviceMappings.build(), monitoringEnabled, securityGroupIds.build(), securityGroupNames.build(), userData); } public static Builder fromLaunchSpecification(LaunchSpecification in) { return new Builder().instanceType(in.getInstanceType()).imageId(in.getImageId()).kernelId(in.getKernelId()) - .ramdiskId(in.getRamdiskId()).availabilityZone(in.getAvailabilityZone()).keyName(in.getKeyName()) - .securityGroupIdToNames(in.getSecurityGroupIdToNames()).securityGroupIds(in.getSecurityGroupIds()) - .securityGroupNames(in.getSecurityGroupNames()).blockDeviceMappings(in.getBlockDeviceMappings()) - .monitoringEnabled(in.isMonitoringEnabled()).userData(in.getUserData()); + .ramdiskId(in.getRamdiskId()).availabilityZone(in.getAvailabilityZone()).subnetId(in.getSubnetId()) + .keyName(in.getKeyName()).securityGroupIdToNames(in.getSecurityGroupIdToNames()) + .securityGroupIds(in.getSecurityGroupIds()).securityGroupNames(in.getSecurityGroupNames()) + .blockDeviceMappings(in.getBlockDeviceMappings()).monitoringEnabled(in.isMonitoringEnabled()) + .userData(in.getUserData()); } } @@ -196,6 +204,7 @@ public class LaunchSpecification { protected final String kernelId; protected final String ramdiskId; protected final String availabilityZone; + protected final String subnetId; protected final String keyName; protected final Map securityGroupIdToNames; protected final Set blockDeviceMappings; @@ -205,7 +214,7 @@ public class LaunchSpecification { protected final byte[] userData; public LaunchSpecification(String instanceType, String imageId, String kernelId, String ramdiskId, - String availabilityZone, String keyName, Map securityGroupIdToNames, + String availabilityZone, String subnetId, String keyName, Map securityGroupIdToNames, Iterable blockDeviceMappings, Boolean monitoringEnabled, Set securityGroupIds, Set securityGroupNames, byte[] userData) { this.instanceType = checkNotNull(instanceType, "instanceType"); @@ -213,6 +222,7 @@ public class LaunchSpecification { this.kernelId = kernelId; this.ramdiskId = ramdiskId; this.availabilityZone = availabilityZone; + this.subnetId = subnetId; this.keyName = keyName; this.securityGroupIdToNames = ImmutableMap.copyOf(checkNotNull(securityGroupIdToNames, "securityGroupIdToNames")); this.blockDeviceMappings = ImmutableSortedSet.copyOf(checkNotNull(blockDeviceMappings, "blockDeviceMappings")); @@ -268,6 +278,14 @@ public class LaunchSpecification { public String getAvailabilityZone() { return availabilityZone; } + + /** + * The ID of the subnet in which to launch the Spot Instance. + */ + @Nullable + public String getSubnetId() { + return subnetId; + } /** * Optional. RAM disk associated with this instance. @@ -309,6 +327,7 @@ public class LaunchSpecification { final int prime = 31; int result = 1; result = prime * result + ((availabilityZone == null) ? 0 : availabilityZone.hashCode()); + result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode()); result = prime * result + ((blockDeviceMappings == null) ? 0 : blockDeviceMappings.hashCode()); result = prime * result + ((imageId == null) ? 0 : imageId.hashCode()); result = prime * result + ((instanceType == null) ? 0 : instanceType.hashCode()); @@ -337,6 +356,11 @@ public class LaunchSpecification { return false; } else if (!availabilityZone.equals(other.availabilityZone)) return false; + if (subnetId == null) { + if (other.subnetId != null) + return false; + } else if (!subnetId.equals(other.subnetId)) + return false; if (blockDeviceMappings == null) { if (other.blockDeviceMappings != null) return false; @@ -399,7 +423,7 @@ public class LaunchSpecification { @Override public String toString() { return "[instanceType=" + instanceType + ", imageId=" + imageId + ", kernelId=" + kernelId + ", ramdiskId=" - + ramdiskId + ", availabilityZone=" + availabilityZone + ", keyName=" + keyName + + ramdiskId + ", availabilityZone=" + availabilityZone + ", subnetId=" + subnetId + ", keyName=" + keyName + ", securityGroupIdToNames=" + securityGroupIdToNames + ", blockDeviceMappings=" + blockDeviceMappings + ", securityGroupIds=" + securityGroupIds + ", securityGroupNames=" + securityGroupNames + ", monitoringEnabled=" + monitoringEnabled + ", userData=" + Arrays.toString(userData) + "]"; diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/LaunchSpecificationHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/LaunchSpecificationHandler.java index 5944b74e00..e8390ff98e 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/LaunchSpecificationHandler.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/LaunchSpecificationHandler.java @@ -110,6 +110,8 @@ public class LaunchSpecificationHandler extends HandlerForGeneratedRequestWithRe builder.keyName(currentOrNull()); } else if (qName.equals("availabilityZone")) { builder.availabilityZone(currentOrNull()); + } else if (qName.equals("subnetId")) { + builder.subnetId(currentOrNull()); } else if (qName.equals("ramdiskId")) { builder.ramdiskId(currentOrNull()); } else if (qName.equals("enabled")) { diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/binders/BindLaunchSpecificationToFormParamsTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/binders/BindLaunchSpecificationToFormParamsTest.java index 113c81c6ab..bfdd423093 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/binders/BindLaunchSpecificationToFormParamsTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/binders/BindLaunchSpecificationToFormParamsTest.java @@ -66,4 +66,13 @@ public class BindLaunchSpecificationToFormParamsTest { assertEquals(binder.apply(spec), ImmutableMap.of("LaunchSpecification.InstanceType", "t1.micro", "LaunchSpecification.ImageId", "ami-123", "LaunchSpecification.SecurityGroupId.1", "sid-foo")); } + + @Test + public void testApplyWithSubnetId() throws UnknownHostException { + LaunchSpecification spec = LaunchSpecification.builder().instanceType(InstanceType.T1_MICRO).imageId("ami-123") + .subnetId("subnet-xyz").build(); + + assertEquals(binder.apply(spec), ImmutableMap.of("LaunchSpecification.InstanceType", "t1.micro", + "LaunchSpecification.ImageId", "ami-123", "LaunchSpecification.SubnetId", "subnet-xyz")); + } } diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceExpectTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceExpectTest.java new file mode 100644 index 0000000000..45004a9906 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceExpectTest.java @@ -0,0 +1,95 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jclouds.aws.ec2.compute; + +import static org.testng.Assert.assertEquals; + +import javax.ws.rs.core.MediaType; + +import org.jclouds.aws.ec2.compute.internal.BaseAWSEC2ComputeServiceExpectTest; +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.Template; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; +import com.google.common.collect.Iterables; + +/** + * Tests the compute service abstraction of the EC2 api. + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "AWSEC2ComputeServiceExpectTest") +public class AWSEC2ComputeServiceExpectTest extends BaseAWSEC2ComputeServiceExpectTest { + + public void testLaunchVPCSpotInstanceMissesVPCId() throws Exception { + HttpRequest requestSpotInstancesRequest = formSigner.filter(HttpRequest.builder().method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("Action", "RequestSpotInstances") + .addFormParam("InstanceCount", "1") + .addFormParam("LaunchSpecification.ImageId", "ami-be3adfd7") + .addFormParam("LaunchSpecification.InstanceType", "m1.small") + .addFormParam("LaunchSpecification.KeyName", "Demo") + .addFormParam("LaunchSpecification.Placement.AvailabilityZone", "us-east-1a") + .addFormParam("LaunchSpecification.SubnetId", "subnet-xyz") + .addFormParam("LaunchSpecification.UserData", "I2Nsb3VkLWNvbmZpZwpyZXBvX3VwZ3JhZGU6IG5vbmUK") + .addFormParam("SpotPrice", "1.0").build()); + + HttpResponse requestSpotInstancesResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType( + "/request_spot_instances-ebs.xml", MediaType.APPLICATION_XML)).build(); + + HttpRequest describeSpotInstanceRequest = formSigner.filter(HttpRequest.builder().method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("Action", "DescribeSpotInstanceRequests") + .addFormParam("SpotInstanceRequestId.1", "sir-228e6406").build()); + + HttpResponse describeSpotInstanceResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType( + "/request_spot_instances-ebs.xml", MediaType.APPLICATION_XML)).build(); + + Builder requestResponseMap = ImmutableMap. builder(); + requestResponseMap.put(describeRegionsRequest, describeRegionsResponse); + requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse); + requestResponseMap.put(describeImagesRequest, describeImagesResponse); + requestResponseMap.put(createKeyPairRequest, createKeyPairResponse); + requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse); + requestResponseMap.put(describeSecurityGroupRequest, describeSecurityGroupResponse); + requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse); + requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse); + requestResponseMap.put(requestSpotInstancesRequest, requestSpotInstancesResponse); + requestResponseMap.put(describeSpotInstanceRequest, describeSpotInstanceResponse); + + ComputeService createsVPCSpotInstance = requestsSendResponses(requestResponseMap.build()); + + Template template = createsVPCSpotInstance.templateBuilder().locationId("us-east-1a").build(); + + template.getOptions().as(AWSEC2TemplateOptions.class).spotPrice(1f).subnetId("subnet-xyz").keyPair("Demo").blockUntilRunning(false); + + NodeMetadata node = Iterables.getOnlyElement(createsVPCSpotInstance.createNodesInGroup("demoGroup", 1, template)); + assertEquals(node.getId(), "us-east-1/sir-228e6406"); + } + +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/internal/BaseAWSEC2ComputeServiceExpectTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/internal/BaseAWSEC2ComputeServiceExpectTest.java new file mode 100644 index 0000000000..93542dde1e --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/internal/BaseAWSEC2ComputeServiceExpectTest.java @@ -0,0 +1,112 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jclouds.aws.ec2.compute.internal; + +import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_CC_AMI_QUERY; +import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_GENERATE_INSTANCE_NAMES; + +import java.util.Properties; +import java.util.concurrent.atomic.AtomicInteger; + +import org.jclouds.aws.ec2.config.AWSEC2RestClientModule; +import org.jclouds.date.DateService; +import org.jclouds.ec2.compute.internal.BaseEC2ComputeServiceExpectTest; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.ConfiguresRestClient; +import org.testng.annotations.BeforeClass; + +import com.google.common.base.Supplier; +import com.google.inject.Module; +import com.google.inject.Provides; +import com.google.inject.TypeLiteral; + +/** + * Tests the compute service abstraction of the EC2 api. + * + * @author Adrian Cole + */ +public abstract class BaseAWSEC2ComputeServiceExpectTest extends BaseEC2ComputeServiceExpectTest { + + public BaseAWSEC2ComputeServiceExpectTest() { + provider = "aws-ec2"; + } + + @Override + protected Properties setupProperties() { + Properties properties = super.setupProperties(); + // zero out cluster image query for now + properties.setProperty(PROPERTY_EC2_CC_AMI_QUERY, ""); + properties.setProperty(PROPERTY_EC2_GENERATE_INSTANCE_NAMES, "false"); + return properties; + } + + @BeforeClass + @Override + protected void setupDefaultRequests() { + super.setupDefaultRequests(); + + describeImagesRequest = + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("Action", "DescribeImages") + .addFormParam("Filter.1.Name", "owner-id") + .addFormParam("Filter.1.Value.1", "137112412989") + .addFormParam("Filter.1.Value.2", "801119661308") + .addFormParam("Filter.1.Value.3", "063491364108") + .addFormParam("Filter.1.Value.4", "099720109477") + .addFormParam("Filter.1.Value.5", "411009282317") + .addFormParam("Filter.2.Name", "state") + .addFormParam("Filter.2.Value.1", "available") + .addFormParam("Filter.3.Name", "image-type") + .addFormParam("Filter.3.Value.1", "machine").build()); + } + + @ConfiguresRestClient + protected static class TestAWSEC2RestClientModule extends AWSEC2RestClientModule { + + @Override + protected void configure() { + super.configure(); + // predicatable node names + final AtomicInteger suffix = new AtomicInteger(); + bind(new TypeLiteral>() { + }).toInstance(new Supplier() { + + @Override + public String get() { + return suffix.getAndIncrement() + ""; + } + + }); + } + + @Override + @Provides + protected String provideTimeStamp(DateService dateService) { + return CONSTANT_DATE; + } + } + + @Override + protected Module createModule() { + return new TestAWSEC2RestClientModule(); + } +}