diff --git a/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java b/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java index 0c94f6374e..6fab8fc46e 100644 --- a/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java +++ b/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java @@ -138,6 +138,8 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes SshClient client3 = createMock(SshClient.class); SshClient client4 = createMock(SshClient.class); SshClient client5 = createMock(SshClient.class); + SshClient client6 = createMock(SshClient.class); + SshClient client7 = createMock(SshClient.class); expect( factory.create(HostAndPort.fromParts("144.175.1.1", 22), @@ -211,10 +213,20 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes factory.create(HostAndPort.fromParts("144.175.1.5", 22), LoginCredentials.builder().user("root").password("password5").build())).andReturn(client5) .times(2); + expect( + factory.create(HostAndPort.fromParts("144.175.1.6", 22), + LoginCredentials.builder().user("root").password("password6").build())).andReturn(client6) + .times(2); + expect( + factory.create(HostAndPort.fromParts("144.175.1.7", 22), + LoginCredentials.builder().user("root").password("password7").build())).andReturn(client7) + .times(2); runScriptAndInstallSsh(client3, "bootstrap", 3); runScriptAndInstallSsh(client4, "bootstrap", 4); runScriptAndInstallSsh(client5, "bootstrap", 5); + runScriptAndInstallSsh(client6, "bootstrap", 6); + runScriptAndInstallSsh(client7, "bootstrap", 7); expect( factory.create(eq(HostAndPort.fromParts("144.175.1.1", 22)), @@ -236,11 +248,21 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes factory.create(eq(HostAndPort.fromParts("144.175.1.5", 22)), eq(LoginCredentials.builder().user("defaultAdminUsername").privateKey(Pems.PRIVATE_PKCS1_MARKER).build()))) .andReturn(client5); + expect( + factory.create(eq(HostAndPort.fromParts("144.175.1.6", 22)), + eq(LoginCredentials.builder().user("defaultAdminUsername").privateKey(Pems.PRIVATE_PKCS1_MARKER).build()))) + .andReturn(client6); + expect( + factory.create(eq(HostAndPort.fromParts("144.175.1.7", 22)), + eq(LoginCredentials.builder().user("defaultAdminUsername").privateKey(Pems.PRIVATE_PKCS1_MARKER).build()))) + .andReturn(client7); helloAndJava(client2); helloAndJava(client3); helloAndJava(client4); helloAndJava(client5); + helloAndJava(client6); + helloAndJava(client7); replay(factory); replay(client1); @@ -251,6 +273,8 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes replay(client3); replay(client4); replay(client5); + replay(client6); + replay(client7); bind(SshClient.Factory.class).toInstance(factory); } @@ -472,6 +496,11 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes } @Test(enabled = true, dependsOnMethods = "testTemplateMatch") + public void testConcurrentUseOfComputeServiceToCreateNodes() throws Exception { + super.testConcurrentUseOfComputeServiceToCreateNodes(); + } + + @Test(enabled = true, dependsOnMethods = "testConcurrentUseOfComputeServiceToCreateNodes") public void testCreateTwoNodesWithRunScript() throws Exception { super.testCreateTwoNodesWithRunScript(); } diff --git a/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceLiveTest.java b/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceLiveTest.java index f5202b32f4..2ea50bd480 100644 --- a/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceLiveTest.java @@ -48,7 +48,9 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import java.io.IOException; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.NoSuchElementException; @@ -105,7 +107,10 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.net.HostAndPort; +import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; import com.google.inject.Module; /** @@ -323,7 +328,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte ComputeTestUtils.checkHttpGet(view.utils().http(), node, 8080); } - @Test(enabled = true, dependsOnMethods = "testCompareSizes") + @Test(enabled = true, dependsOnMethods = "testConcurrentUseOfComputeServiceToCreateNodes") public void testCreateTwoNodesWithRunScript() throws Exception { try { client.destroyNodesMatching(inGroup(group)); @@ -412,6 +417,39 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte this.nodes.add(node); } + @Test(enabled = true, dependsOnMethods = "testCompareSizes") + public void testConcurrentUseOfComputeServiceToCreateNodes() throws Exception { + final long timeoutMs = 20*60*1000; + List groups = new ArrayList(); + List> futures = new ArrayList>(); + ListeningExecutorService executor = MoreExecutors.listeningDecorator(context.utils().userExecutor()); + + try { + for (int i = 0; i < 2; i++) { + final int groupNum = i; + final String group = "groupconcurrent"+groupNum; + groups.add(group); + + ListenableFuture future = executor.submit(new Callable() { + public NodeMetadata call() throws Exception { + NodeMetadata node = getOnlyElement(client.createNodesInGroup(group, 1, + inboundPorts(22, 8080).blockOnPort(22, 300+groupNum))); + getAnonymousLogger().info("Started node "+node.getId()); + return node; + }}); + futures.add(future); + } + + ListenableFuture> compoundFuture = Futures.allAsList(futures); + compoundFuture.get(timeoutMs, TimeUnit.MILLISECONDS); + + } finally { + for (String group : groups) { + client.destroyNodesMatching(inGroup(group)); + } + } + } + @Test(enabled = true, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired") public void testCredentialsCache() throws Exception { initializeContext();