Issue 428 cannot delete instances outside ec2 east

This commit is contained in:
Adrian Cole 2010-12-22 13:39:10 +01:00
parent b4ed57b142
commit e235427b5f
6 changed files with 268 additions and 167 deletions

View File

@ -126,6 +126,7 @@ public class EC2ComputeService extends BaseComputeService {
} }
} }
} }
} catch (UnsupportedOperationException e) {
} catch (HttpResponseException e) { } catch (HttpResponseException e) {
// Eucalyptus does not support placement groups yet. // Eucalyptus does not support placement groups yet.
if (!(e.getResponse().getStatusCode() == 400 && context.getProviderSpecificContext().getProvider() if (!(e.getResponse().getStatusCode() == 400 && context.getProviderSpecificContext().getProvider()

View File

@ -90,6 +90,9 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler {
response.getStatusLine()); response.getStatusLine());
switch (response.getStatusCode()) { switch (response.getStatusCode()) {
case 400: case 400:
if (error != null && error.getCode() != null
&& (error.getCode().equals("UnsupportedOperation")))
exception = new UnsupportedOperationException(message, exception);
if (error != null && error.getCode() != null if (error != null && error.getCode() != null
&& (error.getCode().endsWith(".NotFound") || error.getCode().endsWith(".Unknown"))) && (error.getCode().endsWith(".NotFound") || error.getCode().endsWith(".Unknown")))
exception = new ResourceNotFoundException(message, exception); exception = new ResourceNotFoundException(message, exception);

View File

@ -19,162 +19,68 @@
package org.jclouds.aws.ec2.compute; package org.jclouds.aws.ec2.compute;
import static java.lang.String.format;
import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock; import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay; import static org.easymock.classextension.EasyMock.replay;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.c1_medium; import static org.easymock.classextension.EasyMock.verify;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.c1_xlarge;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.cc1_4xlarge;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.m1_large;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.m1_small;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.m1_xlarge;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.m2_2xlarge;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.m2_4xlarge;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.m2_xlarge;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.t1_micro;
import static org.testng.Assert.assertEquals;
import java.util.Set; import java.util.Map;
import java.util.concurrent.ExecutorService;
import javax.inject.Provider; import javax.inject.Provider;
import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.compute.domain.Hardware; import org.jclouds.aws.ec2.services.PlacementGroupClient;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.ImageBuilder; import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.strategy.ListNodesStrategy;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.strategy.RebootNodeStrategy;
import org.jclouds.compute.domain.internal.TemplateBuilderImpl; import org.jclouds.compute.strategy.ResumeNodeStrategy;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
import org.jclouds.domain.Credentials; import org.jclouds.compute.strategy.SuspendNodeStrategy;
import org.jclouds.domain.Location; import org.jclouds.compute.util.ComputeUtils;
import org.jclouds.domain.LocationScope;
import org.jclouds.domain.internal.LocationImpl;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.base.Function; import com.google.common.base.Predicate;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableSet;
/** /**
* Tests compute service specifically to EC2. * @author Adrian Cole
*
* These tests are designed to verify the local functionality of jclouds, rather than the
* interaction with Amazon Web Services.
*
* @see EC2ComputeServiceLiveTest
*
* @author Oleksiy Yarmula
*/ */
@Test(groups = "unit")
public class EC2ComputeServiceTest { public class EC2ComputeServiceTest {
private static final Location location = new LocationImpl(LocationScope.REGION, "us-east-1", "us east", null);
public static final Hardware CC1_4XLARGE = cc1_4xlarge().location(location).supportsImageIds("us-east-1/cc-image") @SuppressWarnings({ "unchecked" })
.build(); public void testUnsupportedOperationOkForPlacementGroups() {
EC2Client client = createMock(EC2Client.class);
EC2ComputeService service = new EC2ComputeService(createMock(ComputeServiceContext.class), createMock(Map.class),
createMock(Supplier.class), createMock(Supplier.class), createMock(Supplier.class),
createMock(ListNodesStrategy.class), createMock(GetNodeMetadataStrategy.class),
createMock(RunNodesAndAddToSetStrategy.class), createMock(RebootNodeStrategy.class),
createMock(DestroyNodeStrategy.class), createMock(ResumeNodeStrategy.class),
createMock(SuspendNodeStrategy.class), createMock(Provider.class), createMock(Provider.class),
createMock(Predicate.class), createMock(Predicate.class), createMock(Predicate.class),
createMock(ComputeUtils.class), createMock(Timeouts.class), createMock(ExecutorService.class), client,
createMock(Map.class), createMock(Map.class), createMock(Map.class), createMock(Predicate.class));
/** PlacementGroupClient placementClient = createMock(PlacementGroupClient.class);
* Verifies that {@link TemplateBuilderImpl} would choose the correct size of the instance, based
* on {@link org.jclouds.compute.domain.Hardware} from {@link EC2Hardware}.
*
* Expected size: m2.xlarge
*/
@Test
public void testTemplateChoiceForInstanceByhardwareId() throws Exception {
Template template = newTemplateBuilder().os64Bit(true).hardwareId("m2.xlarge").locationId("us-east-1").build();
assert template != null : "The returned template was null, but it should have a value."; // setup expectations
// assert m2_xlarge().build().equals(template.getHardware()) : format( expect(client.getPlacementGroupServices()).andReturn(placementClient).atLeastOnce();
// "Incorrect image determined by the template. Expected: %s. Found: %s.", "m2.xlarge", expect(placementClient.describePlacementGroupsInRegion("us-west-1", "jclouds#tag#us-west-1")).andThrow(
// String.valueOf(template.getHardware())); new UnsupportedOperationException());
assertEquals(m2_xlarge().build(), template.getHardware());
}
@Test // replay mocks
public void testTemplateChoiceForInstanceByCChardwareId() throws Exception { replay(client);
Template template = newTemplateBuilder().fastest().build(); replay(placementClient);
// run
service.deletePlacementGroup("us-west-1", "tag");
assert template != null : "The returned template was null, but it should have a value."; // verify mocks
assert CC1_4XLARGE.equals(template.getHardware()) : format( verify(client);
"Incorrect image determined by the template. Expected: %s. Found: %s.", CC1_4XLARGE.getId(), String verify(placementClient);
.valueOf(template.getHardware()));
}
/**
* Verifies that {@link TemplateBuilderImpl} would choose the correct size of the instance, based
* on physical attributes (# of cores, ram, etc).
*
* Expected size: m2.xlarge
*/
@Test
public void testTemplateChoiceForInstanceByAttributes() throws Exception {
Template template = newTemplateBuilder().os64Bit(true).minRam(17510).minCores(6.5).smallest().locationId(
"us-east-1").build();
assert template != null : "The returned template was null, but it should have a value.";
assert CC1_4XLARGE.equals(template.getHardware()) : format(
"Incorrect image determined by the template. Expected: %s. Found: %s.", CC1_4XLARGE, String
.valueOf(template.getHardware()));
}
/**
* Negative test version of {@link #testTemplateChoiceForInstanceByAttributes}.
*
* Verifies that {@link TemplateBuilderImpl} would not choose the insufficient size of the
* instance, based on physical attributes (# of cores, ram, etc).
*
* Expected size: anything but m2.xlarge
*/
@Test
public void testNegativeTemplateChoiceForInstanceByAttributes() throws Exception {
Template template = newTemplateBuilder().os64Bit(true).minRam(17510).minCores(6.7).smallest().locationId(
"us-east-1").build();
assert template != null : "The returned template was null, but it should have a value.";
assert !m2_xlarge().build().equals(template.getHardware()) : format(
"Incorrect image determined by the template. Expected: not %s. Found: %s.", "m2.xlarge", String
.valueOf(template.getHardware()));
}
@SuppressWarnings("unchecked")
private TemplateBuilder newTemplateBuilder() {
Provider<TemplateOptions> optionsProvider = createMock(Provider.class);
Provider<TemplateBuilder> templateBuilderProvider = createMock(Provider.class);
TemplateOptions defaultOptions = createMock(TemplateOptions.class);
expect(optionsProvider.get()).andReturn(defaultOptions);
Image image = new ImageBuilder().providerId("cc-image").name("image").id("us-east-1/cc-image").location(location)
.operatingSystem(new OperatingSystem(OsFamily.UBUNTU, null, "1.0", null, "ubuntu", true)).description(
"description").version("1.0").defaultCredentials(new Credentials("root", null)).build();
replay(optionsProvider);
replay(templateBuilderProvider);
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(location));
Supplier<Set<? extends Image>> images = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet
.<Image> of(image));
Supplier<Set<? extends Hardware>> sizes = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(t1_micro().build(), c1_medium().build(), c1_xlarge().build(), m1_large().build(),
m1_small().build(), m1_xlarge().build(), m2_xlarge().build(), m2_2xlarge().build(),
m2_4xlarge().build(), CC1_4XLARGE));
return new TemplateBuilderImpl(locations, images, sizes, Suppliers.ofInstance(location), optionsProvider,
templateBuilderProvider) {
};
}
Function<ComputeMetadata, String> indexer() {
return new Function<ComputeMetadata, String>() {
@Override
public String apply(ComputeMetadata from) {
return from.getProviderId();
}
};
}
} }
}

View File

@ -0,0 +1,180 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.compute;
import static java.lang.String.format;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.c1_medium;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.c1_xlarge;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.cc1_4xlarge;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.m1_large;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.m1_small;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.m1_xlarge;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.m2_2xlarge;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.m2_4xlarge;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.m2_xlarge;
import static org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder.t1_micro;
import static org.testng.Assert.assertEquals;
import java.util.Set;
import javax.inject.Provider;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.domain.internal.TemplateBuilderImpl;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope;
import org.jclouds.domain.internal.LocationImpl;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableSet;
/**
* Tests compute service specifically to EC2.
*
* These tests are designed to verify the local functionality of jclouds, rather than the
* interaction with Amazon Web Services.
*
* @see EC2ComputeServiceLiveTest
*
* @author Oleksiy Yarmula
*/
public class EC2TemplateBuilderTest {
private static final Location location = new LocationImpl(LocationScope.REGION, "us-east-1", "us east", null);
public static final Hardware CC1_4XLARGE = cc1_4xlarge().location(location).supportsImageIds("us-east-1/cc-image")
.build();
/**
* Verifies that {@link TemplateBuilderImpl} would choose the correct size of the instance, based
* on {@link org.jclouds.compute.domain.Hardware} from {@link EC2Hardware}.
*
* Expected size: m2.xlarge
*/
@Test
public void testTemplateChoiceForInstanceByhardwareId() throws Exception {
Template template = newTemplateBuilder().os64Bit(true).hardwareId("m2.xlarge").locationId("us-east-1").build();
assert template != null : "The returned template was null, but it should have a value.";
// assert m2_xlarge().build().equals(template.getHardware()) : format(
// "Incorrect image determined by the template. Expected: %s. Found: %s.", "m2.xlarge",
// String.valueOf(template.getHardware()));
assertEquals(m2_xlarge().build(), template.getHardware());
}
@Test
public void testTemplateChoiceForInstanceByCChardwareId() throws Exception {
Template template = newTemplateBuilder().fastest().build();
assert template != null : "The returned template was null, but it should have a value.";
assert CC1_4XLARGE.equals(template.getHardware()) : format(
"Incorrect image determined by the template. Expected: %s. Found: %s.", CC1_4XLARGE.getId(), String
.valueOf(template.getHardware()));
}
/**
* Verifies that {@link TemplateBuilderImpl} would choose the correct size of the instance, based
* on physical attributes (# of cores, ram, etc).
*
* Expected size: m2.xlarge
*/
@Test
public void testTemplateChoiceForInstanceByAttributes() throws Exception {
Template template = newTemplateBuilder().os64Bit(true).minRam(17510).minCores(6.5).smallest().locationId(
"us-east-1").build();
assert template != null : "The returned template was null, but it should have a value.";
assert CC1_4XLARGE.equals(template.getHardware()) : format(
"Incorrect image determined by the template. Expected: %s. Found: %s.", CC1_4XLARGE, String
.valueOf(template.getHardware()));
}
/**
* Negative test version of {@link #testTemplateChoiceForInstanceByAttributes}.
*
* Verifies that {@link TemplateBuilderImpl} would not choose the insufficient size of the
* instance, based on physical attributes (# of cores, ram, etc).
*
* Expected size: anything but m2.xlarge
*/
@Test
public void testNegativeTemplateChoiceForInstanceByAttributes() throws Exception {
Template template = newTemplateBuilder().os64Bit(true).minRam(17510).minCores(6.7).smallest().locationId(
"us-east-1").build();
assert template != null : "The returned template was null, but it should have a value.";
assert !m2_xlarge().build().equals(template.getHardware()) : format(
"Incorrect image determined by the template. Expected: not %s. Found: %s.", "m2.xlarge", String
.valueOf(template.getHardware()));
}
@SuppressWarnings("unchecked")
private TemplateBuilder newTemplateBuilder() {
Provider<TemplateOptions> optionsProvider = createMock(Provider.class);
Provider<TemplateBuilder> templateBuilderProvider = createMock(Provider.class);
TemplateOptions defaultOptions = createMock(TemplateOptions.class);
expect(optionsProvider.get()).andReturn(defaultOptions);
Image image = new ImageBuilder().providerId("cc-image").name("image").id("us-east-1/cc-image").location(location)
.operatingSystem(new OperatingSystem(OsFamily.UBUNTU, null, "1.0", null, "ubuntu", true)).description(
"description").version("1.0").defaultCredentials(new Credentials("root", null)).build();
replay(optionsProvider);
replay(templateBuilderProvider);
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(location));
Supplier<Set<? extends Image>> images = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet
.<Image> of(image));
Supplier<Set<? extends Hardware>> sizes = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(t1_micro().build(), c1_medium().build(), c1_xlarge().build(), m1_large().build(),
m1_small().build(), m1_xlarge().build(), m2_xlarge().build(), m2_2xlarge().build(),
m2_4xlarge().build(), CC1_4XLARGE));
return new TemplateBuilderImpl(locations, images, sizes, Suppliers.ofInstance(location), optionsProvider,
templateBuilderProvider) {
};
}
Function<ComputeMetadata, String> indexer() {
return new Function<ComputeMetadata, String>() {
@Override
public String apply(ComputeMetadata from) {
return from.getProviderId();
}
};
}
}

View File

@ -30,7 +30,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import org.jclouds.aws.domain.Region; import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.compute.EC2ComputeServiceTest; import org.jclouds.aws.ec2.compute.EC2TemplateBuilderTest;
import org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder; import org.jclouds.aws.ec2.compute.domain.EC2HardwareBuilder;
import org.jclouds.aws.ec2.compute.domain.RegionAndName; import org.jclouds.aws.ec2.compute.domain.RegionAndName;
import org.jclouds.aws.ec2.compute.domain.RegionNameAndIngressRules; import org.jclouds.aws.ec2.compute.domain.RegionNameAndIngressRules;
@ -118,7 +118,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup constants // setup constants
String region = Region.US_EAST_1; String region = Region.US_EAST_1;
String tag = "tag"; String tag = "tag";
Hardware size = EC2ComputeServiceTest.CC1_4XLARGE; Hardware size = EC2TemplateBuilderTest.CC1_4XLARGE;
String systemGeneratedKeyPairName = "systemGeneratedKeyPair"; String systemGeneratedKeyPairName = "systemGeneratedKeyPair";
String generatedGroup = "group"; String generatedGroup = "group";
Set<String> generatedGroups = ImmutableSet.of(generatedGroup); Set<String> generatedGroups = ImmutableSet.of(generatedGroup);
@ -177,7 +177,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup constants // setup constants
String region = Region.US_EAST_1; String region = Region.US_EAST_1;
String tag = "tag"; String tag = "tag";
Hardware size = EC2ComputeServiceTest.CC1_4XLARGE; Hardware size = EC2TemplateBuilderTest.CC1_4XLARGE;
String systemGeneratedKeyPairName = "systemGeneratedKeyPair"; String systemGeneratedKeyPairName = "systemGeneratedKeyPair";
String generatedGroup = "group"; String generatedGroup = "group";
Set<String> generatedGroups = ImmutableSet.of(generatedGroup); Set<String> generatedGroups = ImmutableSet.of(generatedGroup);

View File

@ -57,6 +57,12 @@ public class ParseAWSErrorFromXmlContentTest {
"<Error><Code>Monster.NotFound</Code></Error>", ResourceNotFoundException.class); "<Error><Code>Monster.NotFound</Code></Error>", ResourceNotFoundException.class);
} }
@Test
public void test400WithUnsupportedCodeMakesUnsupportedOperationException() {
assertCodeMakes("POST", URI.create("https://ec2.us-west-1.amazonaws.com/"), 400, "",
"<Error><Code>UnsupportedOperation</Code></Error>", UnsupportedOperationException.class);
}
@Test @Test
public void test400WithUnknownSetsResourceNotFoundException() { public void test400WithUnknownSetsResourceNotFoundException() {
assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "",
@ -71,8 +77,13 @@ public class ParseAWSErrorFromXmlContentTest {
@Test @Test
public void test409SetsIllegalStateException() { public void test409SetsIllegalStateException() {
assertCodeMakes("PUT", URI.create("https://adriancole-blobstore011.s3.amazonaws.com/"), 409, "", assertCodeMakes(
"<Error><Code>OperationAborted</Code><Message>A conflicting conditional operation is currently in progress against this resource. Please try again.</Message><RequestId>F716E81C3D814E59</RequestId><HostId>SDprHxWzG/YXzanVnV7VTz/wP+6fRt1dS+q00kH1rz248YOOSddkFiTXF04XtqNO</HostId></Error>", IllegalStateException.class); "PUT",
URI.create("https://adriancole-blobstore011.s3.amazonaws.com/"),
409,
"",
"<Error><Code>OperationAborted</Code><Message>A conflicting conditional operation is currently in progress against this resource. Please try again.</Message><RequestId>F716E81C3D814E59</RequestId><HostId>SDprHxWzG/YXzanVnV7VTz/wP+6fRt1dS+q00kH1rz248YOOSddkFiTXF04XtqNO</HostId></Error>",
IllegalStateException.class);
} }
@Test @Test