blob: 7f8d32014a42b02c0b95ae74f1cf428897d25132 [file] [log] [blame]
/*
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.nodepool;
import static com.google.common.collect.Iterables.getOnlyElement;
import static java.lang.String.format;
import static java.util.logging.Logger.getAnonymousLogger;
import static org.jclouds.compute.RunScriptData.JBOSS_HOME;
import static org.jclouds.compute.RunScriptData.installAdminUserJBossAndOpenPorts;
import static org.jclouds.compute.RunScriptData.startJBoss;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_PORT_OPEN;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE;
import static org.jclouds.compute.options.RunScriptOptions.Builder.nameTask;
import static org.jclouds.compute.options.TemplateOptions.Builder.inboundPorts;
import static org.jclouds.compute.options.TemplateOptions.Builder.runAsRoot;
import static org.jclouds.nodepool.config.NodePoolProperties.BASEDIR;
import static org.jclouds.nodepool.config.NodePoolProperties.MAX_SIZE;
import static org.jclouds.nodepool.config.NodePoolProperties.MIN_SIZE;
import static org.jclouds.nodepool.config.NodePoolProperties.POOL_ADMIN_ACCESS;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.RunScriptData;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.internal.BaseComputeServiceLiveTest;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.logging.config.LoggingModule;
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.jclouds.util.Strings2;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
import com.google.common.base.Stopwatch;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.common.io.Closeables;
import com.google.inject.Module;
public class NodePoolComputeServiceLiveTest extends BaseComputeServiceLiveTest {
private final String basedir = "target/" + this.getClass().getSimpleName().toLowerCase();
public NodePoolComputeServiceLiveTest() {
provider = "nodepool";
}
@Override
protected Properties setupProperties() {
Properties contextProperties = super.setupProperties();
contextProperties.setProperty(BASEDIR, basedir);
contextProperties.setProperty("nodepool.identity", "pooluser");
contextProperties.setProperty(POOL_ADMIN_ACCESS, "adminUsername=pooluser,adminPassword=poolpassword");
contextProperties.setProperty(TIMEOUT_SCRIPT_COMPLETE, (1200 * 1000) + "");
contextProperties.setProperty(TIMEOUT_PORT_OPEN, (1200 * 1000) + "");
contextProperties.setProperty(BASEDIR, basedir);
contextProperties.setProperty(POOL_ADMIN_ACCESS, "adminUsername=pooluser,adminPassword=poolpassword");
contextProperties.setProperty(MAX_SIZE, 2 + "");
contextProperties.setProperty(MIN_SIZE, 1 + "");
return contextProperties;
}
@AfterClass(groups = { "integration", "live" })
@Override
protected void tearDownContext() {
Closeables.closeQuietly(context);
}
@Override
protected Module getSshModule() {
return new SshjSshClientModule();
}
@Override
protected LoggingModule getLoggingModule() {
return new SLF4JLoggingModule();
}
@Override
@Test(enabled = true, groups = "live")
public void testCreateAndRunAService() throws Exception {
final String configuration = Strings2.toStringAndClose(RunScriptData.class
.getResourceAsStream("/standalone-basic.xml"));
ImmutableMap<String, String> userMetadata = ImmutableMap.<String, String> of("Name", group);
ImmutableSet<String> tags = ImmutableSet.of(group);
Stopwatch watch = new Stopwatch().start();
NodeMetadata node = getOnlyElement(client.createNodesInGroup(group, 1, inboundPorts(22, 8080)
.blockOnPort(22, 300).userMetadata(userMetadata).tags(tags)));
long createSeconds = watch.elapsedTime(TimeUnit.SECONDS);
final String nodeId = node.getId();
checkUserMetadataInNodeEquals(node, userMetadata);
checkTagsInNodeEquals(node, tags);
getAnonymousLogger().info(
format("<< available node(%s) os(%s) in %ss", node.getId(), node.getOperatingSystem(), createSeconds));
watch.reset().start();
// note this is a dependency on the template resolution so we have the
// right process per
// operating system. moreover, we wish this to run as root, so that it
// can change ip
// tables rules and setup our admin user
client.runScriptOnNode(nodeId, installAdminUserJBossAndOpenPorts(node.getOperatingSystem()),
nameTask("configure-jboss"));
long configureSeconds = watch.elapsedTime(TimeUnit.SECONDS);
getAnonymousLogger()
.info(format("<< configured node(%s) with %s and JBoss %s in %ss",
nodeId,
exec(nodeId, "java -fullversion"),
// version of the jboss jar
exec(nodeId,
format("ls %s/bundles/org/jboss/as/osgi/configadmin/main|sed -e 's/.*-//g' -e 's/.jar//g'",
JBOSS_HOME)), configureSeconds));
trackAvailabilityOfProcessOnNode(view.utils().userExecutor().submit(new Callable<ExecResponse>() {
@Override
public ExecResponse call() {
return client.runScriptOnNode(nodeId, startJBoss(configuration), runAsRoot(false).blockOnComplete(false)
.nameTask("jboss"));
}
@Override
public String toString() {
return "initial start of jboss";
}
}), "jboss", node, JBOSS_PATTERN);
client.runScriptOnNode(nodeId, "/tmp/init-jboss stop", runAsRoot(false).wrapInInitScript(false));
trackAvailabilityOfProcessOnNode(view.utils().userExecutor().submit(new Callable<ExecResponse>() {
@Override
public ExecResponse call() {
return client.runScriptOnNode(nodeId, "/tmp/init-jboss start", runAsRoot(false).wrapInInitScript(false));
}
@Override
public String toString() {
return "warm start of jboss";
}
}), "jboss", node, JBOSS_PATTERN);
}
@Test(enabled = true, groups = "live", dependsOnMethods = "testCreateAndRunAService")
public void testRebuildPoolStateFromStore() {
tearDownContext();
setupContext();
assertSame(client.listNodes().size(), 1);
assertEquals(((NodeMetadata) Iterables.get(client.listNodes(), 0)).getGroup(), this.group);
}
@Test(enabled = true, groups = "live", dependsOnMethods = "testRebuildPoolStateFromStore")
public void testIncreasePoolAllowed() throws RunNodesException {
client.createNodesInGroup(this.group, 1);
assertSame(client.listNodes().size(), 2);
}
@Test(enabled = true, groups = "live", dependsOnMethods = "testIncreasePoolAllowed")
public void testIncreasePoolNotAllowed() throws RunNodesException {
boolean caughtException = false;
try {
client.createNodesInGroup(this.group, 1);
} catch (Exception e) {
caughtException = true;
}
assertTrue(caughtException, "expected an exception to be thrown");
}
@Test(enabled = true, groups = "live", dependsOnMethods = "testIncreasePoolNotAllowed")
public void testGetBackendComputeServiceContext() {
NodePoolComputeServiceContext ctx = context.utils().injector().getInstance(NodePoolComputeServiceContext.class);
assertNotNull(ctx.getBackendContext());
assertSame(
Sets.filter(ctx.getBackendContext().getComputeService().listNodesDetailsMatching(NodePredicates.all()),
NodePredicates.inGroup(ctx.getPoolGroupName())).size(), 2);
}
@Test(enabled = true, groups = "live", dependsOnMethods = "testGetBackendComputeServiceContext")
public void testDestroyPoolNodes() {
client.destroyNodesMatching(NodePredicates.inGroup(this.group));
// after we destroy all nodes we should still have minsize nodes in the pool
NodePoolComputeServiceContext ctx = context.utils().injector().getInstance(NodePoolComputeServiceContext.class);
assertSame(ctx.getPoolStats().currentSize(), 1);
}
@Test(enabled = true, groups = "live", dependsOnMethods = "testDestroyPoolNodes")
public void testDestroyPool() {
// TODO get the ctx without the injector
NodePoolComputeServiceContext ctx = context.utils().injector().getInstance(NodePoolComputeServiceContext.class);
ctx.destroyPool();
assertSame(
Sets.filter(ctx.getBackendContext().getComputeService().listNodesDetailsMatching(NodePredicates.all()),
NodePredicates.inGroup(ctx.getPoolGroupName())).size(), 0);
}
@Override
@Test(enabled = false)
public void testAScriptExecutionAfterBootWithBasicTemplate() throws Exception {
}
@Override
@Test(enabled = false)
public void testCompareSizes() throws Exception {
}
@Override
@Test(enabled = false)
public void testConcurrentUseOfComputeServiceToCreateNodes() throws Exception {
}
@Override
@Test(enabled = false, expectedExceptions = AuthorizationException.class)
public void testCorrectAuthException() throws Exception {
}
@Override
@Test(enabled = false, expectedExceptions = NoSuchElementException.class)
public void testCorrectExceptionRunningNodesNotFound() throws Exception {
}
@Override
@Test(enabled = false, dependsOnMethods = "testCreateTwoNodesWithRunScript")
public void testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired() throws Exception {
}
@Override
@Test(enabled = false, dependsOnMethods = "testConcurrentUseOfComputeServiceToCreateNodes")
public void testCreateTwoNodesWithRunScript() throws Exception {
}
@Override
@Test(enabled = false, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
public void testCredentialsCache() throws Exception {
}
@Override
@Test(enabled = false, dependsOnMethods = { "testListNodes", "testGetNodesWithDetails" })
public void testDestroyNodes() {
}
@Override
@Test(enabled = false, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
public void testGet() throws Exception {
}
@Override
@Test(enabled = false, groups = { "integration", "live" })
public void testGetAssignableLocations() throws Exception {
}
@Override
@Test(enabled = false, dependsOnMethods = "testSuspendResume")
public void testGetNodesWithDetails() throws Exception {
}
@Override
@Test(enabled = false)
public void testImageById() {
}
@Override
@Test(enabled = false)
public void testImagesCache() throws Exception {
}
@Override
@Test(enabled = false)
public void testListImages() throws Exception {
}
@Override
@Test(enabled = false, dependsOnMethods = "testSuspendResume")
public void testListNodes() throws Exception {
}
@Override
@Test(enabled = false)
public void testListSizes() throws Exception {
}
@Override
@Test(enabled = false)
public void testOptionToNotBlock() throws Exception {
}
@Override
@Test(enabled = false, dependsOnMethods = "testGet")
public void testReboot() throws Exception {
}
@Override
@Test(enabled = false, dependsOnMethods = "testReboot")
public void testSuspendResume() throws Exception {
}
@Override
@Test(enabled = false, dependsOnMethods = "testImagesCache")
public void testTemplateMatch() throws Exception {
}
}