Repository: jclouds
Updated Branches:
  refs/heads/1.8.x 85eaea575 -> 243b96798


http://git-wip-us.apache.org/repos/asf/jclouds/blob/243b9679/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSAMIApiTest.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSAMIApiTest.java
 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSAMIApiTest.java
deleted file mode 100644
index cc99fb2..0000000
--- 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSAMIApiTest.java
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF 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.features;
-
-import static 
org.jclouds.ec2.options.DescribeImagesOptions.Builder.executableBy;
-import static org.jclouds.reflect.Reflection2.method;
-
-import java.io.IOException;
-
-import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
-import org.jclouds.aws.ec2.xml.ProductCodesHandler;
-import org.jclouds.ec2.options.CreateImageOptions;
-import org.jclouds.ec2.options.DescribeImagesOptions;
-import org.jclouds.ec2.options.RegisterImageBackedByEbsOptions;
-import org.jclouds.ec2.options.RegisterImageOptions;
-import org.jclouds.ec2.xml.BlockDeviceMappingHandler;
-import org.jclouds.ec2.xml.DescribeImagesResponseHandler;
-import org.jclouds.ec2.xml.ImageIdHandler;
-import org.jclouds.ec2.xml.PermissionHandler;
-import org.jclouds.http.HttpRequest;
-import org.jclouds.http.functions.ParseSax;
-import org.jclouds.http.functions.ReleasePayloadAndReturn;
-import org.jclouds.rest.internal.GeneratedHttpRequest;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.reflect.Invokable;
-/**
- * Tests behavior of {@code AWSAMIApi}
- */
-// NOTE:without testName, this will not call @Before* and fail w/NPE during 
surefire
-@Test(groups = "unit", testName = "AWSAMIApiTest")
-public class AWSAMIApiTest extends BaseAWSEC2ApiTest<AWSAMIApi> {
-   public AWSAMIApiTest() {
-      provider = "aws-ec2";
-   }
-
-   HttpRequest createImage = HttpRequest.builder().method("POST")
-                                        
.endpoint("https://ec2.us-east-1.amazonaws.com/";)
-                                        .addHeader("Host", 
"ec2.us-east-1.amazonaws.com")
-                                        .addFormParam("Action", "CreateImage")
-                                        .addFormParam("InstanceId", 
"instanceId")
-                                        .addFormParam("Name", "name").build();
-
-   public void testCreateImage() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, "createImageInRegion", 
String.class, String.class, String.class,
-               CreateImageOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "name", "instanceId"));
-
-      request = (GeneratedHttpRequest) 
request.getFilters().get(0).filter(request);
-      
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
filter.filter(createImage).getPayload().getRawContent().toString(),
-            "application/x-www-form-urlencoded", false);
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, ImageIdHandler.class);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   HttpRequest createImageOptions = HttpRequest.builder().method("POST")
-                                               
.endpoint("https://ec2.us-east-1.amazonaws.com/";)
-                                               .addHeader("Host", 
"ec2.us-east-1.amazonaws.com")
-                                               .addFormParam("Action", 
"CreateImage")
-                                               .addFormParam("Description", 
"description")
-                                               .addFormParam("InstanceId", 
"instanceId")
-                                               .addFormParam("Name", "name")
-                                               .addFormParam("NoReboot", 
"true").build();
-
-   public void testCreateImageOptions() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, "createImageInRegion", 
String.class, String.class, String.class,
-               CreateImageOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "name", "instanceId", new CreateImageOptions()
-               .withDescription("description").noReboot()));
-
-      request = (GeneratedHttpRequest) 
request.getFilters().get(0).filter(request);
-      
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
filter.filter(createImageOptions).getPayload().getRawContent().toString(),
-            "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, ImageIdHandler.class);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   HttpRequest describeImages = HttpRequest.builder().method("POST")
-                                           
.endpoint("https://ec2.us-east-1.amazonaws.com/";)
-                                           .addHeader("Host", 
"ec2.us-east-1.amazonaws.com")
-                                           .addFormParam("Action", 
"DescribeImages").build();
-
-   public void testDescribeImages() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, 
"describeImagesInRegion", String.class,
-               DescribeImagesOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList((String) null));
-
-      request = (GeneratedHttpRequest) 
request.getFilters().get(0).filter(request);
-      
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
filter.filter(describeImages).getPayload().getRawContent().toString(),
-            "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, 
DescribeImagesResponseHandler.class);
-      assertFallbackClassEquals(method, EmptySetOnNotFoundOr404.class);
-
-      checkFilters(request);
-   }
-
-   HttpRequest describeImagesOptions = HttpRequest.builder().method("POST")
-                                                  
.endpoint("https://ec2.us-east-1.amazonaws.com/";)
-                                                  .addHeader("Host", 
"ec2.us-east-1.amazonaws.com")
-                                                  .addFormParam("Action", 
"DescribeImages")
-                                                  
.addFormParam("ExecutableBy", "me")
-                                                  .addFormParam("ImageId.1", 
"1")
-                                                  .addFormParam("ImageId.2", 
"2")
-                                                  .addFormParam("Owner.1", 
"fred")
-                                                  .addFormParam("Owner.2", 
"nancy").build();
-
-   public void testDescribeImagesOptions() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, 
"describeImagesInRegion", String.class,
-               DescribeImagesOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, executableBy("me").ownedBy("fred", 
"nancy").imageIds(
-               "1", "2")));
-
-      request = (GeneratedHttpRequest) 
request.getFilters().get(0).filter(request);
-      
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
filter.filter(describeImagesOptions).getPayload().getRawContent().toString(),
-            "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, 
DescribeImagesResponseHandler.class);
-      assertFallbackClassEquals(method, EmptySetOnNotFoundOr404.class);
-
-      checkFilters(request);
-   }
-
-   HttpRequest deregisterImage = HttpRequest.builder().method("POST")
-                                            
.endpoint("https://ec2.us-east-1.amazonaws.com/";)
-                                            .addHeader("Host", 
"ec2.us-east-1.amazonaws.com")
-                                            .addFormParam("Action", 
"DeregisterImage")
-                                            .addFormParam("ImageId", 
"imageId").build();
-
-   public void testDeregisterImage() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, 
"deregisterImageInRegion", String.class, String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "imageId"));
-
-      request = (GeneratedHttpRequest) 
request.getFilters().get(0).filter(request);
-      
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
filter.filter(deregisterImage).getPayload().getRawContent().toString(),
-            "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, 
ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   HttpRequest registerImageFromManifest = HttpRequest.builder().method("POST")
-                                                      
.endpoint("https://ec2.us-east-1.amazonaws.com/";)
-                                                      .addHeader("Host", 
"ec2.us-east-1.amazonaws.com")
-                                                      .addFormParam("Action", 
"RegisterImage")
-                                                      
.addFormParam("ImageLocation", "pathToManifest")
-                                                      .addFormParam("Name", 
"name").build();
-
-   public void testRegisterImageFromManifest() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, 
"registerImageFromManifestInRegion", String.class, String.class,
-               String.class, RegisterImageOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "name", "pathToManifest"));
-
-      request = (GeneratedHttpRequest) 
request.getFilters().get(0).filter(request);
-      
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
filter.filter(registerImageFromManifest).getPayload().getRawContent().toString(),
-            "application/x-www-form-urlencoded", false);
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, ImageIdHandler.class);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   HttpRequest registerImageFromManifestOptions = 
HttpRequest.builder().method("POST")
-                                                             
.endpoint("https://ec2.us-east-1.amazonaws.com/";)
-                                                             
.addHeader("Host", "ec2.us-east-1.amazonaws.com")
-                                                             
.addFormParam("Action", "RegisterImage")
-                                                             
.addFormParam("Description", "description")
-                                                             
.addFormParam("ImageLocation", "pathToManifest")
-                                                             
.addFormParam("Name", "name").build();
-
-   public void testRegisterImageFromManifestOptions() throws 
SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, 
"registerImageFromManifestInRegion", String.class, String.class,
-               String.class, RegisterImageOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "name", "pathToManifest", new 
RegisterImageOptions()
-               .withDescription("description")));
-
-      request = (GeneratedHttpRequest) 
request.getFilters().get(0).filter(request);
-      
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
filter.filter(registerImageFromManifestOptions).getPayload().getRawContent()
-            .toString(), "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, ImageIdHandler.class);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   HttpRequest registerImageBackedByEBS = HttpRequest.builder().method("POST")
-                                                     
.endpoint("https://ec2.us-east-1.amazonaws.com/";)
-                                                     .addHeader("Host", 
"ec2.us-east-1.amazonaws.com")
-                                                     .addFormParam("Action", 
"RegisterImage")
-                                                     
.addFormParam("BlockDeviceMapping.0.DeviceName", "/dev/sda1")
-                                                     
.addFormParam("BlockDeviceMapping.0.Ebs.SnapshotId", "snapshotId")
-                                                     .addFormParam("Name", 
"imageName")
-                                                     
.addFormParam("RootDeviceName", "/dev/sda1").build();
-
-   public void testRegisterImageBackedByEBS() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, 
"registerUnixImageBackedByEbsInRegion", String.class,
-               String.class, String.class, 
RegisterImageBackedByEbsOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "imageName", "snapshotId"));
-
-      request = (GeneratedHttpRequest) 
request.getFilters().get(0).filter(request);
-      
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
filter.filter(registerImageBackedByEBS).getPayload().getRawContent().toString(),
-            "application/x-www-form-urlencoded", false);
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, ImageIdHandler.class);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   HttpRequest registerImageBackedByEBSOptions = 
HttpRequest.builder().method("POST")
-           .endpoint("https://ec2.us-east-1.amazonaws.com/";)
-           .addHeader("Host", "ec2.us-east-1.amazonaws.com")
-           .addFormParam("Action", "RegisterImage")
-           .addFormParam("BlockDeviceMapping.0.DeviceName", "/dev/sda1")
-           .addFormParam("BlockDeviceMapping.0.Ebs.SnapshotId", "snapshotId")
-           .addFormParam("BlockDeviceMapping.1.DeviceName", "/dev/device")
-           .addFormParam("BlockDeviceMapping.1.Ebs.DeleteOnTermination", 
"false")
-           .addFormParam("BlockDeviceMapping.1.Ebs.SnapshotId", "snapshot")
-           .addFormParam("BlockDeviceMapping.1.Ebs.VolumeType", "gp2")
-           .addFormParam("BlockDeviceMapping.2.DeviceName", "/dev/newdevice")
-           .addFormParam("BlockDeviceMapping.2.Ebs.DeleteOnTermination", 
"false")
-           .addFormParam("BlockDeviceMapping.2.Ebs.VolumeSize", "100")
-           .addFormParam("BlockDeviceMapping.2.VirtualName", "newblock")
-           .addFormParam("Description", "description")
-           .addFormParam("Name", "imageName")
-           .addFormParam("RootDeviceName", "/dev/sda1").build();
-
-   public void testRegisterImageBackedByEBSOptions() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, 
"registerUnixImageBackedByEbsInRegion", String.class,
-               String.class, String.class, 
RegisterImageBackedByEbsOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "imageName", "snapshotId",
-               new 
RegisterImageBackedByEbsOptions().withDescription("description").addBlockDeviceFromSnapshot(
-                        "/dev/device", null, "snapshot", false, "gp2", null, 
false).addNewBlockDevice("/dev/newdevice", "newblock", 100)));
-
-      request = (GeneratedHttpRequest) 
request.getFilters().get(0).filter(request);
-      
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
filter.filter(registerImageBackedByEBSOptions).getPayload().getRawContent()
-            .toString(), "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, ImageIdHandler.class);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   HttpRequest getBlockDeviceMappingsForImage = 
HttpRequest.builder().method("POST")
-                                                           
.endpoint("https://ec2.us-east-1.amazonaws.com/";)
-                                                           .addHeader("Host", 
"ec2.us-east-1.amazonaws.com")
-                                                           
.addFormParam("Action", "DescribeImageAttribute")
-                                                           
.addFormParam("Attribute", "blockDeviceMapping")
-                                                           
.addFormParam("ImageId", "imageId").build();
-
-   public void testGetBlockDeviceMappingsForImage() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, 
"getBlockDeviceMappingsForImageInRegion", String.class,
-               String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "imageId"));
-
-      request = (GeneratedHttpRequest) 
request.getFilters().get(0).filter(request);
-      
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
filter.filter(getBlockDeviceMappingsForImage).getPayload().getRawContent()
-            .toString(), "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, 
BlockDeviceMappingHandler.class);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   HttpRequest getLaunchPermissionForImage = 
HttpRequest.builder().method("POST")
-                                                        
.endpoint("https://ec2.us-east-1.amazonaws.com/";)
-                                                        .addHeader("Host", 
"ec2.us-east-1.amazonaws.com")
-                                                        
.addFormParam("Action", "DescribeImageAttribute")
-                                                        
.addFormParam("Attribute", "launchPermission")
-                                                        
.addFormParam("ImageId", "imageId").build();
-
-   public void testGetLaunchPermissionForImage() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, 
"getLaunchPermissionForImageInRegion", String.class, String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "imageId"));
-
-      request = (GeneratedHttpRequest) 
request.getFilters().get(0).filter(request);
-      
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
filter.filter(getLaunchPermissionForImage).getPayload().getRawContent().toString(),
-            "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, PermissionHandler.class);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   HttpRequest addLaunchPermission = HttpRequest.builder().method("POST")
-                                                          
.endpoint("https://ec2.us-east-1.amazonaws.com/";)
-                                                          .addHeader("Host", 
"ec2.us-east-1.amazonaws.com")
-                                                          
.addFormParam("Action", "ModifyImageAttribute")
-                                                          
.addFormParam("Attribute", "launchPermission")
-                                                          
.addFormParam("ImageId", "imageId")
-                                                          
.addFormParam("OperationType", "add")
-                                                          
.addFormParam("UserGroup.1", "all")
-                                                          
.addFormParam("UserId.1", "bob")
-                                                          
.addFormParam("UserId.2", "sue").build();
-
-   public void testAddLaunchPermissionsToImage() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, 
"addLaunchPermissionsToImageInRegion", String.class,
-               Iterable.class, Iterable.class, String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, ImmutableList.of("bob", "sue"), ImmutableList
-               .of("all"), "imageId"));
-
-      request = (GeneratedHttpRequest) 
request.getFilters().get(0).filter(request);
-      
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
filter.filter(addLaunchPermission).getPayload().getRawContent().toString(),
-            "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, 
ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   HttpRequest removeLaunchPermission = HttpRequest.builder().method("POST")
-                                                   
.endpoint("https://ec2.us-east-1.amazonaws.com/";)
-                                                   .addHeader("Host", 
"ec2.us-east-1.amazonaws.com")
-                                                   .addFormParam("Action", 
"ModifyImageAttribute")
-                                                   .addFormParam("Attribute", 
"launchPermission")
-                                                   .addFormParam("ImageId", 
"imageId")
-                                                   
.addFormParam("OperationType", "remove")
-                                                   
.addFormParam("UserGroup.1", "all")
-                                                   .addFormParam("UserId.1", 
"bob")
-                                                   .addFormParam("UserId.2", 
"sue").build();
-
-   public void testRemoveLaunchPermissionsFromImage() throws 
SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, 
"removeLaunchPermissionsFromImageInRegion", String.class,
-               Iterable.class, Iterable.class, String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, ImmutableList.of("bob", "sue"), ImmutableList
-               .of("all"), "imageId"));
-
-      request = (GeneratedHttpRequest) 
request.getFilters().get(0).filter(request);
-      
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
filter.filter(removeLaunchPermission).getPayload().getRawContent().toString(),
-            "application/x-www-form-urlencoded", false);
-      assertResponseParserClassEquals(method, request, 
ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   HttpRequest resetLaunchPermissionsOnImage = 
HttpRequest.builder().method("POST")
-                                                          
.endpoint("https://ec2.us-east-1.amazonaws.com/";)
-                                                          .addHeader("Host", 
"ec2.us-east-1.amazonaws.com")
-                                                          
.addFormParam("Action", "ResetImageAttribute")
-                                                          
.addFormParam("Attribute", "launchPermission")
-                                                          
.addFormParam("ImageId", "imageId").build();
-
-   public void testResetLaunchPermissionsOnImage() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, 
"resetLaunchPermissionsOnImageInRegion", String.class,
-               String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "imageId"));
-
-      request = (GeneratedHttpRequest) 
request.getFilters().get(0).filter(request);
-      
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request,
-            
filter.filter(resetLaunchPermissionsOnImage).getPayload().getRawContent().toString(),
-            "application/x-www-form-urlencoded", false);
-      assertResponseParserClassEquals(method, request, 
ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   public void testGetProductCodesForImage() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, 
"getProductCodesForImageInRegion", String.class, String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "imageId"));
-
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request,
-            
"Action=DescribeImageAttribute&Attribute=productCodes&ImageId=imageId",
-            "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, ProductCodesHandler.class);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   public void testAddProductCodesToImage() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, 
"addProductCodesToImageInRegion", String.class, Iterable.class,
-            String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, ImmutableList.of("code1", "code2"), 
"imageId"));
-
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(
-            request,
-            
"Action=ModifyImageAttribute&OperationType=add&Attribute=productCodes&ImageId=imageId&ProductCode.1=code1&ProductCode.2=code2",
-            "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, 
ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   public void testRemoveProductCodesFromImage() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AWSAMIApi.class, 
"removeProductCodesFromImageInRegion", String.class,
-            Iterable.class, String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, ImmutableList.of("code1", "code2"), 
"imageId"));
-
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(
-            request,
-            
"Action=ModifyImageAttribute&OperationType=remove&Attribute=productCodes&ImageId=imageId&ProductCode.1=code1&ProductCode.2=code2",
-            "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, 
ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/243b9679/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApiTest.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApiTest.java
 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApiTest.java
index 735af5b..2e73dfe 100644
--- 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApiTest.java
+++ 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApiTest.java
@@ -24,7 +24,6 @@ import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
 import org.jclouds.aws.ec2.xml.AWSEC2DescribeSecurityGroupsResponseHandler;
 import org.jclouds.ec2.util.IpPermissions;
-import org.jclouds.http.HttpRequest;
 import org.jclouds.http.functions.ParseSax;
 import org.jclouds.http.functions.ReleasePayloadAndReturn;
 import org.jclouds.net.domain.IpPermission;
@@ -97,13 +96,6 @@ public class AWSSecurityGroupApiTest extends 
BaseAWSEC2ApiTest<AWSSecurityGroupA
       checkFilters(request);
    }
 
-   HttpRequest createSecurityGroup = HttpRequest.builder().method("POST")
-                                                
.endpoint("https://ec2.us-east-1.amazonaws.com/";)
-                                                .addHeader("Host", 
"ec2.us-east-1.amazonaws.com")
-                                                .addFormParam("Action", 
"CreateSecurityGroup")
-                                                
.addFormParam("GroupDescription", "description")
-                                                .addFormParam("GroupName", 
"name").build();
-
    public void testCreateSecurityGroup() throws SecurityException, 
NoSuchMethodException, IOException {
       Invokable<?, ?> method = method(AWSSecurityGroupApi.class, 
"createSecurityGroupInRegion", String.class,
             String.class, String.class);
@@ -113,7 +105,7 @@ public class AWSSecurityGroupApiTest extends 
BaseAWSEC2ApiTest<AWSSecurityGroupA
 
       assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
       assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
filter.filter(createSecurityGroup).getPayload().getRawContent().toString(),
+      assertPayloadEquals(request, 
"Action=CreateSecurityGroup&GroupName=name&GroupDescription=description&Version=2012-06-01",
             "application/x-www-form-urlencoded", false);
 
       assertResponseParserClassEquals(method, request, 
ReleasePayloadAndReturn.class);

http://git-wip-us.apache.org/repos/asf/jclouds/blob/243b9679/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/BaseAWSEC2ApiTest.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/BaseAWSEC2ApiTest.java
 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/BaseAWSEC2ApiTest.java
index caf6e48..349b780 100644
--- 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/BaseAWSEC2ApiTest.java
+++ 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/BaseAWSEC2ApiTest.java
@@ -17,7 +17,10 @@
 package org.jclouds.aws.ec2.features;
 
 import static com.google.common.collect.Maps.transformValues;
+import static com.google.common.net.HttpHeaders.AUTHORIZATION;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
 
 import java.io.IOException;
 import java.net.URI;
@@ -29,7 +32,8 @@ import javax.inject.Singleton;
 import org.jclouds.aws.domain.Region;
 import org.jclouds.aws.ec2.AWSEC2ProviderMetadata;
 import org.jclouds.aws.ec2.config.AWSEC2HttpApiModule;
-import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.aws.filters.FormSignerV4;
+import org.jclouds.aws.filters.FormSignerV4.ServiceAndRegion;
 import org.jclouds.compute.domain.Image;
 import org.jclouds.date.DateService;
 import org.jclouds.ec2.compute.domain.RegionAndName;
@@ -49,18 +53,20 @@ import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
 import com.google.inject.Module;
 import com.google.inject.Provides;
 
 @Test(groups = "unit")
 public abstract class BaseAWSEC2ApiTest<T> extends 
BaseRestAnnotationProcessingTest<T> {
 
-      @ConfiguresHttpApi
+   @ConfiguresHttpApi
    protected static class StubAWSEC2HttpApiModule extends AWSEC2HttpApiModule {
 
       @Override
       protected String provideTimeStamp(DateService dateService) {
-         return "2009-11-08T15:54:08.897Z";
+         return "20120416T155408Z";
       }
 
       @Provides
@@ -83,10 +89,10 @@ public abstract class BaseAWSEC2ApiTest<T> extends 
BaseRestAnnotationProcessingT
 
             @Override
             public Map<String, Supplier<URI>> get() {
-               return transformValues(ImmutableMap.<String, URI> 
of(Region.EU_WEST_1, URI
-                        .create("https://ec2.eu-west-1.amazonaws.com";), 
Region.US_EAST_1, URI
-                        .create("https://ec2.us-east-1.amazonaws.com";), 
Region.US_WEST_1, URI
-                        .create("https://ec2.us-west-1.amazonaws.com";)), 
Suppliers2.<URI> ofInstanceFunction());
+               return transformValues(ImmutableMap
+                     .<String, URI>of(Region.EU_WEST_1, 
URI.create("https://ec2.eu-west-1.amazonaws.com";),
+                           Region.US_EAST_1, 
URI.create("https://ec2.us-east-1.amazonaws.com";), Region.US_WEST_1,
+                           URI.create("https://ec2.us-west-1.amazonaws.com";)), 
Suppliers2.<URI>ofInstanceFunction());
             }
 
          });
@@ -100,21 +106,49 @@ public abstract class BaseAWSEC2ApiTest<T> extends 
BaseRestAnnotationProcessingT
 
          });
       }
+
+      @Provides ServiceAndRegion ServiceAndRegion(){
+         return new ServiceAndRegion() {
+            @Override public String service() {
+               return "ec2";
+            }
+
+            @Override public String region(String host) {
+               return "us-east-1";
+            }
+         };
+      }
+   }
+
+   @Override protected void assertNonPayloadHeadersEqual(HttpRequest request, 
String toMatch) {
+      Multimap<String, String> headersToCheck = LinkedHashMultimap.create();
+      for (String key : request.getHeaders().keySet()) {
+         if (key.equals("X-Amz-Date")) {
+            assertEquals(request.getFirstHeaderOrNull(key), 
"20120416T155408Z");
+         } else if (key.equals("Authorization")) {
+            assertThat(request.getFirstHeaderOrNull(AUTHORIZATION)).startsWith(
+                  "AWS4-HMAC-SHA256 Credential=identity/20120416/"
+                        + "us-east-1/ec2/aws4_request, 
SignedHeaders=content-type;host;x-amz-date, Signature=");
+         } else {
+            headersToCheck.putAll(key, request.getHeaders().get(key));
+         }
+      }
+      assertEquals(sortAndConcatHeadersIntoString(headersToCheck), toMatch);
    }
 
-   protected FormSigner filter;
+   protected FormSignerV4 filter;
 
    @Override
    protected void checkFilters(HttpRequest request) {
       assertEquals(request.getFilters().size(), 1);
-      assertEquals(request.getFilters().get(0).getClass(), FormSigner.class);
+      assertTrue(request.getFilters().get(0) instanceof FormSignerV4);
    }
 
    @Override
    @BeforeTest
    protected void setupFactory() throws IOException {
       super.setupFactory();
-      this.filter = injector.getInstance(FormSigner.class);
+      this.filter = injector.getInstance(FormSignerV4.class);
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/jclouds/blob/243b9679/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/MonitoringApiMockTest.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/MonitoringApiMockTest.java
 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/MonitoringApiMockTest.java
new file mode 100644
index 0000000..cad674c
--- /dev/null
+++ 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/MonitoringApiMockTest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.features;
+
+import static org.testng.Assert.assertFalse;
+
+import java.util.Map;
+
+import org.jclouds.aws.ec2.domain.MonitoringState;
+import org.jclouds.aws.ec2.internal.BaseAWSEC2ApiMockTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "MonitoringApiMockTest", singleThreaded = 
true)
+public class MonitoringApiMockTest extends BaseAWSEC2ApiMockTest {
+
+   public void monitorInstancesInRegion() throws Exception {
+      enqueueRegions(DEFAULT_REGION);
+      enqueueXml(DEFAULT_REGION, "/monitoring.xml");
+
+      Map<String, MonitoringState> result = monitoringApi()
+            .monitorInstancesInRegion(DEFAULT_REGION, "i-911444f0", 
"i-911444f1");
+
+      assertFalse(result.isEmpty());
+
+      assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
+      assertPosted(DEFAULT_REGION, 
"Action=MonitorInstances&InstanceId.0=i-911444f0&InstanceId.1=i-911444f1");
+   }
+
+   public void unmonitorInstancesInRegion() throws Exception {
+      enqueueRegions(DEFAULT_REGION);
+      enqueueXml(DEFAULT_REGION, "/monitoring.xml");
+
+      Map<String, MonitoringState> result = monitoringApi()
+            .unmonitorInstancesInRegion(DEFAULT_REGION, "i-911444f0", 
"i-911444f1");
+
+      assertFalse(result.isEmpty());
+      assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
+      assertPosted(DEFAULT_REGION, 
"Action=UnmonitorInstances&InstanceId.0=i-911444f0&InstanceId.1=i-911444f1");
+   }
+
+   private MonitoringApi monitoringApi() {
+      return api().getMonitoringApi().get();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/243b9679/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/MonitoringApiTest.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/MonitoringApiTest.java
 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/MonitoringApiTest.java
deleted file mode 100644
index 23b9d62..0000000
--- 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/MonitoringApiTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF 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.features;
-
-import static org.jclouds.reflect.Reflection2.method;
-
-import java.io.IOException;
-
-import org.jclouds.aws.ec2.xml.MonitoringStateHandler;
-import org.jclouds.http.functions.ParseSax;
-import org.jclouds.rest.internal.GeneratedHttpRequest;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.Lists;
-import com.google.common.reflect.Invokable;
-/**
- * Tests behavior of {@code MonitoringApi}
- */
-// NOTE:without testName, this will not call @Before* and fail w/NPE during 
surefire
-@Test(groups = "unit", testName = "MonitoringApiTest")
-public class MonitoringApiTest extends BaseAWSEC2ApiTest<MonitoringApi> {
-
-   public void testUnmonitorInstances() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(MonitoringApi.class, 
"unmonitorInstancesInRegion", String.class, String.class,
-            String[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "instance1", "instance2"));
-
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      String payload = 
"Action=UnmonitorInstances&InstanceId.0=instance1&InstanceId.1=instance2";
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, payload, 
"application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, MonitoringStateHandler.class);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   public void testMonitorInstances() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(MonitoringApi.class, 
"monitorInstancesInRegion", String.class, String.class,
-            String[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "instance1", "instance2"));
-
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request,
-            
"Action=MonitorInstances&InstanceId.0=instance1&InstanceId.1=instance2",
-            "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, MonitoringStateHandler.class);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/243b9679/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/PlacementGroupApiExpectTest.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/PlacementGroupApiExpectTest.java
 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/PlacementGroupApiExpectTest.java
deleted file mode 100644
index 77d51de..0000000
--- 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/PlacementGroupApiExpectTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF 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.features;
-
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static org.testng.Assert.assertEquals;
-
-import org.jclouds.aws.ec2.AWSEC2Api;
-import org.jclouds.aws.ec2.compute.internal.BaseAWSEC2ComputeServiceExpectTest;
-import org.jclouds.aws.ec2.domain.PlacementGroup;
-import org.jclouds.http.HttpRequest;
-import org.jclouds.http.HttpResponse;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableSet;
-
-@Test(groups = "unit", testName = "PlacementGroupApiExpectTest")
-public class PlacementGroupApiExpectTest extends 
BaseAWSEC2ComputeServiceExpectTest {
-
-   HttpRequest filter = HttpRequest.builder().method("POST")
-           .endpoint("https://ec2.us-east-1.amazonaws.com/";)
-           .addHeader("Host", "ec2.us-east-1.amazonaws.com")
-           .addFormParam("Action", "DescribePlacementGroups")
-           .addFormParam("Filter.1.Name", "strategy")
-           .addFormParam("Filter.1.Value.1", "cluster")
-           .addFormParam("Signature", 
"SaA7Un1BE3m9jIEKyjXNdQPzFh/QAJSCebvKXiwUEK0%3D")
-           .addFormParam("SignatureMethod", "HmacSHA256")
-           .addFormParam("SignatureVersion", "2")
-           .addFormParam("Timestamp", "2012-04-16T15%3A54%3A08.897Z")
-           .addFormParam("Version", "2012-06-01")
-           .addFormParam("AWSAccessKeyId", "identity").build();
-
-   public void testFilterWhenResponseIs2xx() {
-      HttpResponse filterResponse = HttpResponse.builder().statusCode(200)
-              
.payload(payloadFromResourceWithContentType("/describe_placement_groups.xml", 
"text/xml")).build();
-
-      AWSEC2Api apiWhenExist = requestsSendResponses(describeRegionsRequest, 
describeRegionsResponse, filter, filterResponse)
-              .getContext().unwrapApi(AWSEC2Api.class);
-
-      PlacementGroup group = 
getOnlyElement(apiWhenExist.getPlacementGroupApi().get().describePlacementGroupsInRegionWithFilter("us-east-1",
-              ImmutableMultimap.<String, String>builder()
-                      .put("strategy", "cluster")
-                      .build()));
-
-      assertEquals(group.getName(), "XYZ-cluster");
-   }
-
-   public void testFilterWhenResponseIs404() {
-      HttpResponse filterResponse = 
HttpResponse.builder().statusCode(404).build();
-
-      AWSEC2Api apiWhenNotExist = 
requestsSendResponses(describeRegionsRequest, describeRegionsResponse, filter, 
filterResponse)
-              .getContext().unwrapApi(AWSEC2Api.class);
-
-      
assertEquals(apiWhenNotExist.getPlacementGroupApi().get().describePlacementGroupsInRegionWithFilter("us-east-1",
-              ImmutableMultimap.<String, String>builder()
-                      .put("strategy", "cluster")
-                      .build()),
-              ImmutableSet.of());
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/243b9679/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/PlacementGroupApiMockTest.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/PlacementGroupApiMockTest.java
 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/PlacementGroupApiMockTest.java
new file mode 100644
index 0000000..b94c6c3
--- /dev/null
+++ 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/PlacementGroupApiMockTest.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.features;
+
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static org.testng.Assert.assertEquals;
+
+import org.jclouds.aws.ec2.domain.PlacementGroup;
+import org.jclouds.aws.ec2.internal.BaseAWSEC2ApiMockTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.squareup.okhttp.mockwebserver.MockResponse;
+
+@Test(groups = "unit", testName = "PlacementGroupApiMockTest", singleThreaded 
= true)
+public class PlacementGroupApiMockTest extends BaseAWSEC2ApiMockTest {
+
+   public void describePlacementGroupsInRegionWithFilter() throws Exception {
+      enqueueRegions(DEFAULT_REGION);
+      enqueueXml(DEFAULT_REGION, "/describe_placement_groups.xml");
+
+      PlacementGroup result = getOnlyElement(placementApi()
+            .describePlacementGroupsInRegionWithFilter(DEFAULT_REGION, 
ImmutableMultimap.of("strategy", "cluster")));
+
+      assertEquals(result.getName(), "XYZ-cluster");
+
+      assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
+      assertPosted(DEFAULT_REGION, 
"Action=DescribePlacementGroups&Filter.1.Name=strategy&Filter.1.Value.1=cluster");
+   }
+
+   public void describePlacementGroupsInRegionWithFilter_404() throws 
Exception {
+      enqueueRegions(DEFAULT_REGION);
+      enqueue(DEFAULT_REGION, new MockResponse().setResponseCode(404));
+
+      
assertEquals(placementApi().describePlacementGroupsInRegionWithFilter(DEFAULT_REGION,
+                  ImmutableMultimap.of("strategy", "cluster")), 
ImmutableSet.of());
+
+      assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
+      assertPosted(DEFAULT_REGION, 
"Action=DescribePlacementGroups&Filter.1.Name=strategy&Filter.1.Value.1=cluster");
+   }
+
+   public void deletePlacementGroupInRegion() throws Exception {
+      enqueueRegions(DEFAULT_REGION);
+      enqueue(DEFAULT_REGION, new MockResponse());
+
+      placementApi().deletePlacementGroupInRegion(DEFAULT_REGION, "name");
+
+      assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
+      assertPosted(DEFAULT_REGION, 
"Action=DeletePlacementGroup&GroupName=name");
+   }
+
+   public void deletePlacementGroupInRegion_404() throws Exception {
+      enqueueRegions(DEFAULT_REGION);
+      enqueue(DEFAULT_REGION, new MockResponse().setResponseCode(404));
+
+      placementApi().deletePlacementGroupInRegion(DEFAULT_REGION, "name");
+
+      assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
+      assertPosted(DEFAULT_REGION, 
"Action=DeletePlacementGroup&GroupName=name");
+   }
+
+   public void createPlacementGroupInRegion() throws Exception {
+      enqueueRegions(DEFAULT_REGION);
+      enqueue(DEFAULT_REGION, new MockResponse());
+
+      placementApi().createPlacementGroupInRegion(DEFAULT_REGION, "name");
+
+      assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
+      assertPosted(DEFAULT_REGION, 
"Action=CreatePlacementGroup&Strategy=cluster&GroupName=name");
+   }
+
+   public void createPlacementGroupInRegion_strategy() throws Exception {
+      enqueueRegions(DEFAULT_REGION);
+      enqueue(DEFAULT_REGION, new MockResponse());
+
+      placementApi().createPlacementGroupInRegion(DEFAULT_REGION, "name", 
"cluster");
+
+      assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
+      assertPosted(DEFAULT_REGION, 
"Action=CreatePlacementGroup&GroupName=name&Strategy=cluster");
+   }
+
+   private PlacementGroupApi placementApi() {
+      return api().getPlacementGroupApi().get();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/243b9679/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/PlacementGroupApiTest.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/PlacementGroupApiTest.java
 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/PlacementGroupApiTest.java
deleted file mode 100644
index 76bd954..0000000
--- 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/PlacementGroupApiTest.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF 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.features;
-
-import static org.jclouds.reflect.Reflection2.method;
-
-import java.io.IOException;
-
-import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
-import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import org.jclouds.aws.ec2.xml.DescribePlacementGroupsResponseHandler;
-import org.jclouds.http.HttpRequest;
-import org.jclouds.http.functions.ParseSax;
-import org.jclouds.http.functions.ReleasePayloadAndReturn;
-import org.jclouds.rest.internal.GeneratedHttpRequest;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.Lists;
-import com.google.common.reflect.Invokable;
-/**
- * Tests behavior of {@code PlacementGroupApi}
- */
-// NOTE:without testName, this will not call @Before* and fail w/NPE during 
surefire
-@Test(groups = "unit", testName = "PlacementGroupApiTest")
-public class PlacementGroupApiTest extends 
BaseAWSEC2ApiTest<PlacementGroupApi> {
-
-   public void testDeletePlacementGroup() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(PlacementGroupApi.class, 
"deletePlacementGroupInRegion", String.class,
-               String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "name"));
-
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
"Action=DeletePlacementGroup&GroupName=name",
-               "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, 
ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, VoidOnNotFoundOr404.class);
-
-      checkFilters(request);
-   }
-
-   HttpRequest createPlacementGroup = HttpRequest.builder().method("POST")
-                                                 
.endpoint("https://ec2.us-east-1.amazonaws.com/";)
-                                                 .addHeader("Host", 
"ec2.us-east-1.amazonaws.com")
-                                                 .addFormParam("Action", 
"CreatePlacementGroup")
-                                                 .addFormParam("GroupName", 
"name")
-                                                 .addFormParam("Strategy", 
"cluster").build();
-
-   public void testCreatePlacementGroup() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(PlacementGroupApi.class, 
"createPlacementGroupInRegion", String.class,
-               String.class, String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "name", "cluster"));
-
-      request = (GeneratedHttpRequest) 
request.getFilters().get(0).filter(request);
-      
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
filter.filter(createPlacementGroup).getPayload().getRawContent().toString(),
-            "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, 
ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   public void testCreatePlacementGroupDefault() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(PlacementGroupApi.class, 
"createPlacementGroupInRegion", String.class,
-               String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "name"));
-
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
"Action=CreatePlacementGroup&Strategy=cluster&GroupName=name",
-               "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, 
ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   public void testDescribePlacementGroups() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(PlacementGroupApi.class, 
"describePlacementGroupsInRegion", String.class,
-               String[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList((String) null));
-
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, "Action=DescribePlacementGroups",
-               "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, 
DescribePlacementGroupsResponseHandler.class);
-      assertFallbackClassEquals(method, EmptySetOnNotFoundOr404.class);
-
-      checkFilters(request);
-   }
-
-   public void testDescribePlacementGroupsArgs() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(PlacementGroupApi.class, 
"describePlacementGroupsInRegion", String.class,
-               String[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "1", "2"));
-
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
"Action=DescribePlacementGroups&GroupName.1=1&GroupName.2=2",
-               "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, 
DescribePlacementGroupsResponseHandler.class);
-      assertFallbackClassEquals(method, EmptySetOnNotFoundOr404.class);
-
-      checkFilters(request);
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/243b9679/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/SpotInstanceApiExpectTest.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/SpotInstanceApiExpectTest.java
 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/SpotInstanceApiExpectTest.java
deleted file mode 100644
index 7460505..0000000
--- 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/SpotInstanceApiExpectTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF 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.features;
-
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static org.testng.Assert.assertEquals;
-
-import org.jclouds.aws.ec2.AWSEC2Api;
-import org.jclouds.aws.ec2.compute.internal.BaseAWSEC2ComputeServiceExpectTest;
-import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
-import org.jclouds.http.HttpRequest;
-import org.jclouds.http.HttpResponse;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableSet;
-
-@Test(groups = "unit", testName = "SpotInstanceApiExpectTest")
-public class SpotInstanceApiExpectTest extends 
BaseAWSEC2ComputeServiceExpectTest {
-
-   HttpRequest filter = HttpRequest.builder().method("POST")
-           .endpoint("https://ec2.us-east-1.amazonaws.com/";)
-           .addHeader("Host", "ec2.us-east-1.amazonaws.com")
-           .addFormParam("Action", "DescribeSpotInstanceRequests")
-           .addFormParam("Filter.1.Name", "instance-id")
-           .addFormParam("Filter.1.Value.1", "i-ef308e8e")
-           .addFormParam("Signature", 
"wQtGpumMCDEzvlldKepCKeEjD9iE7eAyiRBlQztcJMA%3D")
-           .addFormParam("SignatureMethod", "HmacSHA256")
-           .addFormParam("SignatureVersion", "2")
-           .addFormParam("Timestamp", "2012-04-16T15%3A54%3A08.897Z")
-           .addFormParam("Version", "2012-06-01")
-           .addFormParam("AWSAccessKeyId", "identity").build();
-
-   public void testFilterWhenResponseIs2xx() {
-      HttpResponse filterResponse = HttpResponse.builder().statusCode(200)
-              
.payload(payloadFromResourceWithContentType("/describe_spot_instance.xml", 
"text/xml")).build();
-
-      AWSEC2Api apiWhenExist = requestsSendResponses(describeRegionsRequest, 
describeRegionsResponse, filter, filterResponse)
-              .getContext().unwrapApi(AWSEC2Api.class);
-
-      SpotInstanceRequest request = 
getOnlyElement(apiWhenExist.getSpotInstanceApi().get().describeSpotInstanceRequestsInRegionWithFilter("us-east-1",
-              ImmutableMultimap.<String, String>builder()
-                      .put("instance-id", "i-ef308e8e")
-                      .build()));
-
-      assertEquals(request.getId(), "sir-1ede0012");
-   }
-
-   public void testFilterWhenResponseIs404() {
-      HttpResponse filterResponse = 
HttpResponse.builder().statusCode(404).build();
-
-      AWSEC2Api apiWhenNotExist = 
requestsSendResponses(describeRegionsRequest, describeRegionsResponse, filter, 
filterResponse)
-              .getContext().unwrapApi(AWSEC2Api.class);
-
-      
assertEquals(apiWhenNotExist.getSpotInstanceApi().get().describeSpotInstanceRequestsInRegionWithFilter("us-east-1",
-              ImmutableMultimap.<String, String>builder()
-                      .put("instance-id", "i-ef308e8e")
-                      .build()),
-              ImmutableSet.of());
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/243b9679/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/SpotInstanceApiMockTest.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/SpotInstanceApiMockTest.java
 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/SpotInstanceApiMockTest.java
new file mode 100644
index 0000000..5863059
--- /dev/null
+++ 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/SpotInstanceApiMockTest.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.features;
+
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static 
org.jclouds.aws.ec2.options.DescribeSpotPriceHistoryOptions.Builder.from;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Date;
+import java.util.Set;
+
+import org.jclouds.aws.ec2.domain.Spot;
+import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
+import org.jclouds.aws.ec2.internal.BaseAWSEC2ApiMockTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.squareup.okhttp.mockwebserver.MockResponse;
+
+   @Test(groups = "unit", testName = "SpotInstanceApiMockTest", singleThreaded 
= true)
+   public class SpotInstanceApiMockTest extends BaseAWSEC2ApiMockTest {
+
+      public void describeSpotInstanceRequestsInRegionWithFilter() throws 
Exception {
+         enqueueRegions(DEFAULT_REGION);
+         enqueueXml(DEFAULT_REGION, "/describe_spot_instance.xml");
+
+         SpotInstanceRequest result = getOnlyElement(spotApi()
+               .describeSpotInstanceRequestsInRegionWithFilter(DEFAULT_REGION,
+                     ImmutableMultimap.of("instance-id", "i-ef308e8e")));
+
+         assertEquals(result.getId(), "sir-1ede0012");
+
+         assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
+         assertPosted(DEFAULT_REGION, 
"Action=DescribeSpotInstanceRequests&Filter.1.Name=instance-id&Filter.1.Value.1=i-ef308e8e");
+      }
+
+      public void describeSpotInstanceRequestsInRegionWithFilter_404() throws 
Exception {
+         enqueueRegions(DEFAULT_REGION);
+         enqueue(DEFAULT_REGION, new MockResponse().setResponseCode(404));
+
+         
assertEquals(spotApi().describeSpotInstanceRequestsInRegionWithFilter(DEFAULT_REGION,
+               ImmutableMultimap.of("instance-id", "i-ef308e8e")), 
ImmutableSet.of());
+
+         assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
+         assertPosted(DEFAULT_REGION, 
"Action=DescribeSpotInstanceRequests&Filter.1.Name=instance-id&Filter.1.Value.1=i-ef308e8e");
+      }
+
+      public void cancelSpotInstanceRequestsInRegion() throws Exception {
+         enqueueRegions(DEFAULT_REGION);
+         enqueue(DEFAULT_REGION, new MockResponse());
+
+         spotApi().cancelSpotInstanceRequestsInRegion(DEFAULT_REGION, 
"sir-f4d44212");
+
+         assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
+         assertPosted(DEFAULT_REGION, 
"Action=CancelSpotInstanceRequests&SpotInstanceRequestId.1=sir-f4d44212");
+      }
+
+      public void cancelSpotInstanceRequestsInRegion_404() throws Exception {
+         enqueueRegions(DEFAULT_REGION);
+         enqueue(DEFAULT_REGION, new MockResponse().setResponseCode(404));
+
+         spotApi().cancelSpotInstanceRequestsInRegion(DEFAULT_REGION, 
"sir-f4d44212");
+
+         assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
+         assertPosted(DEFAULT_REGION, 
"Action=CancelSpotInstanceRequests&SpotInstanceRequestId.1=sir-f4d44212");
+      }
+
+      public void describeSpotPriceHistoryInRegion() throws Exception {
+         enqueueRegions(DEFAULT_REGION);
+         enqueueXml(DEFAULT_REGION, "/describe_spot_price_history.xml");
+
+         Set<Spot> result = 
spotApi().describeSpotPriceHistoryInRegion(DEFAULT_REGION);
+
+         assertEquals(result.size(), 3);
+
+         assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
+         assertPosted(DEFAULT_REGION, "Action=DescribeSpotPriceHistory");
+      }
+
+      public void describeSpotPriceHistoryInRegion_404() throws Exception {
+         enqueueRegions(DEFAULT_REGION);
+         enqueue(DEFAULT_REGION, new MockResponse().setResponseCode(404));
+
+         Set<Spot> result = 
spotApi().describeSpotPriceHistoryInRegion(DEFAULT_REGION);
+
+         assertTrue(result.isEmpty());
+
+         assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
+         assertPosted(DEFAULT_REGION, "Action=DescribeSpotPriceHistory");
+      }
+
+      public void describeSpotPriceHistoryInRegionOptions() throws Exception {
+         enqueueRegions(DEFAULT_REGION);
+         enqueueXml(DEFAULT_REGION, "/describe_spot_price_history.xml");
+
+         Date from = new Date(12345678910l);
+         Date to = new Date(1234567891011l);
+
+         Set<Spot> result = 
spotApi().describeSpotPriceHistoryInRegion(DEFAULT_REGION,
+               
from(from).to(to).productDescription("description").instanceType("m1.small"));
+
+         assertEquals(result.size(), 3);
+
+         assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
+         assertPosted(DEFAULT_REGION, 
"Action=DescribeSpotPriceHistory&StartTime=1970-05-23T21%3A21%3A18.910Z&EndTime=2009-02-13T23%3A31%3A31.011Z&ProductDescription=description&InstanceType.1=m1.small");
+      }
+
+      private SpotInstanceApi spotApi() {
+         return api().getSpotInstanceApi().get();
+      }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/243b9679/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/SpotInstanceApiTest.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/SpotInstanceApiTest.java
 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/SpotInstanceApiTest.java
deleted file mode 100644
index 5337ca8..0000000
--- 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/SpotInstanceApiTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF 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.features;
-
-import static org.jclouds.reflect.Reflection2.method;
-
-import java.io.IOException;
-import java.util.Date;
-
-import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
-import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import org.jclouds.aws.ec2.options.DescribeSpotPriceHistoryOptions;
-import org.jclouds.aws.ec2.xml.DescribeSpotPriceHistoryResponseHandler;
-import org.jclouds.http.functions.ParseSax;
-import org.jclouds.http.functions.ReleasePayloadAndReturn;
-import org.jclouds.rest.internal.GeneratedHttpRequest;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.Lists;
-import com.google.common.reflect.Invokable;
-/**
- * Tests behavior of {@code SpotInstanceApi}
- */
-// NOTE:without testName, this will not call @Before* and fail w/NPE during 
surefire
-@Test(groups = "unit", testName = "SpotInstanceApiTest")
-public class SpotInstanceApiTest extends BaseAWSEC2ApiTest<SpotInstanceApi> {
-
-   public void testCancelSpotInstanceRequests() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(SpotInstanceApi.class, 
"cancelSpotInstanceRequestsInRegion", String.class,
-            String[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, "id"));
-
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, 
"Action=CancelSpotInstanceRequests&SpotInstanceRequestId.1=id",
-            "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, 
ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, VoidOnNotFoundOr404.class);
-
-      checkFilters(request);
-   }
-
-   public void testDescribeSpotPriceHistory() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(SpotInstanceApi.class, 
"describeSpotPriceHistoryInRegion", String.class,
-            DescribeSpotPriceHistoryOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList((String) null));
-
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(request, "Action=DescribeSpotPriceHistory",
-            "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, 
DescribeSpotPriceHistoryResponseHandler.class);
-      assertFallbackClassEquals(method, EmptySetOnNotFoundOr404.class);
-
-      checkFilters(request);
-   }
-
-   Date from = new Date(12345678910l);
-   Date to = new Date(1234567891011l);
-
-   public void testDescribeSpotPriceHistoryArgs() throws SecurityException, 
NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(SpotInstanceApi.class, 
"describeSpotPriceHistoryInRegion", String.class,
-            DescribeSpotPriceHistoryOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, 
Lists.<Object> newArrayList(null, 
DescribeSpotPriceHistoryOptions.Builder.from(from)
-            
.to(to).productDescription("description").instanceType("m1.small")));
-
-      assertRequestLineEquals(request, "POST 
https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "Host: 
ec2.us-east-1.amazonaws.com\n");
-      assertPayloadEquals(
-            request,
-            
"Action=DescribeSpotPriceHistory&StartTime=1970-05-23T21%3A21%3A18.910Z&EndTime=2009-02-13T23%3A31%3A31.011Z&ProductDescription=description&InstanceType.1=m1.small",
-            "application/x-www-form-urlencoded", false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, 
DescribeSpotPriceHistoryResponseHandler.class);
-      assertFallbackClassEquals(method, EmptySetOnNotFoundOr404.class);
-
-      checkFilters(request);
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/243b9679/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/internal/BaseAWSEC2ApiMockTest.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/internal/BaseAWSEC2ApiMockTest.java
 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/internal/BaseAWSEC2ApiMockTest.java
new file mode 100644
index 0000000..bc21706
--- /dev/null
+++ 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/internal/BaseAWSEC2ApiMockTest.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.internal;
+
+import static com.google.common.base.Throwables.propagate;
+import static com.google.common.net.HttpHeaders.AUTHORIZATION;
+import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
+import static 
com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
+import static javax.ws.rs.core.MediaType.APPLICATION_XML;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.jclouds.aws.filters.FormSignerV4.ServiceAndRegion;
+import static org.jclouds.util.Strings2.toStringAndClose;
+import static org.testng.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.jclouds.Constants;
+import org.jclouds.ContextBuilder;
+import org.jclouds.aws.ec2.AWSEC2Api;
+import org.jclouds.aws.ec2.AWSEC2ProviderMetadata;
+import org.jclouds.aws.ec2.config.AWSEC2HttpApiModule;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.concurrent.config.ExecutorServiceModule;
+import org.jclouds.date.DateService;
+import org.jclouds.rest.ConfiguresHttpApi;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.inject.Module;
+import com.google.inject.Provides;
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import com.squareup.okhttp.mockwebserver.MockWebServer;
+import com.squareup.okhttp.mockwebserver.RecordedRequest;
+
+/**
+ * Tests need to run {@code singleThreaded = true) as otherwise tests will 
clash on the regionToServers field.
+ * Sharing the regionToServers field means less code to write.
+ */
+public class BaseAWSEC2ApiMockTest {
+   protected static final String DEFAULT_REGION = "us-east-1";
+
+   // Example keys from 
http://docs.aws.amazon.com/general/latest/gr/signature-version-2.html
+   private static final String ACCESS_KEY = "AKIAIOSFODNN7EXAMPLE";
+   private static final String SECRET_KEY = 
"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY";
+
+   private Map<String, MockWebServer> regionToServers = 
Maps.newLinkedHashMap();
+
+   protected AWSEC2Api api() {
+      return builder(new Properties()).buildApi(AWSEC2Api.class);
+   }
+
+   protected ComputeService computeService() {
+      return builder(new 
Properties()).buildView(ComputeServiceContext.class).getComputeService();
+   }
+
+   protected ContextBuilder builder(Properties overrides) {
+      overrides.setProperty(Constants.PROPERTY_MAX_RETRIES, "1");
+      return ContextBuilder.newBuilder(new AWSEC2ProviderMetadata())
+            .credentials(ACCESS_KEY, SECRET_KEY)
+            .endpoint("http://localhost:"; + 
regionToServers.get(DEFAULT_REGION).getPort())
+            .overrides(overrides)
+            .modules(modules);
+   }
+
+   private final Set<Module> modules = ImmutableSet
+         .<Module>of(new MockAWSEC2HttpApiModule(), new 
ExecutorServiceModule(sameThreadExecutor()));
+
+   @ConfiguresHttpApi
+   class MockAWSEC2HttpApiModule extends AWSEC2HttpApiModule {
+
+      @Override
+      protected String provideTimeStamp(DateService dateService) {
+         return "20120416T155408Z";
+      }
+
+      @Provides ServiceAndRegion serviceAndRegion(){
+         return new ServiceAndRegion() {
+            @Override public String service() {
+               return "ec2";
+            }
+
+            @Override public String region(String host) {
+               for (Map.Entry<String, MockWebServer> regionToServer : 
regionToServers.entrySet()) {
+                  if (host.equals("localhost:" + 
regionToServer.getValue().getPort())) {
+                     return regionToServer.getKey();
+                  }
+               }
+               throw new IllegalStateException(host + " not found");
+            }
+         };
+      }
+   }
+
+   @BeforeMethod
+   public void start() throws IOException {
+      MockWebServer server = new MockWebServer();
+      server.play();
+      regionToServers.put(DEFAULT_REGION, server);
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void stop() throws IOException {
+      for (MockWebServer server : regionToServers.values()) {
+         server.shutdown();
+      }
+   }
+
+   protected void enqueue(String region, MockResponse response) {
+      regionToServers.get(region).enqueue(response);
+   }
+
+   protected void enqueueRegions(String... regions) throws IOException {
+      StringBuilder describeRegionsResponse = new StringBuilder();
+      describeRegionsResponse.append("<DescribeRegionsResponse>");
+      for (String region : regions) {
+         describeRegionsResponse.append("<item>");
+         
describeRegionsResponse.append("<regionName>").append(region).append("</regionName>");
+         if (!regionToServers.containsKey(region)) {
+            MockWebServer server = new MockWebServer();
+            server.play();
+            regionToServers.put(region, server);
+         }
+         String regionEndpoint = "http://localhost:"; + 
regionToServers.get(region).getPort();
+         
describeRegionsResponse.append("<regionEndpoint>").append(regionEndpoint).append("</regionEndpoint>");
+         describeRegionsResponse.append("</item>");
+      }
+      describeRegionsResponse.append("</DescribeRegionsResponse>");
+      enqueue(DEFAULT_REGION,
+            new MockResponse().addHeader(CONTENT_TYPE, 
APPLICATION_XML).setBody(describeRegionsResponse.toString()));
+   }
+
+   protected void enqueueXml(String region, String resource) {
+      enqueue(region,
+            new MockResponse().addHeader(CONTENT_TYPE, 
APPLICATION_XML).setBody(stringFromResource(resource)));
+   }
+
+   protected String stringFromResource(String resourceName) {
+      try {
+         return toStringAndClose(getClass().getResourceAsStream(resourceName));
+      } catch (IOException e) {
+         throw propagate(e);
+      }
+   }
+
+   protected RecordedRequest assertPosted(String region, String postParams) 
throws InterruptedException {
+      RecordedRequest request = regionToServers.get(region).takeRequest();
+      assertEquals(request.getMethod(), "POST");
+      assertEquals(request.getPath(), "/");
+      assertEquals(request.getHeader("X-Amz-Date"), "20120416T155408Z");
+      assertThat(
+            request.getHeader(AUTHORIZATION)).startsWith("AWS4-HMAC-SHA256 
Credential=AKIAIOSFODNN7EXAMPLE/20120416/" +
+            region + "/ec2/aws4_request, 
SignedHeaders=content-type;host;x-amz-date, Signature=");
+      String body = new String(request.getBody(), Charsets.UTF_8);
+      assertThat(body).contains("&Version=2012-06-01");
+      assertEquals(body.replace("&Version=2012-06-01", ""), postParams);
+      return request;
+   }
+}

Reply via email to