diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/options/RunInstancesOptions.java b/apis/ec2/src/main/java/org/jclouds/ec2/options/RunInstancesOptions.java index aa48c655ad..95975da69c 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/options/RunInstancesOptions.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/options/RunInstancesOptions.java @@ -144,7 +144,7 @@ public class RunInstancesOptions extends BaseEC2RequestOptions { if (mapping.getEbsIops() != null) formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.Iops", i), String.valueOf(mapping.getEbsIops())); - if (mapping.getEbsEncrypted() != null) + if (mapping.getEbsEncrypted() != null && mapping.getEbsEncrypted()) formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.Encrypted", i), String.valueOf(mapping.getEbsEncrypted())); i++; } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/features/AMIApiLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/features/AMIApiLiveTest.java index 3c242b8162..a3fda97327 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/features/AMIApiLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/features/AMIApiLiveTest.java @@ -33,6 +33,7 @@ import java.util.Iterator; import java.util.Properties; import java.util.Set; +import org.jclouds.Constants; import org.jclouds.aws.AWSResponseException; import org.jclouds.compute.RunNodesException; import org.jclouds.compute.domain.Template; @@ -45,7 +46,9 @@ import org.jclouds.ec2.domain.Image.ImageType; import org.jclouds.ec2.domain.RootDeviceType; import org.jclouds.ec2.domain.RunningInstance; import org.jclouds.ec2.domain.Snapshot; +import org.jclouds.ec2.options.RegisterImageBackedByEbsOptions; import org.jclouds.ec2.predicates.InstanceStateRunning; +import org.jclouds.ec2.predicates.SnapshotCompleted; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -182,7 +185,7 @@ public class AMIApiLiveTest extends BaseComputeServiceContextLiveTest { // Register a new image... ebsBackedImageId = client.registerUnixImageBackedByEbsInRegion(regionId, ebsBackedImageName, snapshot.getId(), - addNewBlockDevice("/dev/sda2", "myvirtual", 1, false, "gp2", null, false).withDescription("adrian")); + newBlockDeviceOption()); imagesToDeregister.add(ebsBackedImageId); final Image ebsBackedImage = getOnlyElement(client.describeImagesInRegion(regionId, imageIds(ebsBackedImageId))); assertEquals(ebsBackedImage.getName(), ebsBackedImageName); @@ -192,20 +195,35 @@ public class AMIApiLiveTest extends BaseComputeServiceContextLiveTest { assertEquals(ebsBackedImage.getDescription(), "adrian"); assertEquals( ebsBackedImage.getEbsBlockDevices().entrySet(), - ImmutableMap.of("/dev/sda1", new Image.EbsBlockDevice(snapshot.getId(), snapshot.getVolumeSize(), true, "standard", null, false), - "/dev/sda2", new Image.EbsBlockDevice(null, 1, false, "gp2", null, false)).entrySet()); + ImmutableMap.of("/dev/sda1", new Image.EbsBlockDevice(snapshot.getId(), snapshot.getVolumeSize(), true, null, null, false), + "/dev/sda2", newBlockDeviceInfo()).entrySet()); - // List of images after - should be one larger than before - int after = client.describeImagesInRegionWithFilter(regionId, - ImmutableMultimap.builder() - .put("name", ebsBackedImageName).build()).size(); + int describeCount = 0; + int after = 0; + // This loop is in here to deal with a lag between image creation and it showing up in filtered describeImage queries. + while (describeCount < 10 && after == 0) { + describeCount++; + Thread.sleep(30000); + // List of images after - should be one larger than before + after = client.describeImagesInRegionWithFilter(regionId, + ImmutableMultimap.builder() + .put("name", ebsBackedImageName).build()).size(); + } assertEquals(after, sizeBefore + 1); } + protected RegisterImageBackedByEbsOptions newBlockDeviceOption() { + return addNewBlockDevice("/dev/sda2", "myvirtual", 5, false, null, null, false).withDescription("adrian"); + } + + protected Image.EbsBlockDevice newBlockDeviceInfo() { + return new Image.EbsBlockDevice(null, 5, false, null, null, false); + } + // Fires up an instance, finds its root volume ID, takes a snapshot, then // terminates the instance. - private Snapshot createSnapshot() throws RunNodesException { + protected Snapshot createSnapshot() throws RunNodesException { String instanceId = null; try { @@ -222,6 +240,8 @@ public class AMIApiLiveTest extends BaseComputeServiceContextLiveTest { Snapshot snapshot = ec2Api.getElasticBlockStoreApi().get().createSnapshotInRegion(regionId, device.getVolumeId()); snapshotsToDelete.add(snapshot.getId()); + Predicate snapshotted = retry(new SnapshotCompleted(ec2Api.getElasticBlockStoreApi().get()), 600, 10, SECONDS); + assert snapshotted.apply(snapshot); return snapshot; } finally { if (instanceId != null) diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/features/ElasticBlockStoreApiLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/features/ElasticBlockStoreApiLiveTest.java index e6bbc6f212..ac3cf2931e 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/features/ElasticBlockStoreApiLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/features/ElasticBlockStoreApiLiveTest.java @@ -15,10 +15,11 @@ * 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.volumeType; +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; @@ -31,6 +32,7 @@ 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; @@ -48,20 +50,20 @@ import org.testng.annotations.Test; /** * Tests behavior of {@code ElasticBlockStoreApi} */ -@Test(groups = "live", singleThreaded = true, testName = "ElasticBlockStoreApiLiveTest") +@Test(groups = "live", singleThreaded = true) public class ElasticBlockStoreApiLiveTest extends BaseComputeServiceContextLiveTest { public ElasticBlockStoreApiLiveTest() { provider = "ec2"; } - private EC2Api ec2Api; - private ElasticBlockStoreApi client; + protected EC2Api ec2Api; + protected ElasticBlockStoreApi client; - private String defaultRegion; - private String defaultZone; + protected String defaultRegion; + protected String defaultZone; - private String volumeId; - private Snapshot snapshot; + protected String volumeId; + protected Snapshot snapshot; @Override @BeforeClass(groups = { "integration", "live" }) @@ -118,10 +120,9 @@ public class ElasticBlockStoreApiLiveTest extends BaseComputeServiceContextLiveT @Test void testCreateVolumeInAvailabilityZone() { Volume expected = client.createVolumeInAvailabilityZone(defaultZone, - volumeType("gp2")); + withSize(1)); assertNotNull(expected); assertEquals(expected.getAvailabilityZone(), defaultZone); - assertEquals(expected.getVolumeType(), "gp2"); this.volumeId = expected.getId(); Set result = Sets.newLinkedHashSet(client.describeVolumesInRegion(defaultRegion, expected.getId())); @@ -159,10 +160,10 @@ public class ElasticBlockStoreApiLiveTest extends BaseComputeServiceContextLiveT assertEquals(volume.getAvailabilityZone(), defaultZone); assertEquals(result.getStatus(), Volume.Status.AVAILABLE); - client.deleteVolumeInRegion(snapshot.getRegion(), volume.getId()); + client.deleteVolumeInRegion(snapshot.getRegion(), result.getId()); } - @Test(dependsOnMethods = "testCreateSnapshotInRegion") + @Test(dependsOnMethods = "testCreateVolumeFromSnapshotInAvailabilityZone") void testCreateVolumeFromSnapshotInAvailabilityZoneWithOptions() { Volume volume = client.createVolumeInAvailabilityZone(defaultZone, fromSnapshotId(snapshot.getId())); @@ -177,10 +178,10 @@ public class ElasticBlockStoreApiLiveTest extends BaseComputeServiceContextLiveT assertEquals(volume.getAvailabilityZone(), defaultZone); assertEquals(result.getStatus(), Volume.Status.AVAILABLE); - client.deleteVolumeInRegion(snapshot.getRegion(), volume.getId()); + client.deleteVolumeInRegion(snapshot.getRegion(), result.getId()); } - @Test(dependsOnMethods = "testCreateSnapshotInRegion") + @Test(dependsOnMethods = "testCreateVolumeFromSnapshotInAvailabilityZoneWithOptions") void testCreateVolumeFromSnapshotInAvailabilityZoneWithSize() { Volume volume = client.createVolumeFromSnapshotInAvailabilityZone(defaultZone, 2, snapshot.getId()); assertNotNull(volume); @@ -195,7 +196,7 @@ public class ElasticBlockStoreApiLiveTest extends BaseComputeServiceContextLiveT assertEquals(volume.getSize(), 2); assertEquals(result.getStatus(), Volume.Status.AVAILABLE); - client.deleteVolumeInRegion(snapshot.getRegion(), volume.getId()); + client.deleteVolumeInRegion(snapshot.getRegion(), result.getId()); } @Test @@ -274,21 +275,21 @@ public class ElasticBlockStoreApiLiveTest extends BaseComputeServiceContextLiveT // snapshotId); } - @Test(dependsOnMethods = "testCreateSnapshotInRegion") + @Test(dependsOnMethods = "testCreateVolumeFromSnapshotInAvailabilityZoneWithSize") public void testGetCreateVolumePermissionForSnapshot() { client.getCreateVolumePermissionForSnapshotInRegion(snapshot.getRegion(), snapshot.getId()); } - @Test(dependsOnMethods = "testCreateSnapshotInRegion") + @Test(dependsOnMethods = "testGetCreateVolumePermissionForSnapshot") void testDeleteVolumeInRegion() { client.deleteVolumeInRegion(defaultRegion, volumeId); - Set result = Sets.newLinkedHashSet(client.describeVolumesInRegion(defaultRegion, volumeId)); - assertEquals(result.size(), 1); - Volume volume = result.iterator().next(); - assertEquals(volume.getStatus(), Volume.Status.DELETING); + assertEquals(client.describeVolumesInRegionWithFilter(defaultRegion, + ImmutableMultimap.builder() + .put("volume-id", volumeId).build()), + ImmutableSet.of()); } - @Test(dependsOnMethods = "testGetCreateVolumePermissionForSnapshot") + @Test(dependsOnMethods = "testDeleteVolumeInRegion") void testDeleteSnapshotInRegion() { client.deleteSnapshotInRegion(snapshot.getRegion(), snapshot.getId()); assert client.describeSnapshotsInRegion(snapshot.getRegion(), snapshotIds(snapshot.getId())).size() == 0; diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSAMIApiLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSAMIApiLiveTest.java index a8a5ccc1ec..f0b7b2f4de 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSAMIApiLiveTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSAMIApiLiveTest.java @@ -16,18 +16,38 @@ */ package org.jclouds.aws.ec2.features; +import static com.google.common.collect.Iterables.concat; +import static com.google.common.collect.Iterables.getOnlyElement; +import static java.util.concurrent.TimeUnit.SECONDS; import static org.jclouds.aws.ec2.options.AWSDescribeImagesOptions.Builder.filters; +import static org.jclouds.ec2.options.RegisterImageBackedByEbsOptions.Builder.addNewBlockDevice; +import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withBlockDeviceMappings; +import static org.jclouds.util.Predicates2.retry; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; +import java.util.Properties; import java.util.Set; -import org.jclouds.aws.domain.Region; -import org.jclouds.ec2.domain.Image; -import org.jclouds.ec2.features.AMIApiLiveTest; -import org.testng.annotations.Test; - +import com.google.common.base.Predicate; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import org.jclouds.Constants; +import org.jclouds.aws.domain.Region; +import org.jclouds.compute.RunNodesException; +import org.jclouds.ec2.domain.BlockDevice; +import org.jclouds.ec2.domain.BlockDeviceMapping; +import org.jclouds.ec2.domain.Image; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.domain.Snapshot; +import org.jclouds.ec2.domain.Volume; +import org.jclouds.ec2.features.AMIApiLiveTest; +import org.jclouds.ec2.options.RegisterImageBackedByEbsOptions; +import org.jclouds.ec2.options.RunInstancesOptions; +import org.jclouds.ec2.predicates.SnapshotCompleted; +import org.testng.annotations.Test; /** * Tests behavior of {@code AMIApi} @@ -39,6 +59,13 @@ public class AWSAMIApiLiveTest extends AMIApiLiveTest { provider = "aws-ec2"; } + @Override + protected Properties setupProperties() { + Properties overrides = super.setupProperties(); + overrides.put(Constants.PROPERTY_API_VERSION, "2014-05-01"); + return overrides; + } + public void testDescribeImagesCC() { Set ccResults = client.describeImagesInRegion(Region.US_EAST_1, filters(ImmutableMultimap. builder()// @@ -53,4 +80,50 @@ public class AWSAMIApiLiveTest extends AMIApiLiveTest { assertNotNull(ccResults); assert ccResults.size() >= 34 : ccResults; } + + protected RegisterImageBackedByEbsOptions newBlockDeviceOption() { + return addNewBlockDevice("/dev/sda2", "myvirtual", 5, false, "gp2", null, false).withDescription("adrian"); + } + + protected Image.EbsBlockDevice newBlockDeviceInfo() { + return new Image.EbsBlockDevice(null, 5, false, "gp2", null, false); + } + + + @Override + protected Snapshot createSnapshot() throws RunNodesException { + + String instanceId = null; + try { + BlockDeviceMapping mapping = new BlockDeviceMapping.MapNewVolumeToDevice("/dev/sdb", 1, true, "gp2", null, false); + RunInstancesOptions options = withBlockDeviceMappings(ImmutableSet + . of(mapping)); + + RunningInstance instance = getOnlyElement(concat(ec2Api.getInstanceApi().get().runInstancesInRegion( + regionId, null, imageId, 1, 1, options))); + instanceId = instance.getId(); + + assertTrue(runningTester.apply(instance), instanceId + "didn't achieve the state running!"); + + instance = getOnlyElement(concat(ec2Api.getInstanceApi().get().describeInstancesInRegion(regionId, + instanceId))); + BlockDevice gp2Device = instance.getEbsBlockDevices().get("/dev/sdb"); + assertNotNull(gp2Device, "device /dev/sdb not present on " + instance); + Volume gp2Volume = Iterables.getOnlyElement(ec2Api.getElasticBlockStoreApi().get().describeVolumesInRegion(regionId, gp2Device.getVolumeId())); + assertNotNull(gp2Volume, "/dev/sdb volume is null"); + assertEquals(gp2Volume.getVolumeType(), "gp2"); + BlockDevice device = instance.getEbsBlockDevices().get("/dev/sda1"); + assertNotNull(device, "device: /dev/sda1 not present on: " + instance); + Snapshot snapshot = ec2Api.getElasticBlockStoreApi().get().createSnapshotInRegion(regionId, + device.getVolumeId()); + snapshotsToDelete.add(snapshot.getId()); + Predicate snapshotted = retry(new SnapshotCompleted(ec2Api.getElasticBlockStoreApi().get()), 600, 10, SECONDS); + assert snapshotted.apply(snapshot); + return snapshot; + } finally { + if (instanceId != null) + ec2Api.getInstanceApi().get().terminateInstancesInRegion(regionId, instanceId); + } + } + } diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSElasticBlockStoreApiLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSElasticBlockStoreApiLiveTest.java new file mode 100644 index 0000000000..689118d308 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSElasticBlockStoreApiLiveTest.java @@ -0,0 +1,68 @@ +/* + * 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.CreateVolumeOptions.Builder.volumeType; +import static org.jclouds.ec2.options.CreateVolumeOptions.Builder.withSize; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +import java.util.Properties; +import java.util.Set; + +import com.google.common.collect.Sets; +import org.jclouds.Constants; +import org.jclouds.ec2.domain.Volume; +import org.jclouds.ec2.features.ElasticBlockStoreApiLiveTest; +import org.testng.annotations.Test; + +/** + * Tests behavior of {@code ElasticBlockStoreApi} + */ +@Test(groups = "live", singleThreaded = true) +public class AWSElasticBlockStoreApiLiveTest extends ElasticBlockStoreApiLiveTest { + + public AWSElasticBlockStoreApiLiveTest() { + provider = "aws-ec2"; + } + + @Override + protected Properties setupProperties() { + Properties overrides = super.setupProperties(); + overrides.put(Constants.PROPERTY_API_VERSION, "2014-05-01"); + return overrides; + } + + @Test + void testCreateVolumeInAvailabilityZoneWithVolumeType() { + Volume expected = client.createVolumeInAvailabilityZone(defaultZone, + volumeType("gp2"), withSize(1)); + assertNotNull(expected); + assertEquals(expected.getAvailabilityZone(), defaultZone); + assertEquals(expected.getVolumeType(), "gp2"); + + Set 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()); + + client.deleteVolumeInRegion(volume.getRegion(), volume.getId()); + } + +}