Issue 112: added better testing for cloud compatibility

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2290 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-11-15 01:48:27 +00:00
parent edf82a7047
commit 9a1abce72f
24 changed files with 566 additions and 79 deletions

View File

@ -0,0 +1,75 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.predicates;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import org.jclouds.logging.Logger;
import org.joda.time.DateTime;
import com.google.common.base.Predicate;
/**
*
* Retries a condition until it is met or a timeout occurs.
*
* @author Adrian Cole
*/
public class RetryablePredicate<T> implements Predicate<T> {
private final int maxWait;
private final int checkInterval;
private final Predicate<T> predicate;
@Resource
protected Logger logger = Logger.NULL;
public RetryablePredicate(Predicate<T> predicate, long maxWait, long checkInterval, TimeUnit unit) {
this.predicate = predicate;
this.maxWait = (int) unit.toMillis(maxWait);
this.checkInterval = (int) unit.toMillis(checkInterval);
}
@Override
public boolean apply(T input) {
try {
for (DateTime end = new DateTime().plusMillis(maxWait); before(end); Thread
.sleep(checkInterval)) {
if (predicate.apply(input)) {
return true;
} else if (!before(end)){
return false;
}
}
} catch (InterruptedException e) {
logger.warn(e, "predicate %s on %s interrupted, returning false", input, predicate);
}
return false;
}
boolean before(DateTime end){
return new DateTime().compareTo(end) < 1;
}
}

View File

@ -0,0 +1,79 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.predicates;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
/**
*
* Tests to see if a socket is open.
*
* @author Adrian Cole
*/
@Singleton
public class SocketOpen implements Predicate<InetSocketAddress> {
@Resource
protected Logger logger = Logger.NULL;
@Inject(optional = true)
@Named("org.jclouds.socket_timeout")
private int timeout = 2000;
@Override
public boolean apply(InetSocketAddress socketAddress) {
Socket socket = null;
try {
logger.trace("testing socket %s", socketAddress);
socket = new Socket();
socket.setReuseAddress(false);
socket.setSoLinger(false, 1);
socket.setSoTimeout(timeout);
socket.connect(socketAddress, timeout);
} catch (IOException e) {
return false;
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException ioe) {
// no work to do
}
}
}
return true;
}
}

View File

@ -0,0 +1,68 @@
package org.jclouds.predicates;
import java.util.concurrent.TimeUnit;
import org.joda.time.DateTime;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
/**
*
* @author Adrian Cole
*
*/
@Test(groups = "unit", sequential = true, testName = "jclouds.RetryablePredicateTest")
public class RetryablePredicateTest {
@Test
void testAlwaysTrue() {
RetryablePredicate<String> predicate = new RetryablePredicate<String>(Predicates
.<String> alwaysTrue(), 3, 1, TimeUnit.SECONDS);
DateTime start = new DateTime();
predicate.apply("");
DateTime now = new DateTime();
assert now.compareTo(start.plusSeconds(1)) < 0 : String.format("%s should be less than %s",
now, start.plusSeconds(1)); }
@Test
void testAlwaysFalseMillis() {
RetryablePredicate<String> predicate = new RetryablePredicate<String>(Predicates
.<String> alwaysFalse(), 3, 1, TimeUnit.SECONDS);
DateTime start = new DateTime();
predicate.apply("");
DateTime now = new DateTime();
assert now.compareTo(start.plusSeconds(3)) > 0 : String.format("%s should be less than %s",
start.plusSeconds(3), now);
assert now.compareTo(start.plusSeconds(6)) <= 0 : String.format(
"%s should be greater than %s", start.plusSeconds(6), now);
}
private static class SecondTimeTrue implements Predicate<String> {
private int count = 0;
@Override
public boolean apply(String input) {
return count++ == 1;
}
}
@Test
void testSecondTimeTrue() {
RetryablePredicate<String> predicate = new RetryablePredicate<String>(new SecondTimeTrue(),
3, 1, TimeUnit.SECONDS);
DateTime start = new DateTime();
predicate.apply("");
DateTime now = new DateTime();
assert now.compareTo(start.plusSeconds(1)) > 0 : String.format("%s should be greater than %s",
now,start.plusSeconds(1));
assert now.compareTo(start.plusSeconds(2)) <= 0 : String.format(
"%s should be greater than %s", start.plusSeconds(2), now);
}
}

View File

@ -26,6 +26,7 @@ package org.jclouds.vcloud;
import static org.jclouds.vcloud.VCloudMediaType.CATALOG_XML;
import static org.jclouds.vcloud.VCloudMediaType.TASKSLIST_XML;
import static org.jclouds.vcloud.VCloudMediaType.TASK_XML;
import static org.jclouds.vcloud.VCloudMediaType.VAPP_XML;
import static org.jclouds.vcloud.VCloudMediaType.VDC_XML;
import java.net.URI;
@ -157,4 +158,9 @@ public interface VCloudClient {
@Path("/action/cancel")
Future<Void> cancelTask(@Endpoint URI task);
@GET
@Consumes(VAPP_XML)
@Endpoint(org.jclouds.vcloud.endpoints.VCloud.class)
@Path("/vapp/{vAppId}")
String getVApp(@PathParam("vAppId") String appId);
}

View File

@ -23,6 +23,8 @@
*/
package org.jclouds.vcloud;
import java.util.concurrent.Future;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@ -52,5 +54,5 @@ public interface VCloudDiscovery {
@Endpoint(Org.class)
@Consumes(VCloudMediaType.ORG_XML)
@XMLResponseParser(OrgHandler.class)
Organization getOrganization();
Future<? extends Organization> getOrganization();
}

View File

@ -24,6 +24,7 @@
package org.jclouds.vcloud;
import java.util.Map;
import java.util.concurrent.Future;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
@ -66,5 +67,5 @@ public interface VCloudLogin {
@ResponseParser(ParseLoginResponseFromHeaders.class)
@Path("/login")
@Consumes(MediaType.APPLICATION_XML)
VCloudSession login();
Future<VCloudSession> login();
}

View File

@ -39,6 +39,7 @@ import org.jclouds.concurrent.ExpirableSupplier;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.RestClientFactory;
import org.jclouds.util.Utils;
import org.jclouds.vcloud.VCloudDiscovery;
import org.jclouds.vcloud.VCloudLogin;
import org.jclouds.vcloud.VCloudToken;
@ -85,7 +86,12 @@ public class VCloudDiscoveryRestClientModule extends AbstractModule {
@Named(PROPERTY_VCLOUD_SESSIONINTERVAL) long seconds, final VCloudLogin login) {
return new ExpirableSupplier<VCloudSession>(new Supplier<VCloudSession>() {
public VCloudSession get() {
return login.login();
try {
return login.login().get(45, TimeUnit.SECONDS);
} catch (Exception e) {
Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new RuntimeException("Error logging in", e);
}
}
}, seconds, TimeUnit.SECONDS);
}

View File

@ -68,29 +68,30 @@ public class VCloudRestClientModule extends AbstractModule {
@Provides
@Catalog
@Singleton
protected URI provideCatalog(VCloudDiscovery discovery) {
return discovery.getOrganization().getCatalog().getLocation();
protected URI provideCatalog(VCloudDiscovery discovery) throws InterruptedException, ExecutionException, TimeoutException {
return discovery.getOrganization().get(45, TimeUnit.SECONDS).getCatalog().getLocation();
}
@Provides
@CatalogItemRoot
@Singleton
String provideCatalogItemRoot(@VCloud URI vcloudUri) {
return vcloudUri.toASCIIString()+"/catalogItem";
return vcloudUri.toASCIIString() + "/catalogItem";
}
@Provides
@VAppRoot
@Singleton
String provideVAppRoot(@VCloud URI vcloudUri) {
return vcloudUri.toASCIIString()+"/vapp";
return vcloudUri.toASCIIString() + "/vapp";
}
@Provides
@VDC
@Singleton
protected URI provideDefaultVDC(VCloudDiscovery discovery) {
return discovery.getOrganization().getVDCs().values().iterator().next().getLocation();
protected URI provideDefaultVDC(VCloudDiscovery discovery) throws InterruptedException, ExecutionException, TimeoutException {
return discovery.getOrganization().get(45, TimeUnit.SECONDS).getVDCs().values().iterator()
.next().getLocation();
}
@Provides
@ -105,7 +106,7 @@ public class VCloudRestClientModule extends AbstractModule {
@Provides
@TasksList
@Singleton
protected URI provideDefaultTasksList(VCloudDiscovery discovery) {
return discovery.getOrganization().getTasksLists().values().iterator().next().getLocation();
protected URI provideDefaultTasksList(VCloudDiscovery discovery) throws InterruptedException, ExecutionException, TimeoutException {
return discovery.getOrganization().get(45, TimeUnit.SECONDS).getTasksLists().values().iterator().next().getLocation();
}
}

View File

@ -18,12 +18,11 @@ public class CatalogIdToUri implements Function<Object, String> {
@Inject
@CatalogItemRoot
private String catalogItemRoot;
@Override
public String apply(Object from) {
checkArgument(checkNotNull(from, "from") instanceof Integer,
"this binder is only valid for Integers!");
return String.format("%s/%d",catalogItemRoot,from);
return String.format("%s/%d", catalogItemRoot, from);
}
}

View File

@ -18,12 +18,11 @@ public class VAppIdToUri implements Function<Object, String> {
@Inject
@VAppRoot
private String vAppRoot;
@Override
public String apply(Object from) {
checkArgument(checkNotNull(from, "from") instanceof Integer,
"this binder is only valid for Integers!");
return String.format("%s/%d",vAppRoot,from);
return String.format("%s/%d", vAppRoot, from);
}
}

View File

@ -89,6 +89,13 @@ public class VCloudClientLiveTest {
}
}
@Test(enabled = false)
public void testGetVApp() throws Exception {
String response = connection.getVApp("188849-2");
assertNotNull(response);
System.out.println(response);
}
@BeforeGroups(groups = { "live" })
public void setupClient() {
String endpoint = checkNotNull(System.getProperty("jclouds.test.endpoint"),

View File

@ -33,6 +33,7 @@ import static org.testng.Assert.assertNotNull;
import java.net.URI;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import javax.inject.Named;
import javax.inject.Singleton;
@ -89,7 +90,7 @@ public class VCloudDiscoveryLiveTest {
@Test
public void testOrganization() throws Exception {
Organization response = context.getApi().getOrganization();
Organization response = context.getApi().getOrganization().get(45, TimeUnit.SECONDS);
assertNotNull(response);
assertNotNull(account);
assertNotNull(response.getCatalog());

View File

@ -32,6 +32,7 @@ import static org.testng.Assert.assertNotNull;
import java.net.URI;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import javax.inject.Named;
import javax.inject.Singleton;
@ -91,7 +92,7 @@ public class VCloudLoginLiveTest {
public void testLogin() throws Exception {
VCloudLogin authentication = context.getApi();
for (int i = 0; i < 5; i++) {
VCloudSession response = authentication.login();
VCloudSession response = authentication.login().get(45, TimeUnit.SECONDS);
assertNotNull(response);
assertNotNull(response.getVCloudToken());
assertNotNull(response.getOrgs());

View File

@ -30,6 +30,10 @@ import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_USER;
import static org.testng.Assert.assertEquals;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import org.jclouds.http.HttpRetryHandler;
@ -70,6 +74,25 @@ public class VCloudDiscoveryRestClientModuleTest {
});
}
public static abstract class FutureBase<V> implements Future<V> {
public boolean cancel(boolean b) {
return false;
}
public boolean isCancelled() {
return false;
}
public boolean isDone() {
return true;
}
public V get(long l, TimeUnit timeUnit) throws InterruptedException, ExecutionException,
TimeoutException {
return get();
}
}
@Test
void testUpdatesOnlyOncePerSecond() throws NoSuchMethodException, InterruptedException {
VCloudDiscoveryRestClientModule module = new VCloudDiscoveryRestClientModule();
@ -77,18 +100,24 @@ public class VCloudDiscoveryRestClientModuleTest {
private final AtomicInteger token = new AtomicInteger();
public VCloudSession login() {
return new VCloudSession() {
public Future<VCloudSession> login() {
return new FutureBase<VCloudSession>() {
@Override
public VCloudSession get() throws InterruptedException, ExecutionException {
return new VCloudSession() {
public Map<String, NamedLink> getOrgs() {
return null;
public Map<String, NamedLink> getOrgs() {
return null;
}
public String getVCloudToken() {
return token.incrementAndGet() + "";
}
};
}
public String getVCloudToken() {
return token.incrementAndGet() + "";
}
};
}
};

View File

@ -0,0 +1,63 @@
package org.jclouds.vcloud.predicates;
import java.net.URI;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.logging.Logger;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.TaskStatus;
import com.google.common.base.Predicate;
/**
*
* Tests to see if a task succeeds.
*
* @author Adrian Cole
*/
@Singleton
public class TaskSuccess implements Predicate<URI> {
private final VCloudClient client;
@Inject(optional = true)
@Named("org.jclouds.vcloud.timeout")
private long taskTimeout = 30000;
@Resource
protected Logger logger = Logger.NULL;
@Inject
public TaskSuccess(VCloudClient client) {
this.client = client;
}
public boolean apply(URI taskUri) {
logger.trace("looking for status on task %s", taskUri);
Task task;
try {
task = client.getTask(taskUri).get(taskTimeout, TimeUnit.MILLISECONDS);
logger.trace("%s: looking for status %s: currently: %s", task, TaskStatus.SUCCESS, task
.getStatus());
return task.getStatus() == TaskStatus.SUCCESS;
} catch (InterruptedException e) {
logger.warn(e, "%s interrupted, returning false", taskUri);
} catch (ExecutionException e) {
logger.warn(e, "%s exception, returning false", taskUri);
} catch (TimeoutException e) {
logger.warn(e, "%s timeout, returning false", taskUri);
}
return false;
}
}

View File

@ -98,12 +98,25 @@
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="org.jclouds.predicates.SocketOpen">
<priority value="TRACE" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="org.jclouds.vcloud.predicates.TaskSuccess">
<priority value="TRACE" />
<appender-ref ref="ASYNCWIRE" />
</category>
<!--
<category name="jclouds.http.wire">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<!-- ======================= -->
--><!-- ======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->

View File

@ -29,6 +29,10 @@ public class BindInstantiateVAppTemplateParamsToXmlEntity implements MapBinder {
public void bindToRequest(HttpRequest request, Map<String, String> postParams) {
String name = checkNotNull(postParams.get("name"), "name parameter not present");
String password = checkNotNull(postParams.get("password"), "password parameter not present");
String row = checkNotNull(postParams.get("row"), "row parameter not present");
String group = checkNotNull(postParams.get("group"), "group parameter not present");
String template = checkNotNull(postParams.get("template"), "template parameter not present");
String count = checkNotNull(postParams.get("count"), "count parameter not present");
String megabytes = checkNotNull(postParams.get("megabytes"),
@ -36,6 +40,9 @@ public class BindInstantiateVAppTemplateParamsToXmlEntity implements MapBinder {
String network = checkNotNull(postParams.get("network"), "network parameter not present");
String entity = xmlTemplate.replaceAll("\\{name\\}", name);
entity = entity.replaceAll("\\{password\\}", password);
entity = entity.replaceAll("\\{row\\}", row);
entity = entity.replaceAll("\\{group\\}", group);
entity = entity.replaceAll("\\{template\\}", template);
entity = entity.replaceAll("\\{count\\}", count);
entity = entity.replaceAll("\\{megabytes\\}", megabytes);

View File

@ -24,6 +24,13 @@ public class InstantiateVAppTemplateOptions extends BindInstantiateVAppTemplateP
@Network
private URI defaultNetwork;
@VisibleForTesting
String password = "password";
@VisibleForTesting
String group = "default";
@VisibleForTesting
String row = "default";
@VisibleForTesting
String cpuCount = "1";
@VisibleForTesting
@ -35,6 +42,9 @@ public class InstantiateVAppTemplateOptions extends BindInstantiateVAppTemplateP
Map<String, String> copy = Maps.newHashMap();
copy.putAll(postParams);
copy.put("count", cpuCount);
copy.put("password", password);
copy.put("group", group);
copy.put("row", row);
copy.put("megabytes", megabytes);
copy.put("network", network != null ? network : defaultNetwork.toASCIIString());
super.bindToRequest(request, copy);
@ -57,6 +67,21 @@ public class InstantiateVAppTemplateOptions extends BindInstantiateVAppTemplateP
return this;
}
public InstantiateVAppTemplateOptions withPassword(String password) {
this.password = password;
return this;
}
public InstantiateVAppTemplateOptions inGroup(String group) {
this.group = group;
return this;
}
public InstantiateVAppTemplateOptions inRow(String row) {
this.row = row;
return this;
}
public static class Builder {
/**
@ -82,5 +107,30 @@ public class InstantiateVAppTemplateOptions extends BindInstantiateVAppTemplateP
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
return options.inNetwork(networkLocation);
}
/**
* @see InstantiateVAppTemplateOptions#withPassword(String)
*/
public static InstantiateVAppTemplateOptions withPassword(String password) {
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
return options.withPassword(password);
}
/**
* @see InstantiateVAppTemplateOptions#inGroup(String)
*/
public static InstantiateVAppTemplateOptions inGroup(String group) {
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
return options.inGroup(group);
}
/**
* @see InstantiateVAppTemplateOptions#inRow(String)
*/
public static InstantiateVAppTemplateOptions inRow(String row) {
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
return options.inRow(row);
}
}
}

View File

@ -0,0 +1,4 @@
<InternetService xmlns="urn:tmrk:vCloudExpress-1.0"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Id>{id}</Id>{options}
</InternetService>

View File

@ -5,11 +5,11 @@
<ProductSection xmlns:q1="http://www.vmware.com/vcloud/v1"
xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1">
<Property xmlns="http://schemas.dmtf.org/ovf/envelope/1"
ovf:key="password" ovf:value="secretPassword" />
ovf:key="password" ovf:value="{password}" />
<Property xmlns="http://schemas.dmtf.org/ovf/envelope/1"
ovf:key="row" ovf:value="Row1" />
ovf:key="row" ovf:value="{row}" />
<Property xmlns="http://schemas.dmtf.org/ovf/envelope/1"
ovf:key="group" ovf:value="Group1" />
ovf:key="group" ovf:value="{group}" />
</ProductSection>
<VirtualHardwareSection xmlns:q1="http://www.vmware.com/vcloud/v1">
<Item xmlns="http://schemas.dmtf.org/ovf/envelope/1">

View File

@ -36,10 +36,10 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.http.HttpResponseException;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshClient.Factory;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
@ -48,6 +48,7 @@ import org.jclouds.vcloud.VCloudClientLiveTest;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.TaskStatus;
import org.jclouds.vcloud.domain.VAppStatus;
import org.jclouds.vcloud.predicates.TaskSuccess;
import org.jclouds.vcloud.terremark.domain.InternetService;
import org.jclouds.vcloud.terremark.domain.Node;
import org.jclouds.vcloud.terremark.domain.ResourceType;
@ -58,7 +59,6 @@ import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.Iterables;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
@ -77,6 +77,10 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest {
private Node node;
private VApp vApp;
private RetryablePredicate<InetSocketAddress> socketTester;
private RetryablePredicate<URI> successTester;
public static final String PREFIX = System.getProperty("user.name") + "-terremark";
@Test
@ -95,12 +99,16 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest {
String serverName = "adriantest";
int processorCount = 1;
int memory = 512;
long hardDisk = 4194304;
String catalogOs = "Ubuntu JeOS 9.04 (32-bit)";
String expectedOs = "Ubuntu Linux (32-bit)";
// long hardDisk = 4194304;
// String catalogOs = "Ubuntu JeOS 9.04 (32-bit)";
// String expectedOs = "Ubuntu Linux (32-bit)";
long hardDisk = 4194304 / 4 * 10;
String catalogOs = "CentOS 5.3 (32-bit)";
String expectedOs = "Red Hat Enterprise Linux 5 (32-bit)";
int templateId = tmClient.getCatalog().get(45, TimeUnit.SECONDS).get(catalogOs).getId();
System.out.printf("%d: instantiating vApp%n", System.currentTimeMillis());
vApp = tmClient.instantiateVAppTemplate(serverName, templateId).get(45, TimeUnit.SECONDS);
assertEquals(vApp.getStatus(), VAppStatus.CREATING);
@ -127,13 +135,17 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest {
assertEquals(((HttpResponseException) e.getCause()).getResponse().getStatusCode(), 501);
}
deployTask = blockUntilSuccess(deployTask);
assert successTester.apply(deployTask.getLocation());
System.out.printf("%d: done deploying vApp%n", System.currentTimeMillis());
vApp = tmClient.getVApp(vApp.getId()).get(45, TimeUnit.SECONDS);
verifyConfigurationOfVApp(vApp, serverName, expectedOs, processorCount, memory, hardDisk);
assertEquals(vApp.getStatus(), VAppStatus.OFF);
deployTask = blockUntilSuccess(tmClient.powerOnVApp(vApp.getId()).get(45, TimeUnit.SECONDS));
assert successTester.apply(tmClient.powerOnVApp(vApp.getId()).get(45, TimeUnit.SECONDS)
.getLocation());
System.out.printf("%d: done powering on vApp%n", System.currentTimeMillis());
vApp = tmClient.getVApp(vApp.getId()).get(45, TimeUnit.SECONDS);
assertEquals(vApp.getStatus(), VAppStatus.ON);
@ -151,13 +163,7 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest {
node = tmClient.addNode(is.getId(), vApp.getNetworkToAddresses().values().iterator().next(),
vApp.getName() + "-SSH", 22).get(45, TimeUnit.SECONDS);
publicIp = is.getPublicIpAddress().getAddress();
try {
doCheckPass(publicIp);
} catch (Exception e) {
// TODO - harden this up, when we stop hanging
System.err.printf("%s:22 -> %s:22%n%s%n", vApp.getNetworkToAddresses().values().iterator()
.next(), publicIp, e.getMessage());
}
doCheckPass(publicIp);
}
@Test(dependsOnMethods = "testPublicIp")
@ -178,15 +184,20 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest {
assertEquals(((HttpResponseException) e.getCause()).getResponse().getStatusCode(), 501);
}
blockUntilSuccess(tmClient.resetVApp(vApp.getId()).get(45, TimeUnit.SECONDS));
assert successTester.apply(tmClient.resetVApp(vApp.getId()).get(45, TimeUnit.SECONDS)
.getLocation());
vApp = tmClient.getVApp(vApp.getId()).get(45, TimeUnit.SECONDS);
assertEquals(vApp.getStatus(), VAppStatus.ON);
tmClient.shutdownVApp(vApp.getId()).get(45, TimeUnit.SECONDS);
vApp = tmClient.getVApp(vApp.getId()).get(45, TimeUnit.SECONDS);
assertEquals(vApp.getStatus(), VAppStatus.ON);
// TODO we need to determine whether shutdown is supported before invoking it.
// tmClient.shutdownVApp(vApp.getId()).get(45, TimeUnit.SECONDS);
// vApp = tmClient.getVApp(vApp.getId()).get(45, TimeUnit.SECONDS);
// assertEquals(vApp.getStatus(), VAppStatus.ON);
assert successTester.apply(tmClient.powerOffVApp(vApp.getId()).get(45, TimeUnit.SECONDS)
.getLocation());
blockUntilSuccess(tmClient.powerOffVApp(vApp.getId()).get(45, TimeUnit.SECONDS));
vApp = tmClient.getVApp(vApp.getId()).get(45, TimeUnit.SECONDS);
assertEquals(vApp.getStatus(), VAppStatus.OFF);
}
@ -208,18 +219,6 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest {
.get(ResourceType.VIRTUAL_DISK).getVirtualQuantity());
}
private Task blockUntilSuccess(Task task) throws InterruptedException, ExecutionException,
TimeoutException {
for (task = tmClient.getTask(task.getLocation()).get(30, TimeUnit.SECONDS); task.getStatus() != TaskStatus.SUCCESS; task = tmClient
.getTask(task.getLocation()).get(30, TimeUnit.SECONDS)) {
System.out.printf("%s blocking on status active: currently: %s%n", task.getOwner()
.getName(), task.getStatus());
Thread.sleep(5 * 1000);
}
System.out.printf("%s complete%n", task.getResult().getName());
return task;
}
private Task getLastTaskFor(URI owner) throws InterruptedException, ExecutionException,
TimeoutException {
return Iterables.getLast(tmClient.getDefaultTasksList().get(45, TimeUnit.SECONDS)
@ -227,11 +226,17 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest {
}
private void doCheckPass(InetAddress address) throws IOException {
System.out.printf("%s:%s%n", address, 22);
SshClient connection = sshFactory.create(new InetSocketAddress(address, 22), "vcloud",
"p4ssw0rd");
InetSocketAddress socket = new InetSocketAddress(address, 22);
System.out.printf("%d: %s awaiting ssh service to start%n", System.currentTimeMillis(),
socket);
assert socketTester.apply(socket);
System.out.printf("%d: %s ssh service started%n", System.currentTimeMillis(), socket);
SshClient connection = sshFactory.create(socket, "vcloud", "p4ssw0rd");
try {
connection.connect();
System.out.printf("%d: %s ssh connection made%n", System.currentTimeMillis(), socket);
InputStream etcPasswd = connection.get("/etc/passwd");
Utils.toStringAndClose(etcPasswd);
} finally {
@ -248,8 +253,10 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest {
tmClient.deleteInternetService(is.getId()).get(30, TimeUnit.SECONDS);
if (vApp != null) {
try {
blockUntilSuccess(tmClient.powerOffVApp(vApp.getId()).get(45, TimeUnit.SECONDS));
successTester.apply(tmClient.powerOffVApp(vApp.getId()).get(45, TimeUnit.SECONDS)
.getLocation());
} catch (Exception e) {
}
tmClient.deleteVApp(vApp.getId()).get(45, TimeUnit.SECONDS);
}
@ -260,13 +267,19 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest {
public void setupClient() {
account = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
connection = tmClient = new TerremarkVCloudContextBuilder(
new TerremarkVCloudPropertiesBuilder(account, key).build()).withModules(
new Log4JLoggingModule()).buildContext().getApi();
Injector injector = Guice.createInjector(new Log4JLoggingModule(), new JschSshClientModule(),
new ExecutorServiceModule(new WithinThreadExecutorService()));
sshFactory = injector.getInstance(SshClient.Factory.class);
Injector injector = new TerremarkVCloudContextBuilder(new TerremarkVCloudPropertiesBuilder(
account, key).build()).withModules(new Log4JLoggingModule(),
new JschSshClientModule()).buildInjector();
connection = tmClient = injector.getInstance(TerremarkVCloudClient.class);
sshFactory = injector.getInstance(SshClient.Factory.class);
socketTester = new RetryablePredicate<InetSocketAddress>(injector
.getInstance(SocketOpen.class), 130, 10, TimeUnit.SECONDS);// make it longer then
// default internet
// service timeout
successTester = new RetryablePredicate<URI>(injector.getInstance(TaskSuccess.class), 300, 10,
TimeUnit.SECONDS);
}
}

View File

@ -78,13 +78,16 @@ public class BindInstantiateVAppTemplateParamsToXmlEntityTest {
Map<String, String> map = Maps.newHashMap();
map.put("name", "name");
map.put("password", "password");
map.put("row", "row");
map.put("group", "group");
map.put("template", "http://catalogItem/3");
map.put("count", "1");
map.put("megabytes", "512");
map.put("network", "http://network");
binder.bindToRequest(request, map);
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE), "application/unknown");
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH), "2247");
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH), "2239");
assertEquals(request.getEntity(), expected);
}

View File

@ -1,8 +1,11 @@
package org.jclouds.vcloud.terremark.options;
import static org.jclouds.vcloud.terremark.options.InstantiateVAppTemplateOptions.Builder.cpuCount;
import static org.jclouds.vcloud.terremark.options.InstantiateVAppTemplateOptions.Builder.inGroup;
import static org.jclouds.vcloud.terremark.options.InstantiateVAppTemplateOptions.Builder.inNetwork;
import static org.jclouds.vcloud.terremark.options.InstantiateVAppTemplateOptions.Builder.inRow;
import static org.jclouds.vcloud.terremark.options.InstantiateVAppTemplateOptions.Builder.megabytes;
import static org.jclouds.vcloud.terremark.options.InstantiateVAppTemplateOptions.Builder.withPassword;
import static org.testng.Assert.assertEquals;
import java.net.URI;
@ -23,6 +26,63 @@ public class InstantiateVAppTemplateOptionsTest {
Injector injector = Guice.createInjector(new ParserModule());
@Test
public void testInGroupDefault() {
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
assertEquals(options.group, "default");
}
@Test
public void testInGroup() {
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
options.inGroup("group1");
assertEquals(options.group, "group1");
}
@Test
public void testInGroupStatic() {
InstantiateVAppTemplateOptions options = inGroup("group1");
assertEquals(options.group, "group1");
}
@Test
public void testInRowDefault() {
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
assertEquals(options.row, "default");
}
@Test
public void testInRow() {
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
options.inRow("row1");
assertEquals(options.row, "row1");
}
@Test
public void testInRowStatic() {
InstantiateVAppTemplateOptions options = inRow("row1");
assertEquals(options.row, "row1");
}
@Test
public void testWithPasswordDefault() {
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
assertEquals(options.password, "password");
}
@Test
public void testWithPassword() {
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
options.withPassword("password1");
assertEquals(options.password, "password1");
}
@Test
public void testWithPasswordStatic() {
InstantiateVAppTemplateOptions options = withPassword("password1");
assertEquals(options.password, "password1");
}
@Test
public void testInNetwork() {
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();

View File

@ -5,11 +5,11 @@
<ProductSection xmlns:q1="http://www.vmware.com/vcloud/v1"
xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1">
<Property xmlns="http://schemas.dmtf.org/ovf/envelope/1"
ovf:key="password" ovf:value="secretPassword" />
ovf:key="password" ovf:value="password" />
<Property xmlns="http://schemas.dmtf.org/ovf/envelope/1"
ovf:key="row" ovf:value="Row1" />
ovf:key="row" ovf:value="row" />
<Property xmlns="http://schemas.dmtf.org/ovf/envelope/1"
ovf:key="group" ovf:value="Group1" />
ovf:key="group" ovf:value="group" />
</ProductSection>
<VirtualHardwareSection xmlns:q1="http://www.vmware.com/vcloud/v1">
<Item xmlns="http://schemas.dmtf.org/ovf/envelope/1">