http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AMIApiTest.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AMIApiTest.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AMIApiTest.java new file mode 100644 index 0000000..842a48b --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AMIApiTest.java @@ -0,0 +1,519 @@ +/* + * 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.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.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 AMIApi} + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +@Test(groups = "unit", testName = "AMIApiTest") +public class AMIApiTest extends BaseEC2ApiTest<AMIApi> { + + 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") + .addFormParam("Signature", "MuMtOMs697BLVks2RUZUNeLdVCo6NXPHuDhh0nmNtvc%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testCreateImage() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AMIApi.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, 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") + .addFormParam("Signature", "8SgbaWihxOICMXDLvwk3ahy/99nhZvTvbno%2B8dMyvJg%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testCreateImageOptions() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AMIApi.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, 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") + .addFormParam("Signature", "hQxNAaRVX6OvXV0IKgx1vV0FoNbRyuHQ2fhRhaPJnS8%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testDescribeImages() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AMIApi.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, 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") + .addFormParam("Signature", "cIft3g1fwMu52NgB0En9NtHyXjVhmeSx7TBP7YR%2BTvI%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testDescribeImagesOptions() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AMIApi.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, 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") + .addFormParam("Signature", "tm6nGoPPJh7xt5TSdV5Ov0DJvcGTAW%2BYSfXL7j%2BTkOA%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testDeregisterImage() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AMIApi.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, 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") + .addFormParam("Signature", "Ie7k7w4Bdki3uCGeSFGdJ5EKrp/ohkHvWwivbIaVLEM%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testRegisterImageFromManifest() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AMIApi.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, 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") + .addFormParam("Signature", "ilWV1eAWW6kTK/jHliQ%2BIkzJR4DRNy4ye%2BSKtnUjjDs%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testRegisterImageFromManifestOptions() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AMIApi.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, 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") + .addFormParam("Signature", "ZbZcY6uwxPbD65jFmiNZXoWeHY/2zqRuGuDmTfkt84A%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testRegisterImageBackedByEBS() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AMIApi.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, 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.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") + .addFormParam("Signature", "DrNujyZMGrKvuw73A7ObFTThXvc/MRfNqjvIy8gey5g%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testRegisterImageBackedByEBSOptions() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AMIApi.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").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, 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") + .addFormParam("Signature", "MJCIc1roG%2BnIWxRSUqV9KP9Wc4AWuuiNkxeDSih5/mI%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testGetBlockDeviceMappingsForImage() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AMIApi.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, 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") + .addFormParam("Signature", "iN7JbsAhM1NAES3o%2BOw8BaaFJ%2B1g9imBjcU4mFCyrxM%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testGetLaunchPermissionForImage() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AMIApi.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, 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("Signature", "ZuMuzW/iQDRURhUJaBzvoAdNJrE454y6X0jM24lcxxk%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("UserGroup.1", "all") + .addFormParam("UserId.1", "bob") + .addFormParam("UserId.2", "sue") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testAddLaunchPermissionsToImage() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AMIApi.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, 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("Signature", "HreSEawbVaUp/UMicCJbhrx%2BmoX01f2pEphJCPz8/5g%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("UserGroup.1", "all") + .addFormParam("UserId.1", "bob") + .addFormParam("UserId.2", "sue") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testRemoveLaunchPermissionsFromImage() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AMIApi.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, 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") + .addFormParam("Signature", "fVCR9aGYvNX/Jt1/uqBGcUQRLrHwxtcvmNYKzpul1P4%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testResetLaunchPermissionsOnImage() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AMIApi.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, resetLaunchPermissionsOnImage.getPayload().getRawContent().toString(), + "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/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AvailabilityZoneAndRegionApiLiveTest.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AvailabilityZoneAndRegionApiLiveTest.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AvailabilityZoneAndRegionApiLiveTest.java new file mode 100644 index 0000000..c2eb0df --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AvailabilityZoneAndRegionApiLiveTest.java @@ -0,0 +1,89 @@ +/* + * 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.ec2.features; + +import static org.jclouds.ec2.options.DescribeAvailabilityZonesOptions.Builder.availabilityZones; +import static org.jclouds.ec2.options.DescribeRegionsOptions.Builder.regions; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +import java.net.URI; +import java.util.Iterator; +import java.util.Map.Entry; +import java.util.Set; +import java.util.SortedMap; + +import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest; +import org.jclouds.ec2.EC2Api; +import org.jclouds.ec2.domain.AvailabilityZoneInfo; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.google.common.collect.Maps; + +/** + * Tests behavior of {@code AvailabilityZoneAndRegionApi} + */ +@Test(groups = "live", singleThreaded = true, testName = "AvailabilityZoneAndRegionApiLiveTest") +public class AvailabilityZoneAndRegionApiLiveTest extends BaseComputeServiceContextLiveTest { + public AvailabilityZoneAndRegionApiLiveTest() { + provider = "ec2"; + } + + private EC2Api ec2Api; + private AvailabilityZoneAndRegionApi client; + + @Override + @BeforeClass(groups = { "integration", "live" }) + public void setupContext() { + super.setupContext(); + ec2Api = view.unwrapApi(EC2Api.class); + client = ec2Api.getAvailabilityZoneAndRegionApi().get(); + } + + public void testDescribeAvailabilityZones() { + for (String region : ec2Api.getConfiguredRegions()) { + Set<AvailabilityZoneInfo> allResults = client.describeAvailabilityZonesInRegion(region); + assertNotNull(allResults); + assert !allResults.isEmpty() : allResults.size(); + Iterator<AvailabilityZoneInfo> iterator = allResults.iterator(); + String id1 = iterator.next().getZone(); + Set<AvailabilityZoneInfo> oneResult = client.describeAvailabilityZonesInRegion(region, + availabilityZones(id1)); + assertNotNull(oneResult); + assertEquals(oneResult.size(), 1); + iterator = allResults.iterator(); + assertEquals(iterator.next().getZone(), id1); + } + } + + public void testDescribeRegions() { + SortedMap<String, URI> allResults = Maps.newTreeMap(); + allResults.putAll(client.describeRegions()); + assertNotNull(allResults); + assert !allResults.isEmpty() : allResults.size(); + Iterator<Entry<String, URI>> iterator = allResults.entrySet().iterator(); + String r1 = iterator.next().getKey(); + SortedMap<String, URI> oneResult = Maps.newTreeMap(); + oneResult.putAll(client.describeRegions(regions(r1))); + assertNotNull(oneResult); + assertEquals(oneResult.size(), 1); + iterator = oneResult.entrySet().iterator(); + assertEquals(iterator.next().getKey(), r1); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AvailabilityZoneAndRegionApiTest.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AvailabilityZoneAndRegionApiTest.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AvailabilityZoneAndRegionApiTest.java new file mode 100644 index 0000000..6552dfa --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AvailabilityZoneAndRegionApiTest.java @@ -0,0 +1,114 @@ +/* + * 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.ec2.features; + +import static org.jclouds.ec2.options.DescribeAvailabilityZonesOptions.Builder.availabilityZones; +import static org.jclouds.ec2.options.DescribeRegionsOptions.Builder.regions; +import static org.jclouds.reflect.Reflection2.method; + +import java.io.IOException; + +import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404; +import org.jclouds.aws.domain.Region; +import org.jclouds.ec2.options.DescribeAvailabilityZonesOptions; +import org.jclouds.ec2.options.DescribeRegionsOptions; +import org.jclouds.ec2.xml.DescribeAvailabilityZonesResponseHandler; +import org.jclouds.ec2.xml.DescribeRegionsResponseHandler; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.rest.internal.GeneratedHttpRequest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.reflect.Invokable; +/** + * Tests behavior of {@code AvailabilityZoneAndRegionApi} + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +@Test(groups = "unit", testName = "AvailabilityZoneAndRegionApiTest") +public class AvailabilityZoneAndRegionApiTest extends + BaseEC2ApiTest<AvailabilityZoneAndRegionApi> { + + public void testDescribeAvailabilityZones() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AvailabilityZoneAndRegionApi.class, "describeAvailabilityZonesInRegion", + String.class, DescribeAvailabilityZonesOptions[].class); + GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of(Region.US_WEST_1)); + + assertRequestLineEquals(request, "POST https://ec2.us-west-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-west-1.amazonaws.com\n"); + assertPayloadEquals(request, "Action=DescribeAvailabilityZones", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeAvailabilityZonesResponseHandler.class); + assertFallbackClassEquals(method, EmptySetOnNotFoundOr404.class); + + checkFilters(request); + } + + public void testDescribeAvailabilityZonesOptions() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AvailabilityZoneAndRegionApi.class, "describeAvailabilityZonesInRegion", + String.class, DescribeAvailabilityZonesOptions[].class); + GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("us-east-1", availabilityZones("us-east-1a", "us-east-1b"))); + + 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=DescribeAvailabilityZones&ZoneName.1=us-east-1a&ZoneName.2=us-east-1b", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeAvailabilityZonesResponseHandler.class); + assertFallbackClassEquals(method, EmptySetOnNotFoundOr404.class); + + checkFilters(request); + } + + public void testDescribeRegions() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AvailabilityZoneAndRegionApi.class, "describeRegions", + DescribeRegionsOptions[].class); + GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.of()); + + 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=DescribeRegions", "application/x-www-form-urlencoded", + false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeRegionsResponseHandler.class); + assertFallbackClassEquals(method, null); + + checkFilters(request); + } + + public void testDescribeRegionsOptions() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(AvailabilityZoneAndRegionApi.class, "describeRegions", + DescribeRegionsOptions[].class); + GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of(regions(Region.US_EAST_1, Region.US_WEST_1))); + + 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=DescribeRegions&RegionName.1=us-east-1&RegionName.2=us-west-1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeRegionsResponseHandler.class); + assertFallbackClassEquals(method, null); + + checkFilters(request); + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/BaseEC2ApiTest.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/BaseEC2ApiTest.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/BaseEC2ApiTest.java new file mode 100644 index 0000000..3a2e645 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/BaseEC2ApiTest.java @@ -0,0 +1,142 @@ +/* + * 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.ec2.features; + +import static com.google.common.collect.Maps.transformValues; +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.net.URI; +import java.util.Map; +import java.util.Set; + +import javax.inject.Singleton; + +import org.jclouds.apis.ApiMetadata; +import org.jclouds.aws.domain.Region; +import org.jclouds.aws.filters.FormSigner; +import org.jclouds.compute.domain.Image; +import org.jclouds.date.DateService; +import org.jclouds.ec2.EC2ApiMetadata; +import org.jclouds.ec2.EC2Api; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.config.BaseEC2HttpApiModule; +import org.jclouds.http.HttpRequest; +import org.jclouds.location.config.LocationModule; +import org.jclouds.location.suppliers.RegionIdToURISupplier; +import org.jclouds.location.suppliers.RegionIdToZoneIdsSupplier; +import org.jclouds.rest.ConfiguresHttpApi; +import org.jclouds.rest.internal.BaseAsyncApiTest; +import org.jclouds.util.Suppliers2; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.google.common.base.Supplier; +import com.google.common.cache.CacheBuilder; +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.inject.Module; +import com.google.inject.Provides; + +@Test(groups = "unit") +public abstract class BaseEC2ApiTest<T> extends BaseAsyncApiTest<T> { + @ConfiguresHttpApi + protected static class StubEC2HttpApiModule extends BaseEC2HttpApiModule<EC2Api> { + + protected StubEC2HttpApiModule() { + super(EC2Api.class); + } + + @Provides + @Singleton + LoadingCache<RegionAndName, Image> provide() { + return CacheBuilder.newBuilder().build(new CacheLoader<RegionAndName, Image>() { + + @Override + public Image load(RegionAndName key) throws Exception { + return null; + } + + }); + } + + @Override + protected String provideTimeStamp(DateService dateService) { + return "2009-11-08T15:54:08.897Z"; + } + + static class Zones implements javax.inject.Provider<Map<String, String>> { + @Override + public Map<String, String> get() { + return ImmutableMap.<String, String> of("us-east-1a", "us-east-1"); + } + } + + @Override + protected void installLocations() { + install(new LocationModule()); + bind(RegionIdToURISupplier.class).toInstance(new RegionIdToURISupplier() { + + @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()); + } + + }); + bind(RegionIdToZoneIdsSupplier.class).toInstance(new RegionIdToZoneIdsSupplier() { + + @Override + public Map<String, Supplier<Set<String>>> get() { + return transformValues(ImmutableMap.<String, Set<String>> of("us-east-1", ImmutableSet.of( + "us-east-1a", "us-east-1b", "us-east-1c", "us-east-1b")), Suppliers2 + .<Set<String>> ofInstanceFunction()); + } + + }); + } + } + + protected FormSigner filter; + + @Override + protected void checkFilters(HttpRequest request) { + assertEquals(request.getFilters().size(), 1); + assertEquals(request.getFilters().get(0).getClass(), FormSigner.class); + } + + @Override + @BeforeTest + protected void setupFactory() throws IOException { + super.setupFactory(); + this.filter = injector.getInstance(FormSigner.class); + } + + @Override + protected Module createModule() { + return new StubEC2HttpApiModule(); + } + + @Override + protected ApiMetadata createApiMetadata() { + return new EC2ApiMetadata(); + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/EC2ElasticBlockStoreApiExpectTest.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/EC2ElasticBlockStoreApiExpectTest.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/EC2ElasticBlockStoreApiExpectTest.java new file mode 100644 index 0000000..df71112 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/EC2ElasticBlockStoreApiExpectTest.java @@ -0,0 +1,204 @@ +/* + * 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.ec2.features; + +import static com.google.common.collect.Iterables.getOnlyElement; +import static org.testng.Assert.assertEquals; + +import org.jclouds.ec2.EC2Api; +import org.jclouds.ec2.domain.Snapshot; +import org.jclouds.ec2.domain.Volume; +import org.jclouds.ec2.internal.BaseEC2ApiExpectTest; +import org.jclouds.ec2.options.CreateVolumeOptions; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.rest.ResourceNotFoundException; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; + +@Test(groups = "unit", testName = "EC2ElasticBlockStoreApiExpectTest") +public class EC2ElasticBlockStoreApiExpectTest extends BaseEC2ApiExpectTest<EC2Api> { + Volume creating = Volume.builder() + .id("vol-2a21e543") + .status(Volume.Status.CREATING) + .availabilityZone("us-east-1a") + .region("us-east-1") + .id("vol-2a21e543") + .volumeType("standard") + .iops(0) + .size(1) + .createTime(dateService.iso8601DateParse("2009-12-28T05:42:53.000Z")) + .build(); + + public void testCreateVolumeInAvailabilityZone() { + Builder<HttpRequest, HttpResponse> builder = ImmutableMap.<HttpRequest, HttpResponse>builder(); + builder.put(describeRegionsRequest, describeRegionsResponse); + builder.putAll(describeAvailabilityZonesRequestResponse); + builder.put( + HttpRequest.builder() + .method("POST") + .endpoint("https://ec2.us-east-1.amazonaws.com/") + .addHeader("Host", "ec2.us-east-1.amazonaws.com") + .payload(payloadFromStringWithContentType("Action=CreateVolume&AvailabilityZone=us-east-1a&Signature=NCu8HU8u0A385rTgj%2BN5lq606jkc1eu88jof9yAxb6s%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Size=4&Timestamp=2012-04-16T15%3A54%3A08.897Z&Version=2010-08-31&AWSAccessKeyId=identity", "application/x-www-form-urlencoded")).build(), + HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResource("/created_volume.xml")).build()); + + ElasticBlockStoreApi client = requestsSendResponses(builder.build()).getElasticBlockStoreApi().get(); + + assertEquals(client.createVolumeInAvailabilityZone("us-east-1a", 4), creating); + } + + public void testCreateVolumeInAvailabilityZoneWithOptions() { + Builder<HttpRequest, HttpResponse> builder = ImmutableMap.<HttpRequest, HttpResponse>builder(); + builder.put(describeRegionsRequest, describeRegionsResponse); + builder.putAll(describeAvailabilityZonesRequestResponse); + builder.put( + HttpRequest.builder() + .method("POST") + .endpoint("https://ec2.us-east-1.amazonaws.com/") + .addHeader("Host", "ec2.us-east-1.amazonaws.com") + .payload(payloadFromStringWithContentType("Action=CreateVolume" + + "&AvailabilityZone=us-east-1a" + + "&Iops=0" + + "&Signature=uI5tXrwV4zXB3uh0OP4RkfU2HMdQ2yICfpo4gKrajMI%3D" + + "&SignatureMethod=HmacSHA256" + + "&SignatureVersion=2" + + "&Size=4" + + "&Timestamp=2012-04-16T15%3A54%3A08.897Z" + + "&Version=2010-08-31" + + "&VolumeType=standard" + + "&AWSAccessKeyId=identity", "application/x-www-form-urlencoded")).build(), + HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResource("/created_volume.xml")).build()); + + ElasticBlockStoreApi client = requestsSendResponses(builder.build()).getElasticBlockStoreApi().get(); + + assertEquals(client.createVolumeInAvailabilityZone("us-east-1a", + CreateVolumeOptions.Builder.withSize(4).isEncrypted(false).volumeType("standard").withIops(0)), + creating); + } + + public void testCreateVolumeFromSnapshotInAvailabilityZoneEuSetsCorrectEndpoint() { + String region = "eu-west-1"; + + Builder<HttpRequest, HttpResponse> builder = ImmutableMap.<HttpRequest, HttpResponse>builder(); + builder.put(describeRegionsRequest, describeRegionsResponse); + builder.putAll(describeAvailabilityZonesRequestResponse); + builder.put( + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("Action", "CreateVolume") + .addFormParam("AvailabilityZone", "eu-west-1a") + .addFormParam("Size", "1") + .addFormParam("SnapshotId", "snap-8b7ffbdd") + .build()), + HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResource("/created_volume.xml")).build()); + + ElasticBlockStoreApi client = requestsSendResponses(builder.build()).getElasticBlockStoreApi().get(); + + assertEquals(client.createVolumeFromSnapshotInAvailabilityZone(region + "a", 1, "snap-8b7ffbdd"), creating.toBuilder().region(region).build()); + } + + HttpRequest filterVolumes = HttpRequest.builder().method("POST") + .endpoint("https://ec2.us-east-1.amazonaws.com/") + .addHeader("Host", "ec2.us-east-1.amazonaws.com") + .addFormParam("Action", "DescribeVolumes") + .addFormParam("Filter.1.Name", "snapshot-id") + .addFormParam("Filter.1.Value.1", "snap-536d1b3a") + .addFormParam("Signature", "7g2ySW39nIVfxtIbuVttUBom7sssmQknxX/9SThkm2Y%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2012-04-16T15%3A54%3A08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testFilterVolumesWhenResponseIs2xx() { + HttpResponse filterResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/describe_volumes_single.xml", "text/xml")).build(); + + EC2Api apiWhenExist = requestsSendResponses(describeRegionsRequest, describeRegionsResponse, filterVolumes, filterResponse); + + Volume volume = getOnlyElement(apiWhenExist.getElasticBlockStoreApi().get().describeVolumesInRegionWithFilter("us-east-1", + ImmutableMultimap.<String, String>builder() + .put("snapshot-id", "snap-536d1b3a") + .build())); + + assertEquals(volume.getId(), "vol-4282672b"); + } + + @Test(expectedExceptions = ResourceNotFoundException.class) + public void testFilterVolumesWhenResponseIs404() { + HttpResponse filterResponse = HttpResponse.builder().statusCode(404).build(); + + EC2Api apiWhenNotExist = requestsSendResponses(describeRegionsRequest, describeRegionsResponse, filterVolumes, filterResponse); + + assertEquals(apiWhenNotExist.getElasticBlockStoreApi().get().describeVolumesInRegionWithFilter("us-east-1", + ImmutableMultimap.<String, String>builder() + .put("snapshot-id", "snap-536d1b3a") + .build()), + ImmutableSet.of()); + } + + HttpRequest filterSnapshots = HttpRequest.builder().method("POST") + .endpoint("https://ec2.us-east-1.amazonaws.com/") + .addHeader("Host", "ec2.us-east-1.amazonaws.com") + .addFormParam("Action", "DescribeSnapshots") + .addFormParam("Filter.1.Name", "volume-id") + .addFormParam("Filter.1.Value.1", "4d826724") + .addFormParam("Signature", "vT7R4YmfQJPNLSojXEMY1qcErMh0OzrOTYxbGYSZ4Uw%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2012-04-16T15%3A54%3A08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testFilterSnapshotsWhenResponseIs2xx() { + HttpResponse filterResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/describe_snapshots.xml", "text/xml")).build(); + + EC2Api apiWhenExist = requestsSendResponses(describeRegionsRequest, describeRegionsResponse, filterSnapshots, filterResponse); + + Snapshot snapshot = getOnlyElement(apiWhenExist.getElasticBlockStoreApi().get().describeSnapshotsInRegionWithFilter("us-east-1", + ImmutableMultimap.<String, String>builder() + .put("volume-id", "4d826724") + .build())); + + assertEquals(snapshot.getId(), "snap-78a54011"); + } + + public void testFilterSnapshotsWhenResponseIs404() { + HttpResponse filterResponse = HttpResponse.builder().statusCode(404).build(); + + EC2Api apiWhenNotExist = requestsSendResponses(describeRegionsRequest, describeRegionsResponse, filterSnapshots, filterResponse); + + assertEquals(apiWhenNotExist.getElasticBlockStoreApi().get().describeSnapshotsInRegionWithFilter("us-east-1", + ImmutableMultimap.<String, String>builder() + .put("volume-id", "4d826724") + .build()), + ImmutableSet.of()); + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/ElasticBlockStoreApiLiveTest.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/ElasticBlockStoreApiLiveTest.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/ElasticBlockStoreApiLiveTest.java new file mode 100644 index 0000000..ac3cf29 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/ElasticBlockStoreApiLiveTest.java @@ -0,0 +1,311 @@ +/* + * 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.ec2.features; + +import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.jclouds.ec2.options.CreateVolumeOptions.Builder.fromSnapshotId; +import static org.jclouds.ec2.options.CreateVolumeOptions.Builder.withSize; +import static org.jclouds.ec2.options.DescribeSnapshotsOptions.Builder.snapshotIds; +import static org.jclouds.util.Predicates2.retry; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; + +import java.util.Set; +import java.util.SortedSet; + +import com.google.common.base.Predicate; +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; +import org.jclouds.aws.AWSResponseException; +import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest; +import org.jclouds.ec2.EC2Api; +import org.jclouds.ec2.domain.AvailabilityZoneInfo; +import org.jclouds.ec2.domain.Snapshot; +import org.jclouds.ec2.domain.Volume; +import org.jclouds.ec2.predicates.SnapshotCompleted; +import org.jclouds.ec2.predicates.VolumeAvailable; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Tests behavior of {@code ElasticBlockStoreApi} + */ +@Test(groups = "live", singleThreaded = true) +public class ElasticBlockStoreApiLiveTest extends BaseComputeServiceContextLiveTest { + public ElasticBlockStoreApiLiveTest() { + provider = "ec2"; + } + + protected EC2Api ec2Api; + protected ElasticBlockStoreApi client; + + protected String defaultRegion; + protected String defaultZone; + + protected String volumeId; + protected Snapshot snapshot; + + @Override + @BeforeClass(groups = { "integration", "live" }) + public void setupContext() { + super.setupContext(); + ec2Api = view.unwrapApi(EC2Api.class); + client = ec2Api.getElasticBlockStoreApi().get(); + AvailabilityZoneInfo info = Iterables.get(ec2Api.getAvailabilityZoneAndRegionApi().get() + .describeAvailabilityZonesInRegion(defaultRegion), 0); + defaultRegion = checkNotNull(Strings.emptyToNull(info.getRegion()), "region of " + info); + defaultZone = checkNotNull(Strings.emptyToNull(info.getZone()), "zone of " + info); + } + + @Test + void testDescribeVolumes() { + String region = defaultRegion; + SortedSet<Volume> allResults = Sets.newTreeSet(client.describeVolumesInRegion(region)); + assertNotNull(allResults); + assertFalse(allResults.isEmpty()); + Volume volume = allResults.last(); + SortedSet<Volume> result = Sets.newTreeSet(client.describeVolumesInRegion(region, volume.getId())); + assertNotNull(result); + Volume compare = result.last(); + assertEquals(compare, volume); + } + + @Test + void testDescribeVolumesWithFilter() { + String region = defaultRegion; + SortedSet<Volume> allResults = Sets.newTreeSet(client.describeVolumesInRegion(region)); + assertNotNull(allResults); + assertFalse(allResults.isEmpty()); + Volume volume = allResults.last(); + SortedSet<Volume> result = Sets.newTreeSet(client.describeVolumesInRegionWithFilter(region, + ImmutableMultimap.<String, String>builder() + .put("volume-id", volume.getId()).build())); + assertNotNull(result); + Volume compare = result.last(); + assertEquals(compare, volume); + } + + @Test(expectedExceptions = AWSResponseException.class) + void testDescribeVolumesWithInvalidFilter() { + String region = defaultRegion; + SortedSet<Volume> allResults = Sets.newTreeSet(client.describeVolumesInRegion(region)); + assertNotNull(allResults); + assertFalse(allResults.isEmpty()); + Volume volume = allResults.last(); + SortedSet<Volume> result = Sets.newTreeSet(client.describeVolumesInRegionWithFilter(region, + ImmutableMultimap.<String, String>builder() + .put("invalid-filter", volume.getId()).build())); + } + + @Test + void testCreateVolumeInAvailabilityZone() { + Volume expected = client.createVolumeInAvailabilityZone(defaultZone, + withSize(1)); + assertNotNull(expected); + assertEquals(expected.getAvailabilityZone(), defaultZone); + this.volumeId = expected.getId(); + + Set<Volume> result = Sets.newLinkedHashSet(client.describeVolumesInRegion(defaultRegion, expected.getId())); + assertNotNull(result); + assertEquals(result.size(), 1); + Volume volume = result.iterator().next(); + assertEquals(volume.getId(), expected.getId()); + assertEquals(volume.getVolumeType(), expected.getVolumeType()); + } + + @Test(dependsOnMethods = "testCreateVolumeInAvailabilityZone") + void testCreateSnapshotInRegion() { + Snapshot snapshot = client.createSnapshotInRegion(defaultRegion, volumeId); + Predicate<Snapshot> snapshotted = retry(new SnapshotCompleted(client), 600, 10, SECONDS); + assert snapshotted.apply(snapshot); + + Snapshot result = Iterables.getOnlyElement(client.describeSnapshotsInRegion(snapshot.getRegion(), + snapshotIds(snapshot.getId()))); + + assertEquals(result.getProgress(), 100); + this.snapshot = result; + } + + @Test(dependsOnMethods = "testCreateSnapshotInRegion") + void testCreateVolumeFromSnapshotInAvailabilityZone() { + Volume volume = client.createVolumeFromSnapshotInAvailabilityZone(defaultZone, snapshot.getId()); + assertNotNull(volume); + + Predicate<Volume> availabile = retry(new VolumeAvailable(client), 600, 10, SECONDS); + assert availabile.apply(volume); + + Volume result = Iterables.getOnlyElement(client.describeVolumesInRegion(snapshot.getRegion(), volume.getId())); + assertEquals(volume.getId(), result.getId()); + assertEquals(volume.getSnapshotId(), snapshot.getId()); + assertEquals(volume.getAvailabilityZone(), defaultZone); + assertEquals(result.getStatus(), Volume.Status.AVAILABLE); + + client.deleteVolumeInRegion(snapshot.getRegion(), result.getId()); + } + + @Test(dependsOnMethods = "testCreateVolumeFromSnapshotInAvailabilityZone") + void testCreateVolumeFromSnapshotInAvailabilityZoneWithOptions() { + Volume volume = client.createVolumeInAvailabilityZone(defaultZone, + fromSnapshotId(snapshot.getId())); + assertNotNull(volume); + + Predicate<Volume> availabile = retry(new VolumeAvailable(client), 600, 10, SECONDS); + assert availabile.apply(volume); + + Volume result = Iterables.getOnlyElement(client.describeVolumesInRegion(snapshot.getRegion(), volume.getId())); + assertEquals(volume.getId(), result.getId()); + assertEquals(volume.getSnapshotId(), snapshot.getId()); + assertEquals(volume.getAvailabilityZone(), defaultZone); + assertEquals(result.getStatus(), Volume.Status.AVAILABLE); + + client.deleteVolumeInRegion(snapshot.getRegion(), result.getId()); + } + + @Test(dependsOnMethods = "testCreateVolumeFromSnapshotInAvailabilityZoneWithOptions") + void testCreateVolumeFromSnapshotInAvailabilityZoneWithSize() { + Volume volume = client.createVolumeFromSnapshotInAvailabilityZone(defaultZone, 2, snapshot.getId()); + assertNotNull(volume); + + Predicate<Volume> availabile = retry(new VolumeAvailable(client), 600, 10, SECONDS); + assert availabile.apply(volume); + + Volume result = Iterables.getOnlyElement(client.describeVolumesInRegion(snapshot.getRegion(), volume.getId())); + assertEquals(volume.getId(), result.getId()); + assertEquals(volume.getSnapshotId(), snapshot.getId()); + assertEquals(volume.getAvailabilityZone(), defaultZone); + assertEquals(volume.getSize(), 2); + assertEquals(result.getStatus(), Volume.Status.AVAILABLE); + + client.deleteVolumeInRegion(snapshot.getRegion(), result.getId()); + } + + @Test + void testAttachVolumeInRegion() { + // TODO: need an instance + } + + @Test + void testDetachVolumeInRegion() { + // TODO: need an instance + } + + @Test + void testDescribeSnapshots() { + String region = defaultRegion; + SortedSet<Snapshot> allResults = Sets.newTreeSet(client.describeSnapshotsInRegion(region)); + assertNotNull(allResults); + if (!allResults.isEmpty()) { + Snapshot snapshot = allResults.last(); + Snapshot result = Iterables.getOnlyElement(client.describeSnapshotsInRegion(region, + snapshotIds(snapshot.getId()))); + assertNotNull(result); + assertEquals(result, snapshot); + } + } + + @Test + void testDescribeSnapshotsWithFilter() { + String region = defaultRegion; + SortedSet<Snapshot> allResults = Sets.newTreeSet(client.describeSnapshotsInRegion(region)); + assertNotNull(allResults); + if (!allResults.isEmpty()) { + Snapshot snapshot = allResults.last(); + Snapshot result = Iterables.getOnlyElement(client.describeSnapshotsInRegionWithFilter(region, + ImmutableMultimap.<String, String>builder() + .put("snapshot-id", snapshot.getId()).build())); + assertNotNull(result); + assertEquals(result, snapshot); + } + } + + @Test(expectedExceptions = AWSResponseException.class) + void testDescribeSnapshotsWithFilterInvalid() { + String region = defaultRegion; + SortedSet<Snapshot> allResults = Sets.newTreeSet(client.describeSnapshotsInRegion(region)); + assertNotNull(allResults); + if (!allResults.isEmpty()) { + Snapshot snapshot = allResults.last(); + Snapshot result = Iterables.getOnlyElement(client.describeSnapshotsInRegionWithFilter(region, + ImmutableMultimap.<String, String>builder() + .put("invalid-filter", snapshot.getId()).build())); + } + } + + @Test(enabled = false) + public void testAddCreateVolumePermissionsToSnapshot() { + // TODO client.addCreateVolumePermissionsToSnapshotInRegion(defaultRegion, + // userIds, + // userGroups, + // snapshotId); + } + + @Test(enabled = false) + public void testRemoveCreateVolumePermissionsFromSnapshot() { + // TODO + // client.removeCreateVolumePermissionsFromSnapshotInRegion(defaultRegion, + // userIds, + // userGroups, + // snapshotId); + } + + @Test(enabled = false) + public void testResetCreateVolumePermissionsOnSnapshot() { + // TODO + // client.resetCreateVolumePermissionsOnSnapshotInRegion(defaultRegion, + // snapshotId); + } + + @Test(dependsOnMethods = "testCreateVolumeFromSnapshotInAvailabilityZoneWithSize") + public void testGetCreateVolumePermissionForSnapshot() { + client.getCreateVolumePermissionForSnapshotInRegion(snapshot.getRegion(), snapshot.getId()); + } + + @Test(dependsOnMethods = "testGetCreateVolumePermissionForSnapshot") + void testDeleteVolumeInRegion() { + client.deleteVolumeInRegion(defaultRegion, volumeId); + assertEquals(client.describeVolumesInRegionWithFilter(defaultRegion, + ImmutableMultimap.<String, String>builder() + .put("volume-id", volumeId).build()), + ImmutableSet.of()); + } + + @Test(dependsOnMethods = "testDeleteVolumeInRegion") + void testDeleteSnapshotInRegion() { + client.deleteSnapshotInRegion(snapshot.getRegion(), snapshot.getId()); + assert client.describeSnapshotsInRegion(snapshot.getRegion(), snapshotIds(snapshot.getId())).size() == 0; + } + + @AfterClass(groups = { "integration", "live" }) + @Override + protected void tearDownContext() { + try { + client.deleteSnapshotInRegion(snapshot.getRegion(), snapshot.getId()); + client.deleteVolumeInRegion(defaultRegion, volumeId); + } catch (Exception e) { + // we don't really care about any exception here, so just delete away. + } + + super.tearDownContext(); + } + +}
