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/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java new file mode 100644 index 0000000..527123a --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java @@ -0,0 +1,575 @@ +/* + * 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.compute.strategy; + +import static com.google.common.io.BaseEncoding.base64; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.testng.Assert.assertEquals; + +import javax.inject.Provider; +import java.lang.reflect.Method; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ExecutionException; + +import com.google.common.base.Function; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; +import org.jclouds.aws.domain.Region; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.functions.GroupNamingConvention; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.LoginCredentials; +import org.jclouds.ec2.compute.domain.EC2HardwareBuilder; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.domain.BlockDeviceMapping; +import org.jclouds.ec2.domain.KeyPair; +import org.jclouds.ec2.options.RunInstancesOptions; +import org.jclouds.scriptbuilder.domain.Statements; +import org.testng.annotations.Test; + +@Test(groups = "unit", singleThreaded = true, testName = "CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest") +public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { + + public static final LoginCredentials CREDENTIALS = LoginCredentials + .builder() + .privateKey( + "-----BEGIN RSA PRIVATE KEY-----\n" + + "MIIEowIBAAKCAQEA0CbFlhSdbMdad2ux2BVqk6Ut5fLKb0CdbqubGcEBfwsSz9Rp4Ile76P90MpV\n" + + "W1BGKL5V4MO+flG6dZnRWPVmgrNVyDTmEsALiMGjfEwbACEZ1A8C6mPa36wWO7MlxuyMjg8OczTB\n" + + "EXnHNDpxE5a6KowJtzFlmgjHk2Y+Q42UIqPx47lQUv5bdMDCnfNNomSzTVRjOZLUkDja+ybCKdux\n" + + "gqTsuInhuBRMx+wxff8Z43ECdJV6UPoXK3der1dlZunxGCFkCeYq0kCX7FZ7PV35X744jqhD8P+7\n" + + "y5prO4W+M3DWgChUx0OlbDbSHtDVlcfdbj/+4AKYKU6rQOqh+4DPDQIDAQABAoIBAHjQuEiXKJSV\n" + + "1U2RZcVtENInws9AL/2I/Jfa5Qh6vTqXG9EjklywfzkK72x7tDVvD3ngmAoAs5WwLFDL+fXvYhOk\n" + + "sbql8ZCahVdYRWME7XsSu2IZYHDZipXe1XzLS7b9X8uos5Ns4E8bZuNKtI1RJDdD1vPMqRNR2z0T\n" + + "0Dn3eC7t+t+t7PWaK5AXu2ot7DoOeG1QhqJbwd5pMkIn2ydBILytgmDk/2P3EtJGePIJIeQBicmw\n" + + "Z0KrJFa/K2cC8AtmMJUoZMo+mh1yemDbDLCZW30PjFHbZtcszS2cydAgq/HDFkZynvZG0zhbx/To\n" + + "jzcNza1AyypYwOwb2/9/ulXZp0UCgYEA+QFgWDfYLH2zwjU5b6e0UbIyd/X/yRZ+L8lOEBd0Bbu8\n" + + "qO3txaDbwi7o2mG7pJENHJ3u62CHjgTGDNW9V9Q8eNoGtj3uHvMvi7FdDEK8B6izdZyR7hmZmQ/5\n" + + "MIldelyiGZlz1KBSoy4FsCpA7hV7cI6H6x+Im24NxG90/wd/EgMCgYEA1f+cUyUisIO3yKOCf0hQ\n" + + "aL289q2//F2cbvBxtki6I8JzTg1H3oTO2WVrXQeCA3a/yiuRUatgGH4mxrpCF6byVJyqrEWAj4kU\n" + + "uTbhMgIYhLGoaF1e+vMirCRXUXox0i5X976ASzHn64V9JSd1B+UbKfpcFTYYnChmrRDzmhKN1a8C\n" + + "gYBTvIHAyO7ab18/BRUOllAOVSWhr8lXv0eqHEEzKh/rOaoFCRY3qpOcZpgJsGogumK1Z+sLnoeX\n" + + "W8WaVVp6KbY4UeGF8aedItyvVnLbB6ohzTqkZ4Wvk05S6cs75kXYO0SL5U3NiCiiFXz2NA9nwTOk\n" + + "s1nD2PPgiQ76Kx0mEkhKLwKBgFhHEJqv+AZu37Kx2NRe5WS/2KK9/DPD/hM5tv7mM3sq7Nvm2J3v\n" + + "lVDS6J5AyZ5aLzXcER9qncKcz6wtC7SsFs1Wr4VPSoBroRPikrVJbgnXK8yZr+O/xq7Scv7WdJTq\n" + + "rzkw6cWbObvLnltkUn/GQBVqBPBvF2nbtLdyBbuqKb5bAoGBAI1+aoJnvXEXxT4UHrMkQcY0eXRz\n" + + "3UdbzJmtjMW9CR6l9s11mV6PcZP4qnODp3nd6a+lPeL3wVYQ47DsTJ/Bx5dI17zA5mU57n6mV0a3\n" + + "DbSoPKSdaKTQdo2THnVE9P9sPKZWueAcsE4Yw/qcTjoxrtUnAH/AXN250v0tkKIOvMhu\n" + + "-----END RSA PRIVATE KEY-----").build(); + + public static final KeyPair KEYPAIR = KeyPair.builder().region(Region.AP_SOUTHEAST_1).keyName("myKeyPair") + .sha1OfPrivateKey("13:36:74:b9:56:bb:07:96:c0:19:ab:00:7f:9f:06:d2:16:a0:45:32") + .fingerprint("60:15:d1:f1:d9:e2:3c:e2:ee:a9:64:6a:42:a7:34:0c").keyMaterial(CREDENTIALS.credential).build(); + + private static final Provider<RunInstancesOptions> OPTIONS_PROVIDER = new javax.inject.Provider<RunInstancesOptions>() { + + @Override + public RunInstancesOptions get() { + return new RunInstancesOptions(); + } + + }; + + public void testExecuteWithDefaultOptionsEC2() throws SecurityException, NoSuchMethodException { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String group = "group"; + Hardware size = EC2HardwareBuilder.m1_small().build(); + String systemGeneratedKeyPairName = "systemGeneratedKeyPair"; + String generatedGroup = "group"; + Set<String> generatedGroups = ImmutableSet.of(generatedGroup); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class, + new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) }); + + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + Template template = createMock(Template.class); + + // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); + expect(template.getHardware()).andReturn(size).atLeastOnce(); + expect(template.getOptions()).andReturn(options).atLeastOnce(); + expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce(); + expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options)).andReturn( + systemGeneratedKeyPairName); + expect(strategy.getSecurityGroupsForTagAndOptions(region, group, options)).andReturn(generatedGroups); + expect(options.getUserData()).andReturn(null); + expect(options.getClientToken()).andReturn(null); + + // replay mocks + replay(options); + replay(template); + replay(strategy); + + // run + RunInstancesOptions customize = strategy.execute(region, group, template); + assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of()); + assertEquals( + customize.buildFormParameters().entries(), + ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1", + generatedGroup, "KeyName", systemGeneratedKeyPairName).entries()); + assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of()); + assertEquals(customize.buildStringPayload(), null); + + // verify mocks + verify(options); + verify(template); + verify(strategy); + } + + public void testExecuteWithUserData() throws SecurityException, NoSuchMethodException { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String group = "group"; + Hardware size = EC2HardwareBuilder.m1_small().build(); + String systemGeneratedKeyPairName = "systemGeneratedKeyPair"; + String generatedGroup = "group"; + Set<String> generatedGroups = ImmutableSet.of(generatedGroup); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class, + new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) }); + + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + Template template = createMock(Template.class); + + // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); + expect(template.getHardware()).andReturn(size).atLeastOnce(); + expect(template.getOptions()).andReturn(options).atLeastOnce(); + expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce(); + expect(options.getClientToken()).andReturn("some-token"); + expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options)).andReturn( + systemGeneratedKeyPairName); + expect(strategy.getSecurityGroupsForTagAndOptions(region, group, options)).andReturn(generatedGroups); + expect(options.getUserData()).andReturn("hello".getBytes()); + + // replay mocks + replay(options); + replay(template); + replay(strategy); + + // run + RunInstancesOptions customize = strategy.execute(region, group, template); + assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of()); + assertEquals( + customize.buildFormParameters().entries(), + ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1", "group", + "KeyName", systemGeneratedKeyPairName, "UserData", base64().encode("hello".getBytes()), + "ClientToken", "some-token").entries()); + + assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of()); + assertEquals(customize.buildStringPayload(), null); + + // verify mocks + verify(options); + verify(template); + verify(strategy); + } + + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldTo() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String group = "group"; + String userSuppliedKeyPair = "myKeyPair"; + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.getLoginPrivateKey()).andReturn(null); + expect(options.getRunScript()).andReturn(null); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options), userSuppliedKeyPair); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldToWithRunScriptButNoCredentials() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String group = "group"; + String userSuppliedKeyPair = "myKeyPair"; + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.getLoginUser()).andReturn(null); + expect(options.getLoginPassword()).andReturn(null); + expect(options.getLoginPrivateKey()).andReturn(null); + expect(options.shouldAuthenticateSudo()).andReturn(null); + expect(options.getRunScript()).andReturn(Statements.exec("echo foo")); + + expect(strategy.credentialsMap.containsKey(new RegionAndName(region, userSuppliedKeyPair))).andReturn(false); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options), userSuppliedKeyPair); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldToWithRunScriptAndCredentialsAlreadyInMap() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String group = "group"; + String userSuppliedKeyPair = "myKeyPair"; + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.getLoginPrivateKey()).andReturn(null); + expect(options.getRunScript()).andReturn(Statements.exec("echo foo")); + + expect(strategy.credentialsMap.containsKey(new RegionAndName(region, userSuppliedKeyPair))).andReturn(true); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options), userSuppliedKeyPair); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldToWithRunScriptAndCredentialsSpecified() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String group = "group"; + String userSuppliedKeyPair = "myKeyPair"; + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.getLoginPrivateKey()).andReturn(CREDENTIALS.getOptionalPrivateKey().get()).atLeastOnce(); + + // Notice that the fingerprint and sha1 generated + expect(strategy.credentialsMap.put(new RegionAndName(region, userSuppliedKeyPair), KEYPAIR)).andReturn(null); + expect(options.getRunScript()).andReturn(Statements.exec("echo foo")); + expect(strategy.credentialsMap.containsKey(new RegionAndName(region, userSuppliedKeyPair))).andReturn(true); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options), userSuppliedKeyPair); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_createsNewKeyPairAndReturnsItsNameByDefault() + throws ExecutionException { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String group = "group"; + String userSuppliedKeyPair = null; + boolean shouldAutomaticallyCreateKeyPair = true; + String systemGeneratedKeyPairName = "systemGeneratedKeyPair"; + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair); + expect(keyPair.getKeyName()).andReturn(systemGeneratedKeyPairName).atLeastOnce(); + expect(strategy.credentialsMap.containsKey(new RegionAndName(region, group))).andReturn(true); + expect(strategy.credentialsMap.get(new RegionAndName(region, group))).andReturn(keyPair); + expect(options.getRunScript()).andReturn(null); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options), + systemGeneratedKeyPairName); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_doesntCreateAKeyPairAndReturnsNullWhenToldNotTo() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String group = "group"; + String userSuppliedKeyPair = null; + boolean shouldAutomaticallyCreateKeyPair = false; // here's the important + // part! + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.getRunScript()).andReturn(null); + expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options), null); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + public void testGetSecurityGroupsForTagAndOptions_createsNewGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesntExist() + throws ExecutionException { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String group = "group"; + String generatedMarkerGroup = "jclouds#group"; + Set<String> groupIds = ImmutableSet.<String> of(); + int[] ports = {}; + boolean shouldAuthorizeSelf = true; + Set<String> returnVal = ImmutableSet.<String> of(generatedMarkerGroup); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + + // setup expectations + expect(options.getGroups()).andReturn(groupIds).atLeastOnce(); + expect(options.getInboundPorts()).andReturn(ports).atLeastOnce(); + RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, + ports, shouldAuthorizeSelf); + expect(strategy.securityGroupMap.getUnchecked(regionNameAndIngressRules)).andReturn(group); + + // replay mocks + replay(options); + replayStrategy(strategy); + + // run + assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, group, options), returnVal); + + // verify mocks + verify(options); + verifyStrategy(strategy); + } + + public void testGetSecurityGroupsForTagAndOptions_createsNewGroupByDefaultWhenPortsAreSpecifiedWhenDoesntExist() + throws ExecutionException { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String group = "group"; + String generatedMarkerGroup = "jclouds#group"; + Set<String> groupIds = ImmutableSet.<String> of(); + int[] ports = { 22, 80 }; + boolean shouldAuthorizeSelf = true; + Set<String> returnVal = ImmutableSet.<String> of(generatedMarkerGroup); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + + // setup expectations + expect(options.getGroups()).andReturn(groupIds).atLeastOnce(); + expect(options.getInboundPorts()).andReturn(ports).atLeastOnce(); + RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, + ports, shouldAuthorizeSelf); + expect(strategy.securityGroupMap.getUnchecked(regionNameAndIngressRules)).andReturn(generatedMarkerGroup); + + // replay mocks + replay(options); + replayStrategy(strategy); + + // run + assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, group, options), returnVal); + + // verify mocks + verify(options); + verifyStrategy(strategy); + } + + public void testGetSecurityGroupsForTagAndOptions_reusesGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesExist() + throws ExecutionException { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String group = "group"; + String generatedMarkerGroup = "jclouds#group"; + Set<String> groupIds = ImmutableSet.<String> of(); + int[] ports = {}; + boolean shouldAuthorizeSelf = true; + Set<String> returnVal = ImmutableSet.<String> of(generatedMarkerGroup); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + + // setup expectations + expect(options.getGroups()).andReturn(groupIds).atLeastOnce(); + expect(options.getInboundPorts()).andReturn(ports).atLeastOnce(); + RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, + ports, shouldAuthorizeSelf); + expect(strategy.securityGroupMap.getUnchecked(regionNameAndIngressRules)).andReturn(generatedMarkerGroup); + + // replay mocks + replay(options); + replayStrategy(strategy); + + // run + assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, group, options), returnVal); + + // verify mocks + verify(options); + verifyStrategy(strategy); + } + + public void testGetSecurityGroupsForTagAndOptions_reusesGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesExistAndAcceptsUserSuppliedGroups() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String group = "group"; + String generatedMarkerGroup = "jclouds#group"; + Set<String> groupIds = ImmutableSet.<String> of("group1", "group2"); + int[] ports = {}; + boolean shouldAuthorizeSelf = true; + boolean groupExisted = true; + Set<String> returnVal = ImmutableSet.<String> of(generatedMarkerGroup, "group1", "group2"); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + + // setup expectations + expect(options.getGroups()).andReturn(groupIds).atLeastOnce(); + RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, + ports, shouldAuthorizeSelf); + + expect(strategy.securityGroupMap.getUnchecked(regionNameAndIngressRules)) + .andReturn(groupExisted ? "group" : null); + + // replay mocks + replay(options); + replayStrategy(strategy); + + // run + assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, group, options), returnVal); + + // verify mocks + verify(options); + verifyStrategy(strategy); + } + + private void verifyStrategy(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy) { + verify(strategy.makeKeyPair); + verify(strategy.credentialsMap); + verify(strategy.securityGroupMap); + } + + @SuppressWarnings("unchecked") + private CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions setupStrategy() { + Function<RegionAndName, KeyPair> makeKeyPair = createMock(Function.class); + ConcurrentMap<RegionAndName, KeyPair> credentialsMap = createMock(ConcurrentMap.class); + LoadingCache<RegionAndName, String> securityGroupMap = createMock(LoadingCache.class); + GroupNamingConvention.Factory namingConventionFactory = createMock(GroupNamingConvention.Factory.class); + GroupNamingConvention namingConvention = createMock(GroupNamingConvention.class); + expect(namingConventionFactory.create()).andReturn(namingConvention).anyTimes(); + expect(namingConvention.sharedNameForGroup("group")).andReturn("jclouds#group").anyTimes(); + replay(namingConventionFactory); + replay(namingConvention); + + return new CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions(makeKeyPair, credentialsMap, + securityGroupMap, OPTIONS_PROVIDER, namingConventionFactory); + } + + private void replayStrategy(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy) { + replay(strategy.makeKeyPair); + replay(strategy.credentialsMap); + replay(strategy.securityGroupMap); + } + +}
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/compute/strategy/EC2CreateNodesInGroupThenAddToSetTest.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSetTest.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSetTest.java new file mode 100644 index 0000000..86f39bc --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSetTest.java @@ -0,0 +1,340 @@ +/* + * 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.compute.strategy; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.eq; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.reportMatcher; +import static org.easymock.EasyMock.verify; + +import java.util.Map; +import java.util.Set; + +import com.google.common.base.Optional; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Multimap; +import org.easymock.IArgumentMatcher; +import org.jclouds.compute.config.CustomizationResponse; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.NodeMetadata.Status; +import org.jclouds.compute.domain.NodeMetadataBuilder; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.predicates.AtomicNodeRunning; +import org.jclouds.compute.strategy.GetNodeMetadataStrategy; +import org.jclouds.compute.util.ComputeUtils; +import org.jclouds.domain.Credentials; +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; +import org.jclouds.domain.LoginCredentials; +import org.jclouds.ec2.EC2Api; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.functions.PresentInstances; +import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.domain.Reservation; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.features.ElasticIPAddressApi; +import org.jclouds.ec2.features.InstanceApi; +import org.jclouds.ec2.options.RunInstancesOptions; +import org.testng.Assert; +import org.testng.annotations.Test; + +@Test(groups = "unit", singleThreaded = true, testName = "EC2CreateNodesInGroupThenAddToSetTest") +public class EC2CreateNodesInGroupThenAddToSetTest { + + @SuppressWarnings("unchecked") + public void testIpAllocationThenAfterNodeRunningAssignThenUpdateCache() { + Location location = ZONE_AP_SOUTHEAST_1A; + String region = "ap-southeast-1"; + String zone = "ap-southeast-1a"; + + String imageId = "ami1"; + String instanceCreatedId = "instance1"; + NodeMetadata nodeMetadata = new NodeMetadataBuilder().id(region + "/" + instanceCreatedId) + .providerId(instanceCreatedId).status(Status.RUNNING).build(); + // setup mocks + EC2CreateNodesInGroupThenAddToSet strategy = setupStrategy(nodeMetadata); + InputParams input = new InputParams(location); + InstanceApi instanceClient = createMock(InstanceApi.class); + ElasticIPAddressApi ipClient = createMock(ElasticIPAddressApi.class); + RunInstancesOptions ec2Options = createMock(RunInstancesOptions.class); + RunningInstance instance = createMock(RunningInstance.class); + Reservation<? extends RunningInstance> reservation = new Reservation<RunningInstance>(region, + ImmutableSet.<String> of(), ImmutableSet.<RunningInstance> of(instance), "ownerId", "requesterId", + "reservationId"); + + // enable auto-allocation + strategy.autoAllocateElasticIps = true; + + // setup expectations + expect(input.template.clone()).andReturn(input.template); + expect(strategy.client.getInstanceApi()).andReturn((Optional) Optional.of(instanceClient)).atLeastOnce(); + expect( + strategy.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize + .execute(region, input.tag, input.template)).andReturn(ec2Options); + expect(strategy.client.getElasticIPAddressApi()).andReturn((Optional) Optional.of(ipClient)).atLeastOnce(); + + expect(input.template.getLocation()).andReturn(input.location).atLeastOnce(); + expect(input.template.getImage()).andReturn(input.image).atLeastOnce(); + expect(input.image.getProviderId()).andReturn(imageId).atLeastOnce(); + + // differences when ip allocation + expect(ipClient.allocateAddressInRegion(region)).andReturn("1.1.1.1"); + expect(strategy.runningInstanceToNodeMetadata.apply(instance)).andReturn(nodeMetadata).atLeastOnce(); + ipClient.associateAddressInRegion(region, "1.1.1.1", instanceCreatedId); + strategy.elasticIpCache.put(new RegionAndName(region, instanceCreatedId), "1.1.1.1"); + + expect(instanceClient.runInstancesInRegion(region, zone, imageId, 1, input.count, ec2Options)).andReturn( + Reservation.class.cast(reservation)); + expect(instance.getId()).andReturn(instanceCreatedId).atLeastOnce(); + // simulate a lazy credentials fetch + LoginCredentials creds = LoginCredentials.builder().user("foo").privateKey("bar").build(); + expect(strategy.instanceToCredentials.getUnchecked(instance)).andReturn(Optional.of(creds)); + expect(instance.getRegion()).andReturn(region).atLeastOnce(); + expect(strategy.credentialStore.put("node#" + region + "/" + instanceCreatedId, creds)).andReturn(null); + + expect(strategy.presentInstances.apply(ImmutableSet.of(new RegionAndName(region, instanceCreatedId)))).andReturn(ImmutableSet.of(instance)); + expect(input.template.getOptions()).andReturn(input.options).atLeastOnce(); + expect(input.options.getLoginUser()).andReturn(null); + expect(input.options.getLoginPassword()).andReturn(null); + expect(input.options.getLoginPrivateKey()).andReturn(null); + expect(input.options.shouldAuthenticateSudo()).andReturn(null); + expect(input.options.getMaxCount()).andReturn(0); + + expect( + strategy.utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(eq(input.options), + containsNodeMetadata(nodeMetadata), eq(input.nodes), eq(input.badNodes), eq(input.customization))) + .andReturn(null); + + // replay mocks + replay(instanceClient); + replay(ipClient); + replay(ec2Options); + replay(instance); + input.replayMe(); + replayStrategy(strategy); + + // run + strategy.execute(input.tag, input.count, input.template, input.nodes, input.badNodes, input.customization); + + // verify mocks + verify(instanceClient); + verify(ipClient); + verify(ec2Options); + verify(instance); + input.verifyMe(); + verifyStrategy(strategy); + } + + @Test + public void testZoneAsALocation() { + assertRegionAndZoneForLocation(ZONE_AP_SOUTHEAST_1A, "ap-southeast-1", "ap-southeast-1a"); + } + + @Test + public void testRegionAsALocation() { + assertRegionAndZoneForLocation(REGION_AP_SOUTHEAST_1, "ap-southeast-1", null); + } + + // // fixtures + + public static Iterable<NodeMetadata> containsNodeMetadata(final NodeMetadata in) { + reportMatcher(new IArgumentMatcher() { + + @Override + public void appendTo(StringBuffer buffer) { + buffer.append("contains("); + buffer.append(in); + buffer.append(")"); + } + + @Override + public boolean matches(Object arg) { + return Iterables.contains((Iterable<?>) arg, in); + } + + }); + return null; + } + + @SuppressWarnings("unchecked") + private void assertRegionAndZoneForLocation(Location location, String region, String zone) { + String imageId = "ami1"; + String instanceCreatedId = "instance1"; + NodeMetadata nodeMetadata = new NodeMetadataBuilder().id(region + "/" + instanceCreatedId) + .providerId(instanceCreatedId).status(Status.RUNNING).build(); + + // setup mocks + EC2CreateNodesInGroupThenAddToSet strategy = setupStrategy(nodeMetadata); + InputParams input = new InputParams(location); + InstanceApi instanceClient = createMock(InstanceApi.class); + RunInstancesOptions ec2Options = createMock(RunInstancesOptions.class); + RunningInstance instance = createMock(RunningInstance.class); + Reservation<? extends RunningInstance> reservation = new Reservation<RunningInstance>(region, + ImmutableSet.<String> of(), ImmutableSet.<RunningInstance> of(instance), "ownerId", "requesterId", + "reservationId"); + + // setup expectations + expect(input.template.clone()).andReturn(input.template); + expect(strategy.client.getInstanceApi()).andReturn((Optional) Optional.of(instanceClient)).atLeastOnce(); + expect( + strategy.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize + .execute(region, input.tag, input.template)).andReturn(ec2Options); + expect(input.template.getLocation()).andReturn(input.location).atLeastOnce(); + expect(input.template.getImage()).andReturn(input.image).atLeastOnce(); + expect(input.image.getProviderId()).andReturn(imageId).atLeastOnce(); + expect(instanceClient.runInstancesInRegion(region, zone, imageId, 1, input.count, ec2Options)).andReturn( + Reservation.class.cast(reservation)); + expect(instance.getId()).andReturn(instanceCreatedId).atLeastOnce(); + // simulate a lazy credentials fetch + LoginCredentials creds = LoginCredentials.builder().user("foo").privateKey("bar").build(); + expect(strategy.instanceToCredentials.getUnchecked(instance)).andReturn(Optional.of(creds)); + expect(instance.getRegion()).andReturn(region).atLeastOnce(); + expect(strategy.credentialStore.put("node#" + region + "/" + instanceCreatedId, creds)).andReturn(null); + + expect(strategy.presentInstances.apply(ImmutableSet.of(new RegionAndName(region, instanceCreatedId)))).andReturn(ImmutableSet.of(instance)); + expect(input.template.getOptions()).andReturn(input.options).atLeastOnce(); + expect(input.options.getLoginUser()).andReturn(null); + expect(input.options.getLoginPassword()).andReturn(null); + expect(input.options.getLoginPrivateKey()).andReturn(null); + expect(input.options.shouldAuthenticateSudo()).andReturn(null); + expect(input.options.getMaxCount()).andReturn(0); + + expect(strategy.runningInstanceToNodeMetadata.apply(instance)).andReturn(nodeMetadata); + expect( + strategy.utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(eq(input.options), + containsNodeMetadata(nodeMetadata), eq(input.nodes), eq(input.badNodes), eq(input.customization))) + .andReturn(null); + + // replay mocks + replay(instanceClient); + replay(ec2Options); + replay(instance); + input.replayMe(); + replayStrategy(strategy); + + // run + strategy.execute(input.tag, input.count, input.template, input.nodes, input.badNodes, input.customization); + + // verify mocks + verify(instanceClient); + verify(ec2Options); + verify(instance); + input.verifyMe(); + verifyStrategy(strategy); + } + + private static final Location REGION_AP_SOUTHEAST_1 = new LocationBuilder().scope(LocationScope.REGION) + .id("ap-southeast-1").description("ap-southeast-1") + .parent(new LocationBuilder().scope(LocationScope.PROVIDER).id("aws-ec2").description("aws-ec2").build()) + .build(); + private static final Location ZONE_AP_SOUTHEAST_1A = new LocationBuilder().scope(LocationScope.ZONE) + .id("ap-southeast-1a").description("ap-southeast-1a").parent(REGION_AP_SOUTHEAST_1).build(); + + // ///////////////////////////////////////////////////////////////////// + @SuppressWarnings("unchecked") + private static class InputParams { + String tag = "foo"; + int count = 1; + Template template = createMock(Template.class); + Set<NodeMetadata> nodes = createMock(Set.class); + Map<NodeMetadata, Exception> badNodes = createMock(Map.class); + Multimap<NodeMetadata, CustomizationResponse> customization = createMock(Multimap.class); + Hardware hardware = createMock(Hardware.class); + Image image = createMock(Image.class); + final Location location; + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + + public InputParams(Location location) { + this.location = location; + } + + void replayMe() { + replay(template); + replay(hardware); + replay(image); + replay(nodes); + replay(badNodes); + replay(customization); + replay(options); + } + + void verifyMe() { + verify(template); + verify(hardware); + verify(image); + verify(nodes); + verify(badNodes); + verify(customization); + verify(options); + } + } + + private void verifyStrategy(EC2CreateNodesInGroupThenAddToSet strategy) { + verify(strategy.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize); + verify(strategy.client); + verify(strategy.elasticIpCache); + verify(strategy.presentInstances); + verify(strategy.runningInstanceToNodeMetadata); + verify(strategy.instanceToCredentials); + verify(strategy.credentialStore); + verify(strategy.utils); + } + + @SuppressWarnings("unchecked") + private EC2CreateNodesInGroupThenAddToSet setupStrategy(final NodeMetadata node) { + EC2Api client = createMock(EC2Api.class); + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize = createMock(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class); + PresentInstances presentInstances = createMock(PresentInstances.class); + RunningInstanceToNodeMetadata runningInstanceToNodeMetadata = createMock(RunningInstanceToNodeMetadata.class); + LoadingCache<RunningInstance, Optional<LoginCredentials>> instanceToCredentials = createMock(LoadingCache.class); + LoadingCache<RegionAndName, String> elasticIpCache = createMock(LoadingCache.class); + GetNodeMetadataStrategy nodeRunning = new GetNodeMetadataStrategy() { + + @Override + public NodeMetadata getNode(String input) { + Assert.assertEquals(input, node.getId()); + return node; + } + + }; + Map<String, Credentials> credentialStore = createMock(Map.class); + ComputeUtils utils = createMock(ComputeUtils.class); + return new EC2CreateNodesInGroupThenAddToSet(client, elasticIpCache, new AtomicNodeRunning(nodeRunning), + createKeyPairAndSecurityGroupsAsNeededAndReturncustomize, presentInstances, runningInstanceToNodeMetadata, + instanceToCredentials, credentialStore, utils); + } + + private void replayStrategy(EC2CreateNodesInGroupThenAddToSet strategy) { + replay(strategy.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize); + replay(strategy.client); + replay(strategy.elasticIpCache); + replay(strategy.presentInstances); + replay(strategy.runningInstanceToNodeMetadata); + replay(strategy.instanceToCredentials); + replay(strategy.credentialStore); + replay(strategy.utils); + } + +} 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/compute/strategy/EC2DestroyNodeStrategyTest.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/compute/strategy/EC2DestroyNodeStrategyTest.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/compute/strategy/EC2DestroyNodeStrategyTest.java new file mode 100644 index 0000000..077f4c8 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/compute/strategy/EC2DestroyNodeStrategyTest.java @@ -0,0 +1,186 @@ +/* + * 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.compute.strategy; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.testng.Assert.assertEquals; + +import java.util.concurrent.ExecutionException; + +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.strategy.GetNodeMetadataStrategy; +import org.jclouds.ec2.EC2Api; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.features.ElasticIPAddressApi; +import org.jclouds.ec2.features.InstanceApi; +import org.testng.annotations.Test; + +import com.google.common.base.Optional; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; + +@Test(groups = "unit", singleThreaded = true, testName = "EC2DestroyNodeStrategyTest") +public class EC2DestroyNodeStrategyTest { + + @SuppressWarnings("unchecked") + @Test + public void testDestroyNodeTerminatesInstanceAndReturnsRefreshedNode() throws Exception { + EC2Api client = createMock(EC2Api.class); + InstanceApi instanceClient = createMock(InstanceApi.class); + GetNodeMetadataStrategy getNode = createMock(GetNodeMetadataStrategy.class); + LoadingCache<RegionAndName, String> elasticIpCache = createMock(LoadingCache.class); + + NodeMetadata node = createMock(NodeMetadata.class); + + expect(client.getInstanceApi()).andReturn((Optional) Optional.of(instanceClient)).atLeastOnce(); + expect(instanceClient.terminateInstancesInRegion("region", "i-blah")).andReturn(null); + expect(getNode.getNode("region/i-blah")).andReturn(node); + + replay(client); + replay(getNode); + replay(instanceClient); + replay(elasticIpCache); + + EC2DestroyNodeStrategy destroyer = new EC2DestroyNodeStrategy(client, getNode, elasticIpCache); + + assertEquals(destroyer.destroyNode("region/i-blah"), node); + + verify(client); + verify(getNode); + verify(instanceClient); + verify(elasticIpCache); + } + + @SuppressWarnings("unchecked") + @Test + public void testDestroyNodeDisassociatesAndReleasesIpThenTerminatesInstanceAndReturnsRefreshedNode() + throws Exception { + EC2Api client = createMock(EC2Api.class); + GetNodeMetadataStrategy getNode = createMock(GetNodeMetadataStrategy.class); + LoadingCache<RegionAndName, String> elasticIpCache = createMock(LoadingCache.class); + ElasticIPAddressApi ipClient = createMock(ElasticIPAddressApi.class); + InstanceApi instanceClient = createMock(InstanceApi.class); + + NodeMetadata node = createMock(NodeMetadata.class); + + expect(elasticIpCache.get(new RegionAndName("region", "i-blah"))).andReturn("1.1.1.1"); + + expect(client.getElasticIPAddressApi()).andReturn((Optional) Optional.of(ipClient)).atLeastOnce(); + ipClient.disassociateAddressInRegion("region", "1.1.1.1"); + ipClient.releaseAddressInRegion("region", "1.1.1.1"); + elasticIpCache.invalidate(new RegionAndName("region", "i-blah")); + + + expect(client.getInstanceApi()).andReturn((Optional) Optional.of(instanceClient)).atLeastOnce(); + expect(instanceClient.terminateInstancesInRegion("region", "i-blah")).andReturn(null); + expect(getNode.getNode("region/i-blah")).andReturn(node); + + replay(client); + replay(getNode); + replay(elasticIpCache); + replay(instanceClient); + replay(ipClient); + + EC2DestroyNodeStrategy destroyer = new EC2DestroyNodeStrategy(client, getNode, elasticIpCache); + destroyer.autoAllocateElasticIps = true; + + assertEquals(destroyer.destroyNode("region/i-blah"), node); + + verify(client); + verify(getNode); + verify(elasticIpCache); + verify(instanceClient); + verify(ipClient); + } + + + @SuppressWarnings("unchecked") + @Test + public void testDestroyNodeSafeOnCacheMissThenTerminatesInstanceAndReturnsRefreshedNode() + throws Exception { + EC2Api client = createMock(EC2Api.class); + GetNodeMetadataStrategy getNode = createMock(GetNodeMetadataStrategy.class); + LoadingCache<RegionAndName, String> elasticIpCache = createMock(LoadingCache.class); + ElasticIPAddressApi ipClient = createMock(ElasticIPAddressApi.class); + InstanceApi instanceClient = createMock(InstanceApi.class); + + NodeMetadata node = createMock(NodeMetadata.class); + + expect(elasticIpCache.get(new RegionAndName("region", "i-blah"))).andThrow(new CacheLoader.InvalidCacheLoadException(null)); + + expect(client.getInstanceApi()).andReturn((Optional) Optional.of(instanceClient)).atLeastOnce(); + expect(instanceClient.terminateInstancesInRegion("region", "i-blah")).andReturn(null); + expect(getNode.getNode("region/i-blah")).andReturn(node); + + replay(client); + replay(getNode); + replay(elasticIpCache); + replay(instanceClient); + replay(ipClient); + + EC2DestroyNodeStrategy destroyer = new EC2DestroyNodeStrategy(client, getNode, elasticIpCache); + destroyer.autoAllocateElasticIps = true; + + assertEquals(destroyer.destroyNode("region/i-blah"), node); + + verify(client); + verify(getNode); + verify(elasticIpCache); + verify(instanceClient); + verify(ipClient); + } + + + @SuppressWarnings("unchecked") + @Test + public void testDestroyNodeSafeOnCacheExecutionExceptionThenTerminatesInstanceAndReturnsRefreshedNode() + throws Exception { + EC2Api client = createMock(EC2Api.class); + GetNodeMetadataStrategy getNode = createMock(GetNodeMetadataStrategy.class); + LoadingCache<RegionAndName, String> elasticIpCache = createMock(LoadingCache.class); + ElasticIPAddressApi ipClient = createMock(ElasticIPAddressApi.class); + InstanceApi instanceClient = createMock(InstanceApi.class); + + NodeMetadata node = createMock(NodeMetadata.class); + + expect(elasticIpCache.get(new RegionAndName("region", "i-blah"))).andThrow(new ExecutionException(null)); + + expect(client.getInstanceApi()).andReturn((Optional) Optional.of(instanceClient)).atLeastOnce(); + expect(instanceClient.terminateInstancesInRegion("region", "i-blah")).andReturn(null); + expect(getNode.getNode("region/i-blah")).andReturn(node); + + replay(client); + replay(getNode); + replay(elasticIpCache); + replay(instanceClient); + replay(ipClient); + + EC2DestroyNodeStrategy destroyer = new EC2DestroyNodeStrategy(client, getNode, elasticIpCache); + destroyer.autoAllocateElasticIps = true; + + assertEquals(destroyer.destroyNode("region/i-blah"), node); + + verify(client); + verify(getNode); + verify(elasticIpCache); + verify(instanceClient); + verify(ipClient); + } +} 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/config/EC2HttpApiModuleExpectTest.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/config/EC2HttpApiModuleExpectTest.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/config/EC2HttpApiModuleExpectTest.java new file mode 100644 index 0000000..737f880 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/config/EC2HttpApiModuleExpectTest.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.config; + +import static org.testng.Assert.assertEquals; + +import java.net.URI; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import org.jclouds.ec2.internal.BaseEC2ApiExpectTest; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.location.Region; +import org.jclouds.location.Zone; +import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; +import org.jclouds.location.functions.ZoneToEndpoint; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; +import com.google.common.collect.ImmutableSet; +import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.Module; +import com.google.inject.TypeLiteral; + +@Test(groups = "unit", testName = "EC2HttpApiModuleExpectTest") +public class EC2HttpApiModuleExpectTest extends BaseEC2ApiExpectTest<Injector> { + private Injector injector; + + @BeforeClass + @Override + protected void setupDefaultRequests() { + super.setupDefaultRequests(); + Builder<HttpRequest, HttpResponse> builder = ImmutableMap.<HttpRequest, HttpResponse> builder(); + builder.put(describeRegionsRequest, describeRegionsResponse); + builder.putAll(describeAvailabilityZonesRequestResponse); + + injector = requestsSendResponses(builder.build()); + } + + public void testLocationIdAndURIBindings() { + + assertEquals(injector.getInstance(Key.get(new TypeLiteral<Supplier<Set<String>>>() { + }, Region.class)).get(), ImmutableSet.<String> of("sa-east-1", "ap-northeast-1", "eu-west-1", "us-east-1", + "us-west-1", "us-west-2", "ap-southeast-1")); + + assertEquals(injector.getInstance(Key.get(new TypeLiteral<Supplier<Set<String>>>() { + }, Zone.class)).get(), ImmutableSet.<String> of("sa-east-1a", "sa-east-1b", "ap-northeast-1a", "ap-northeast-1b", + "eu-west-1a", "eu-west-1b", "eu-west-1c", "us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d", + "us-east-1e", "us-west-1a", "us-west-1b", "us-west-1c", "us-west-2a", "us-west-2b", "us-west-2c", + "ap-southeast-1a", "ap-southeast-1b")); + + Map<String, Supplier<URI>> regionToURISupplier = injector.getInstance( + Key.get(new TypeLiteral<Supplier<Map<String, Supplier<URI>>>>() { + }, Region.class)).get(); + + assertEquals(regionToURISupplier.get("sa-east-1").get(), URI.create("https://ec2.sa-east-1.amazonaws.com")); + assertEquals(regionToURISupplier.get("ap-northeast-1").get(), + URI.create("https://ec2.ap-northeast-1.amazonaws.com")); + assertEquals(regionToURISupplier.get("eu-west-1").get(), URI.create("https://ec2.eu-west-1.amazonaws.com")); + assertEquals(regionToURISupplier.get("us-east-1").get(), URI.create("https://ec2.us-east-1.amazonaws.com")); + assertEquals(regionToURISupplier.get("us-west-1").get(), URI.create("https://ec2.us-west-1.amazonaws.com")); + assertEquals(regionToURISupplier.get("us-west-2").get(), URI.create("https://ec2.us-west-2.amazonaws.com")); + assertEquals(regionToURISupplier.get("ap-southeast-1").get(), + URI.create("https://ec2.ap-southeast-1.amazonaws.com")); + + Map<String, Supplier<Set<String>>> regionToZoneIdSupplier = injector.getInstance( + Key.get(new TypeLiteral<Supplier<Map<String, Supplier<Set<String>>>>>() { + }, Zone.class)).get(); + + assertEquals(regionToZoneIdSupplier.get("sa-east-1").get(), ImmutableSet.of("sa-east-1a", "sa-east-1b")); + assertEquals(regionToZoneIdSupplier.get("ap-northeast-1").get(), + ImmutableSet.of("ap-northeast-1a", "ap-northeast-1b")); + assertEquals(regionToZoneIdSupplier.get("eu-west-1").get(), + ImmutableSet.of("eu-west-1a", "eu-west-1b", "eu-west-1c")); + assertEquals(regionToZoneIdSupplier.get("us-east-1").get(), + ImmutableSet.of("us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d", "us-east-1e")); + assertEquals(regionToZoneIdSupplier.get("us-west-1").get(), + ImmutableSet.of("us-west-1a", "us-west-1b", "us-west-1c")); + assertEquals(regionToZoneIdSupplier.get("us-west-2").get(), + ImmutableSet.of("us-west-2a", "us-west-2b", "us-west-2c")); + assertEquals(regionToZoneIdSupplier.get("ap-southeast-1").get(), + ImmutableSet.of("ap-southeast-1a", "ap-southeast-1b")); + + Map<String, Supplier<URI>> zoneToURISupplier = injector.getInstance( + Key.get(new TypeLiteral<Supplier<Map<String, Supplier<URI>>>>() { + }, Zone.class)).get(); + + assertEquals(zoneToURISupplier.get("sa-east-1a").get(), URI.create("https://ec2.sa-east-1.amazonaws.com")); + + assertEquals(zoneToURISupplier.get("ap-northeast-1a").get(), + URI.create("https://ec2.ap-northeast-1.amazonaws.com")); + + assertEquals(zoneToURISupplier.get("eu-west-1a").get(), URI.create("https://ec2.eu-west-1.amazonaws.com")); + + assertEquals(zoneToURISupplier.get("us-east-1a").get(), URI.create("https://ec2.us-east-1.amazonaws.com")); + + assertEquals(zoneToURISupplier.get("us-west-1a").get(), URI.create("https://ec2.us-west-1.amazonaws.com")); + + assertEquals(zoneToURISupplier.get("us-west-2a").get(), URI.create("https://ec2.us-west-2.amazonaws.com")); + + assertEquals(zoneToURISupplier.get("ap-southeast-1a").get(), + URI.create("https://ec2.ap-southeast-1.amazonaws.com")); + + } + + public void testZoneToEndpoint() { + assertEquals(injector.getInstance(ZoneToEndpoint.class).apply("us-west-2a"), + URI.create("https://ec2.us-west-2.amazonaws.com")); + } + + public void testRegionToEndpointOrProviderIfNull() { + assertEquals(injector.getInstance(RegionToEndpointOrProviderIfNull.class).apply("us-west-2"), + URI.create("https://ec2.us-west-2.amazonaws.com")); + } + + @Override + public Injector createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props) { + return createInjector(fn, module, props); + } + +} 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/AMIApiExpectTest.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AMIApiExpectTest.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AMIApiExpectTest.java new file mode 100644 index 0000000..e82d079 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AMIApiExpectTest.java @@ -0,0 +1,73 @@ +/* + * 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.Image; +import org.jclouds.ec2.internal.BaseEC2ApiExpectTest; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; + +@Test(groups = "unit", testName = "AMIApiExpectTest") +public class AMIApiExpectTest extends BaseEC2ApiExpectTest<EC2Api> { + + HttpRequest filter = HttpRequest.builder().method("POST") + .endpoint("https://ec2.us-east-1.amazonaws.com/") + .addHeader("Host", "ec2.us-east-1.amazonaws.com") + .addFormParam("Action", "DescribeImages") + .addFormParam("Filter.1.Name", "owner-id") + .addFormParam("Filter.1.Value.1", "206029621532") + .addFormParam("Signature", "BxOCrCYJujtaUqSPagRvv1ki76veVBiKK3yWHvRWgR0%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 testFilterWhenResponseIs2xx() { + HttpResponse filterResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/describe_images.xml", "text/xml")).build(); + + EC2Api apiWhenExist = requestsSendResponses(describeRegionsRequest, describeRegionsResponse, filter, filterResponse); + + Image image = getOnlyElement(apiWhenExist.getAMIApi().get().describeImagesInRegionWithFilter("us-east-1", + ImmutableMultimap.<String, String>builder() + .put("owner-id", "206029621532") + .build())); + + assertEquals(image.getId(), "ami-be3adfd7"); + } + + public void testFilterWhenResponseIs404() { + HttpResponse filterResponse = HttpResponse.builder().statusCode(404).build(); + + EC2Api apiWhenNotExist = requestsSendResponses(describeRegionsRequest, describeRegionsResponse, filter, filterResponse); + + assertEquals(apiWhenNotExist.getAMIApi().get().describeImagesInRegionWithFilter("us-east-1", + ImmutableMultimap.<String, String>builder() + .put("owner-id", "206029621532") + .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/AMIApiLiveTest.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AMIApiLiveTest.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AMIApiLiveTest.java new file mode 100644 index 0000000..367de3f --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/test/java/org/jclouds/ec2/features/AMIApiLiveTest.java @@ -0,0 +1,266 @@ +/* + * 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 com.google.common.collect.Iterables.concat; +import static com.google.common.collect.Iterables.getFirst; +import static com.google.common.collect.Iterables.getOnlyElement; +import static com.google.common.collect.Sets.newHashSet; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.imageIds; +import static org.jclouds.ec2.options.RegisterImageBackedByEbsOptions.Builder.addNewBlockDevice; +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.Iterator; +import java.util.Properties; +import java.util.Set; + +import org.jclouds.aws.AWSResponseException; +import org.jclouds.compute.RunNodesException; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilderSpec; +import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest; +import org.jclouds.ec2.EC2Api; +import org.jclouds.ec2.domain.BlockDevice; +import org.jclouds.ec2.domain.Image; +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; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; + +/** + * Tests behavior of {@code AMIApi} + */ +@Test(groups = "live", singleThreaded = true) +public class AMIApiLiveTest extends BaseComputeServiceContextLiveTest { + private TemplateBuilderSpec ebsTemplate; + + public AMIApiLiveTest() { + provider = "ec2"; + } + + @Override + protected Properties setupProperties() { + Properties overrides = super.setupProperties(); + String ebsSpec = checkNotNull(setIfTestSystemPropertyPresent(overrides, provider + ".ebs-template"), provider + + ".ebs-template"); + ebsTemplate = TemplateBuilderSpec.parse(ebsSpec); + return overrides; + } + + protected EC2Api ec2Api; + protected AMIApi client; + + protected Predicate<RunningInstance> runningTester; + + protected Set<String> imagesToDeregister = newHashSet(); + protected Set<String> snapshotsToDelete = newHashSet(); + protected String regionId; + protected String ebsBackedImageId; + protected String ebsBackedImageName = "jcloudstest1"; + protected String imageId; + + @Override + @BeforeClass(groups = { "integration", "live" }) + public void setupContext() { + super.setupContext(); + ec2Api = view.unwrapApi(EC2Api.class); + runningTester = retry(new InstanceStateRunning(ec2Api), 600, 5, SECONDS); + + client = ec2Api.getAMIApi().get(); + if (ebsTemplate != null) { + Template template = view.getComputeService().templateBuilder().from(ebsTemplate).build(); + regionId = template.getLocation().getId(); + imageId = template.getImage().getProviderId(); + for (Image image : client.describeImagesInRegionWithFilter(regionId, + ImmutableMultimap.<String, String>builder() + .put("name", ebsBackedImageName).build())) { + if (ebsBackedImageName.equals(image.getName())) + client.deregisterImageInRegion(regionId, image.getId()); + } + } + } + + public void testDescribeImageNotExists() { + assertEquals(client.describeImagesInRegion(null, imageIds("ami-cdf819a3")).size(), 0); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testDescribeImageBadId() { + client.describeImagesInRegion(null, imageIds("asdaasdsa")); + } + + public void testDescribeImages() { + // Just run in the first region - no need to take the time on all of them. + String region = getFirst(ec2Api.getConfiguredRegions(), null); + assertNotNull(region, "region should not be null"); + Set<? extends Image> allResults = client.describeImagesInRegion(region); + assertNotNull(allResults); + assertTrue(allResults.size() >= 2); + Iterator<? extends Image> iterator = allResults.iterator(); + String id1 = iterator.next().getId(); + String id2 = iterator.next().getId(); + Set<? extends Image> twoResults = client.describeImagesInRegion(region, imageIds(id1, id2)); + assertNotNull(twoResults); + assertEquals(twoResults.size(), 2); + iterator = twoResults.iterator(); + assertEquals(iterator.next().getId(), id1); + assertEquals(iterator.next().getId(), id2); + } + + @Test + public void testDescribeImagesWithFilter() { + // Just run in the first region - no need to take the time on all of them. + String region = getFirst(ec2Api.getConfiguredRegions(), null); + assertNotNull(region, "region should not be null"); + Set<? extends Image> allResults = client.describeImagesInRegion(region); + assertNotNull(allResults); + assertTrue(allResults.size() >= 2); + String id1 = allResults.iterator().next().getId(); + Set<? extends Image> filterResult = client.describeImagesInRegionWithFilter(region, + ImmutableMultimap.<String, String>builder() + .put("image-id", id1) + .build()); + assertNotNull(filterResult); + assertEquals(filterResult.size(), 1); + assertEquals(filterResult.iterator().next().getId(), id1); + } + + @Test(expectedExceptions = AWSResponseException.class) + public void testDescribeImagesWithInvalidFilter() { + // Just run in the first region - no need to take the time on all of them. + String region = getFirst(ec2Api.getConfiguredRegions(), null); + assertNotNull(region, "region should not be null"); + + Set<? extends Image> allResults = client.describeImagesInRegion(region); + assertNotNull(allResults); + assertTrue(allResults.size() >= 2); + String id1 = allResults.iterator().next().getId(); + Set<? extends Image> filterResult = client.describeImagesInRegionWithFilter(region, + ImmutableMultimap.<String, String>builder() + .put("invalid-filter-id", id1) + .build()); + assertNotNull(filterResult); + assertEquals(filterResult.size(), 1); + assertEquals(filterResult.iterator().next().getId(), id1); + } + + @Test + public void testCreateAndListEBSBackedImage() throws Exception { + Snapshot snapshot = createSnapshot(); + + // List of images before... + int sizeBefore = client.describeImagesInRegionWithFilter(regionId, + ImmutableMultimap.<String, String>builder() + .put("name", ebsBackedImageName).build()).size(); + + // Register a new image... + ebsBackedImageId = client.registerUnixImageBackedByEbsInRegion(regionId, ebsBackedImageName, snapshot.getId(), + newBlockDeviceOption()); + imagesToDeregister.add(ebsBackedImageId); + final Image ebsBackedImage = getOnlyElement(client.describeImagesInRegion(regionId, imageIds(ebsBackedImageId))); + assertEquals(ebsBackedImage.getName(), ebsBackedImageName); + assertEquals(ebsBackedImage.getImageType(), ImageType.MACHINE); + assertEquals(ebsBackedImage.getRootDeviceType(), RootDeviceType.EBS); + assertEquals(ebsBackedImage.getRootDeviceName(), "/dev/sda1"); + assertEquals(ebsBackedImage.getDescription(), "adrian"); + assertEquals( + ebsBackedImage.getEbsBlockDevices().entrySet(), + ImmutableMap.of("/dev/sda1", new Image.EbsBlockDevice(snapshot.getId(), snapshot.getVolumeSize(), true, null, null, false), + "/dev/sda2", newBlockDeviceInfo()).entrySet()); + + 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.<String, String>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. + protected Snapshot createSnapshot() throws RunNodesException { + + String instanceId = null; + try { + RunningInstance instance = getOnlyElement(concat(ec2Api.getInstanceApi().get().runInstancesInRegion( + regionId, null, imageId, 1, 1))); + instanceId = instance.getId(); + + assertTrue(runningTester.apply(instance), instanceId + "didn't achieve the state running!"); + + instance = getOnlyElement(concat(ec2Api.getInstanceApi().get().describeInstancesInRegion(regionId, + instanceId))); + 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<Snapshot> 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); + } + } + + @Test(dependsOnMethods = "testCreateAndListEBSBackedImage") + public void testGetLaunchPermissionForImage() { + client.getLaunchPermissionForImageInRegion(regionId, ebsBackedImageId); + } + + @Override + @AfterClass(groups = { "integration", "live" }) + protected void tearDownContext() { + for (String imageId : imagesToDeregister) + client.deregisterImageInRegion(regionId, imageId); + for (String snapshotId : snapshotsToDelete) + ec2Api.getElasticBlockStoreApi().get().deleteSnapshotInRegion(regionId, snapshotId); + super.tearDownContext(); + } + +}
