Merge branch 'master' of git://github.com/jclouds/jclouds

This commit is contained in:
vijaykiran 2011-10-31 12:24:26 +01:00
commit a99ce504f1
16 changed files with 389 additions and 30 deletions

View File

@ -62,6 +62,7 @@ import org.jclouds.io.payloads.PhantomPayload;
import org.jclouds.io.payloads.StringPayload; import org.jclouds.io.payloads.StringPayload;
import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.inject.CreationException; import com.google.inject.CreationException;
@ -83,7 +84,6 @@ public class FilesystemAsyncBlobStoreTest {
static { static {
System.setProperty(LOGGING_CONFIG_KEY, LOGGING_CONFIG_VALUE); System.setProperty(LOGGING_CONFIG_KEY, LOGGING_CONFIG_VALUE);
} }
private BlobStoreContext context = null; private BlobStoreContext context = null;
@ -119,6 +119,12 @@ public class FilesystemAsyncBlobStoreTest {
} }
} }
@DataProvider
public Object[][] ignoreOnWindows() {
return (TestUtils.isWindowsOs() ? TestUtils.NO_INVOCATIONS
: TestUtils.SINGLE_NO_ARG_INVOCATION);
}
/** /**
* Checks if context parameters are managed in the correct way * Checks if context parameters are managed in the correct way
*/ */
@ -399,6 +405,7 @@ public class FilesystemAsyncBlobStoreTest {
/** /**
* Test of removeBlob method, with only one blob with a complex path as key * Test of removeBlob method, with only one blob with a complex path as key
*/ */
@Test(dataProvider = "ignoreOnWindows", description = "see http://code.google.com/p/jclouds/issues/detail?id=737")
public void testRemoveBlob_ComplexBlobKey() throws IOException { public void testRemoveBlob_ComplexBlobKey() throws IOException {
final String BLOB_KEY = TestUtils.createRandomBlobKey("aa/bb/cc/dd/", null); final String BLOB_KEY = TestUtils.createRandomBlobKey("aa/bb/cc/dd/", null);
boolean result; boolean result;
@ -429,6 +436,7 @@ public class FilesystemAsyncBlobStoreTest {
* when first blob is removed, not all of its key's path is removed, because * when first blob is removed, not all of its key's path is removed, because
* it is shared with the second blob's key * it is shared with the second blob's key
*/ */
@Test(dataProvider = "ignoreOnWindows", description = "see http://code.google.com/p/jclouds/issues/detail?id=737")
public void testRemoveBlob_TwoComplexBlobKeys() throws IOException { public void testRemoveBlob_TwoComplexBlobKeys() throws IOException {
final String BLOB_KEY1 = TestUtils.createRandomBlobKey("aa/bb/cc/dd/", null); final String BLOB_KEY1 = TestUtils.createRandomBlobKey("aa/bb/cc/dd/", null);
final String BLOB_KEY2 = TestUtils.createRandomBlobKey("aa/bb/ee/ff/", null); final String BLOB_KEY2 = TestUtils.createRandomBlobKey("aa/bb/ee/ff/", null);
@ -702,6 +710,7 @@ public class FilesystemAsyncBlobStoreTest {
TestUtils.directoryExists(TARGET_CONTAINER_NAME2, false); TestUtils.directoryExists(TARGET_CONTAINER_NAME2, false);
} }
@Test(dataProvider = "ignoreOnWindows", description = "see http://code.google.com/p/jclouds/issues/detail?id=737")
public void testInvalidContainerName() { public void testInvalidContainerName() {
try { try {
blobStore.createContainerInLocation(null, "file/system"); blobStore.createContainerInLocation(null, "file/system");
@ -716,23 +725,28 @@ public class FilesystemAsyncBlobStoreTest {
} }
public void testRanges() throws IOException { public void testRanges() throws IOException {
/*
* Using CONTAINER_NAME here breaks tests on Windows because the container
* can't be deleted. See http://code.google.com/p/jclouds/issues/detail?id=737
*/
final String containerName = "containerWithRanges";
String payload = "abcdefgh"; String payload = "abcdefgh";
Blob blob = blobStore.blobBuilder("test").payload(new StringPayload(payload)).build(); Blob blob = blobStore.blobBuilder("test").payload(new StringPayload(payload)).build();
blobStore.putBlob(CONTAINER_NAME, blob); blobStore.putBlob(containerName, blob);
GetOptions getOptionsRangeStartAt = new GetOptions(); GetOptions getOptionsRangeStartAt = new GetOptions();
getOptionsRangeStartAt.startAt(1); getOptionsRangeStartAt.startAt(1);
Blob blobRangeStartAt = blobStore.getBlob(CONTAINER_NAME, blob.getMetadata().getName(), getOptionsRangeStartAt); Blob blobRangeStartAt = blobStore.getBlob(containerName, blob.getMetadata().getName(), getOptionsRangeStartAt);
Assert.assertEquals("bcdefgh", IOUtils.toString(blobRangeStartAt.getPayload().getInput())); Assert.assertEquals("bcdefgh", IOUtils.toString(blobRangeStartAt.getPayload().getInput()));
GetOptions getOptionsRangeTail = new GetOptions(); GetOptions getOptionsRangeTail = new GetOptions();
getOptionsRangeTail.tail(3); getOptionsRangeTail.tail(3);
Blob blobRangeTail = blobStore.getBlob(CONTAINER_NAME, blob.getMetadata().getName(), getOptionsRangeTail); Blob blobRangeTail = blobStore.getBlob(containerName, blob.getMetadata().getName(), getOptionsRangeTail);
Assert.assertEquals("fgh", IOUtils.toString(blobRangeTail.getPayload().getInput())); Assert.assertEquals("fgh", IOUtils.toString(blobRangeTail.getPayload().getInput()));
GetOptions getOptionsFragment = new GetOptions(); GetOptions getOptionsFragment = new GetOptions();
getOptionsFragment.range(4, 6); getOptionsFragment.range(4, 6);
Blob blobFragment = blobStore.getBlob(CONTAINER_NAME, blob.getMetadata().getName(), getOptionsFragment); Blob blobFragment = blobStore.getBlob(containerName, blob.getMetadata().getName(), getOptionsFragment);
Assert.assertEquals("efg", IOUtils.toString(blobFragment.getPayload().getInput())); Assert.assertEquals("efg", IOUtils.toString(blobFragment.getPayload().getInput()));
} }

View File

@ -48,6 +48,7 @@ import org.jclouds.filesystem.utils.TestUtils;
import org.jclouds.io.payloads.FilePayload; import org.jclouds.io.payloads.FilePayload;
import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test; import org.testng.annotations.Test;
/** /**
@ -92,6 +93,12 @@ public class FilesystemStorageStrategyImplTest {
TestUtils.cleanDirectoryContent(TestUtils.TARGET_BASE_DIR); TestUtils.cleanDirectoryContent(TestUtils.TARGET_BASE_DIR);
} }
@DataProvider
public Object[][] ignoreOnWindows() {
return (TestUtils.isWindowsOs() ? TestUtils.NO_INVOCATIONS
: TestUtils.SINGLE_NO_ARG_INVOCATION);
}
public void testCreateDirectory() { public void testCreateDirectory() {
storageStrategy.createDirectory(CONTAINER_NAME, null); storageStrategy.createDirectory(CONTAINER_NAME, null);
TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); TestUtils.directoryExists(TARGET_CONTAINER_NAME, true);
@ -114,10 +121,11 @@ public class FilesystemStorageStrategyImplTest {
storageStrategy.createDirectory(CONTAINER_NAME, null); storageStrategy.createDirectory(CONTAINER_NAME, null);
} }
@Test(dataProvider = "ignoreOnWindows", description = "see http://code.google.com/p/jclouds/issues/detail?id=737")
public void testCreateDirectory_WrongDirectoryName() { public void testCreateDirectory_WrongDirectoryName() {
try { try {
storageStrategy.createDirectory(CONTAINER_NAME, "$%&!'`\\/"); storageStrategy.createDirectory(CONTAINER_NAME, "$%&!'`\\/");
fail("No exception throwed"); fail("No exception thrown");
} catch (Exception e) { } catch (Exception e) {
} }
} }

View File

@ -48,6 +48,12 @@ public class TestUtils {
public static final String TARGET_BASE_DIR = "." + File.separator + "target" + File.separator + "basedir" + File.separator; public static final String TARGET_BASE_DIR = "." + File.separator + "target" + File.separator + "basedir" + File.separator;
public static final Object[][] NO_INVOCATIONS = new Object[0][0];
public static final Object[][] SINGLE_NO_ARG_INVOCATION = new Object[][] { new Object[0] };
public static boolean isWindowsOs() {
return System.getProperty("os.name", "").toLowerCase().contains("windows");
}
/** /**
* Generate a random blob key simple name (with no path in the key) * Generate a random blob key simple name (with no path in the key)

View File

@ -43,6 +43,7 @@ import org.jclouds.vcloud.internal.BaseVCloudAsyncClientTest;
import org.jclouds.vcloud.options.CaptureVAppOptions; import org.jclouds.vcloud.options.CaptureVAppOptions;
import org.jclouds.vcloud.options.CloneVAppOptions; import org.jclouds.vcloud.options.CloneVAppOptions;
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions; import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
import org.jclouds.vcloud.utils.TestUtils;
import org.jclouds.vcloud.xml.CatalogHandler; import org.jclouds.vcloud.xml.CatalogHandler;
import org.jclouds.vcloud.xml.CatalogItemHandler; import org.jclouds.vcloud.xml.CatalogItemHandler;
import org.jclouds.vcloud.xml.OrgHandler; import org.jclouds.vcloud.xml.OrgHandler;
@ -55,6 +56,7 @@ import org.jclouds.vcloud.xml.VAppTemplateHandler;
import org.jclouds.vcloud.xml.VDCHandler; import org.jclouds.vcloud.xml.VDCHandler;
import org.jclouds.vcloud.xml.VmHandler; import org.jclouds.vcloud.xml.VmHandler;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
@ -116,6 +118,7 @@ public class VCloudAsyncClientTest extends BaseVCloudAsyncClientTest<VCloudAsync
checkFilters(request); checkFilters(request);
} }
@Test(dataProvider = "ignoreOnWindows", description = "see http://code.google.com/p/jclouds/issues/detail?id=402")
public void testUpdateGuestConfiguration() throws SecurityException, NoSuchMethodException, IOException { public void testUpdateGuestConfiguration() throws SecurityException, NoSuchMethodException, IOException {
Method method = VCloudAsyncClient.class.getMethod("updateGuestCustomizationOfVm", URI.class, Method method = VCloudAsyncClient.class.getMethod("updateGuestCustomizationOfVm", URI.class,
GuestCustomizationSection.class); GuestCustomizationSection.class);
@ -813,4 +816,10 @@ public class VCloudAsyncClientTest extends BaseVCloudAsyncClientTest<VCloudAsync
syncClient = injector.getInstance(VCloudClient.class); syncClient = injector.getInstance(VCloudClient.class);
} }
@DataProvider
public Object[][] ignoreOnWindows() {
return (TestUtils.isWindowsOs() ? TestUtils.NO_INVOCATIONS
: TestUtils.SINGLE_NO_ARG_INVOCATION);
}
} }

View File

@ -31,8 +31,10 @@ import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.Strings2; import org.jclouds.util.Strings2;
import org.jclouds.vcloud.domain.GuestCustomizationSection; import org.jclouds.vcloud.domain.GuestCustomizationSection;
import org.jclouds.vcloud.internal.BaseVCloudAsyncClientTest; import org.jclouds.vcloud.internal.BaseVCloudAsyncClientTest;
import org.jclouds.vcloud.utils.TestUtils;
import org.jclouds.vcloud.xml.TaskHandler; import org.jclouds.vcloud.xml.TaskHandler;
import org.jclouds.vcloud.xml.VmHandler; import org.jclouds.vcloud.xml.VmHandler;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
@ -69,6 +71,7 @@ public class VmAsyncClientTest extends BaseVCloudAsyncClientTest<VmAsyncClient>
checkFilters(request); checkFilters(request);
} }
@Test(dataProvider = "ignoreOnWindows", description = "see http://code.google.com/p/jclouds/issues/detail?id=402")
public void testUpdateGuestConfiguration() throws SecurityException, NoSuchMethodException, IOException { public void testUpdateGuestConfiguration() throws SecurityException, NoSuchMethodException, IOException {
Method method = VmAsyncClient.class.getMethod("updateGuestCustomizationOfVm", GuestCustomizationSection.class, Method method = VmAsyncClient.class.getMethod("updateGuestCustomizationOfVm", GuestCustomizationSection.class,
URI.class); URI.class);
@ -316,4 +319,10 @@ public class VmAsyncClientTest extends BaseVCloudAsyncClientTest<VmAsyncClient>
checkFilters(request); checkFilters(request);
} }
@DataProvider
public Object[][] ignoreOnWindows() {
return (TestUtils.isWindowsOs() ? TestUtils.NO_INVOCATIONS
: TestUtils.SINGLE_NO_ARG_INVOCATION);
}
} }

View File

@ -0,0 +1,34 @@
/**
* 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.vcloud.utils;
/**
* Utility class for test
*
* @author Andrew Phillips
*/
public class TestUtils {
public static final Object[][] NO_INVOCATIONS = new Object[0][0];
public static final Object[][] SINGLE_NO_ARG_INVOCATION = new Object[][] { new Object[0] };
public static boolean isWindowsOs() {
return System.getProperty("os.name", "").toLowerCase().contains("windows");
}
}

View File

@ -18,8 +18,11 @@
*/ */
package org.jclouds.compute.callables; package org.jclouds.compute.callables;
import static java.lang.String.format;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.File;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
@ -42,7 +45,7 @@ public class InitScriptConfigurationForTasksTest {
public void testPatternUpdatesBasedir() { public void testPatternUpdatesBasedir() {
InitScriptConfigurationForTasks config = InitScriptConfigurationForTasks.create(); InitScriptConfigurationForTasks config = InitScriptConfigurationForTasks.create();
config.initScriptPattern("/var/foo-init-%s"); config.initScriptPattern("/var/foo-init-%s");
assertEquals(config.getBasedir(), "/var"); assertEquals(config.getBasedir(), format("%svar", File.separator));
assertEquals(config.getInitScriptPattern(), "/var/foo-init-%s"); assertEquals(config.getInitScriptPattern(), "/var/foo-init-%s");
} }
@ -57,7 +60,7 @@ public class InitScriptConfigurationForTasksTest {
}).getInstance(InitScriptConfigurationForTasks.class); }).getInstance(InitScriptConfigurationForTasks.class);
config.initScriptPattern("/var/foo-init-%s"); config.initScriptPattern("/var/foo-init-%s");
assertEquals(config.getBasedir(), "/var"); assertEquals(config.getBasedir(), format("%svar", File.separator));
assertEquals(config.getInitScriptPattern(), "/var/foo-init-%s"); assertEquals(config.getInitScriptPattern(), "/var/foo-init-%s");
} }

View File

@ -27,8 +27,11 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Resource;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.json.internal.GsonWrapper; import org.jclouds.json.internal.GsonWrapper;
import org.jclouds.logging.Logger;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -44,6 +47,9 @@ import com.google.inject.TypeLiteral;
*/ */
public class ParseFirstJsonValueNamed<T> implements Function<HttpResponse, T> { public class ParseFirstJsonValueNamed<T> implements Function<HttpResponse, T> {
@Resource
protected Logger logger = Logger.NULL;
private final GsonWrapper json; private final GsonWrapper json;
private final TypeLiteral<T> type; private final TypeLiteral<T> type;
private final String name; private final String name;
@ -68,8 +74,11 @@ public class ParseFirstJsonValueNamed<T> implements Function<HttpResponse, T> {
for (; token != JsonToken.END_DOCUMENT && nnn(this.name, reader, token, name); token = skipAndPeek(token, for (; token != JsonToken.END_DOCUMENT && nnn(this.name, reader, token, name); token = skipAndPeek(token,
reader)) reader))
; ;
if (name.get().equals(this.name)) { if (name.get() == null) {
return json.delegate().<T>fromJson(reader, type.getType()); logger.trace("did not object named %s in json from response %s", this.name, arg0);
return nothing();
} else if (name.get().equals(this.name)) {
return json.delegate().<T> fromJson(reader, type.getType());
} else { } else {
return nothing(); return nothing();
} }

View File

@ -0,0 +1,138 @@
/**
* 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.http.functions;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule;
import org.jclouds.json.internal.GsonWrapper;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Guice;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
*/
@Test(testName = "ParseFirstJsonValueNamedTest")
public class ParseFirstJsonValueNamedTest {
GsonWrapper json = Guice.createInjector(new GsonModule()).getInstance(GsonWrapper.class);
static class Event {
private String name;
private String source;
private Event(String name, String source) {
this.name = name;
this.source = source;
}
@Override
public String toString() {
return String.format("(name=%s, source=%s)", name, source);
}
}
public void testParseNestedElements() throws IOException {
String nested = "{ \"count\":1 ,\"event\" : [ {name:'GREETINGS',source:'guest'} ] }";
HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie")
.payload(Payloads.newPayload(nested)).build();
List<Event> val = new ParseFirstJsonValueNamed<List<Event>>(json, new TypeLiteral<List<Event>>() {
}, "event").apply(response);
assertEquals(val.toString(), "[(name=GREETINGS, source=guest)]");
}
public void testParseNestedElementsWhenNotFoundIsEmpty() throws IOException {
String nested = "{ \"count\":1 ,\"evant\" : [ {name:'GREETINGS',source:'guest'} ] }";
HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie")
.payload(Payloads.newPayload(nested)).build();
List<Event> val = new ParseFirstJsonValueNamed<List<Event>>(json, new TypeLiteral<List<Event>>() {
}, "event").apply(response);
assertEquals(val.toString(), "[]");
}
public void testParseNestedElementsButNothing() throws IOException {
String nested = "{ \"count\":1 ,\"event\" : [ ] }";
HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie")
.payload(Payloads.newPayload(nested)).build();
List<Event> val = new ParseFirstJsonValueNamed<List<Event>>(json, new TypeLiteral<List<Event>>() {
}, "event").apply(response);
assertEquals(val.toString(), "[]");
}
public void testParseNestedFurtherElements() throws IOException {
String nestedFurther = "{ \"listaccountsresponse\" : { \"count\":1 ,\"event\" : [ {name:'GREETINGS',source:'guest'} ] } }";
HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie")
.payload(Payloads.newPayload(nestedFurther)).build();
List<Event> val = new ParseFirstJsonValueNamed<List<Event>>(json, new TypeLiteral<List<Event>>() {
}, "event").apply(response);
assertEquals(val.toString(), "[(name=GREETINGS, source=guest)]");
}
public void testParseNestedFurtherElementsButNothing() throws IOException {
String nestedFurther = "{ \"listaccountsresponse\" : { \"count\":1 ,\"event\" : [ ] } }";
HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie")
.payload(Payloads.newPayload(nestedFurther)).build();
List<Event> val = new ParseFirstJsonValueNamed<List<Event>>(json, new TypeLiteral<List<Event>>() {
}, "event").apply(response);
assertEquals(val.toString(), "[]");
}
public void testParseNoPayloadEmptyList() throws IOException {
HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie").build();
List<Event> val = new ParseFirstJsonValueNamed<List<Event>>(json, new TypeLiteral<List<Event>>() {
}, "event").apply(response);
assertEquals(val, ImmutableList.<Event> of());
}
public void testParseNoPayloadEmptyMap() throws IOException {
HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie").build();
Map<String, String> val = new ParseFirstJsonValueNamed<Map<String, String>>(json,
new TypeLiteral<Map<String, String>>() {
}, "event").apply(response);
assertEquals(val, ImmutableMap.<String, String> of());
}
public void testParseNoPayloadEmptySet() throws IOException {
HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie").build();
Set<Event> val = new ParseFirstJsonValueNamed<Set<Event>>(json, new TypeLiteral<Set<Event>>() {
}, "event").apply(response);
assertEquals(val, ImmutableSet.<Event> of());
}
}

View File

@ -87,6 +87,8 @@ public class SshjSshClientTest {
} }
public void testExceptionClassesRetry() { public void testExceptionClassesRetry() {
assert ssh.shouldRetry(new ConnectionException("Read timed out", new SSHException("Read timed out",
new SocketTimeoutException("Read timed out"))));
assert ssh.shouldRetry(new SocketTimeoutException("connect timed out")); assert ssh.shouldRetry(new SocketTimeoutException("connect timed out"));
assert ssh.shouldRetry(new TransportException("socket closed")); assert ssh.shouldRetry(new TransportException("socket closed"));
assert ssh.shouldRetry(new ConnectionException("problem")); assert ssh.shouldRetry(new ConnectionException("problem"));

View File

@ -190,7 +190,7 @@ public class IsoToIMachine implements Function<String, IMachine> {
} }
private void ensureMachineIsLaunched(String vmName) { private void ensureMachineIsLaunched(String vmName) {
applyForMachine(manager, vmName, new LaunchMachineIfNotAlreadyRunning(manager, ExecutionType.GUI, "")); applyForMachine(manager, vmName, new LaunchMachineIfNotAlreadyRunning(manager, ExecutionType.HEADLESS, ""));
} }
private void ensureGuestAdditionsMediumIsAttached(String vmName, final IMedium guestAdditionsDvdMedium) { private void ensureGuestAdditionsMediumIsAttached(String vmName, final IMedium guestAdditionsDvdMedium) {

View File

@ -29,10 +29,7 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.virtualbox.domain.ErrorCode; import org.jclouds.virtualbox.domain.ErrorCode;
import org.jclouds.virtualbox.domain.ExecutionType; import org.jclouds.virtualbox.domain.ExecutionType;
import org.virtualbox_4_1.IMachine; import org.virtualbox_4_1.*;
import org.virtualbox_4_1.IProgress;
import org.virtualbox_4_1.VBoxException;
import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -50,7 +47,6 @@ import com.google.common.base.Function;
* Failed to assign machine to session. * Failed to assign machine to session.
* *
* @author Mattias Holmqvist * @author Mattias Holmqvist
*
* @see ErrorCode * @see ErrorCode
*/ */
public class LaunchMachineIfNotAlreadyRunning implements Function<IMachine, Void> { public class LaunchMachineIfNotAlreadyRunning implements Function<IMachine, Void> {
@ -88,6 +84,11 @@ public class LaunchMachineIfNotAlreadyRunning implements Function<IMachine, Void
default: default:
propagate(e); propagate(e);
} }
} finally {
if (manager.getSessionObject().getState() == SessionState.Locked) {
// Remove session lock taken by launchVmProcess()
manager.getSessionObject().unlockMachine();
}
} }
return null; return null;
} }

View File

@ -0,0 +1,67 @@
/*
* 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.virtualbox.functions.admin;
import com.google.common.base.Function;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.virtualbox.domain.ErrorCode;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.VBoxException;
import org.virtualbox_4_1.VirtualBoxManager;
import javax.annotation.Nullable;
import javax.annotation.Resource;
import javax.inject.Named;
public class UnregisterMachineIfExists implements Function<String, Void> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private VirtualBoxManager manager;
private CleanupMode mode;
public UnregisterMachineIfExists(VirtualBoxManager manager, CleanupMode mode) {
this.manager = manager;
this.mode = mode;
}
@Override
public Void apply(@Nullable String vmName) {
try {
IMachine machine = manager.getVBox().findMachine(vmName);
machine.unregister(mode);
} catch (VBoxException e) {
ErrorCode errorCode = ErrorCode.valueOf(e);
switch (errorCode) {
case VBOX_E_OBJECT_NOT_FOUND:
logger.debug("Machine %s does not exists, cannot unregister", vmName);
break;
default:
throw e;
}
}
return null;
}
}

View File

@ -36,8 +36,12 @@ import org.jclouds.domain.Credentials;
import org.jclouds.json.Json; import org.jclouds.json.Json;
import org.jclouds.json.config.GsonModule; import org.jclouds.json.config.GsonModule;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest; import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.jclouds.virtualbox.functions.admin.UnregisterMachineIfExists;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine; import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.VirtualBoxManager; import org.virtualbox_4_1.VirtualBoxManager;
@ -69,9 +73,9 @@ public class IsoToIMachineLiveTest extends BaseVirtualBoxClientLiveTest {
public void setUp() throws Exception { public void setUp() throws Exception {
identity = "toor"; identity = "toor";
credential = "password"; credential = "password";
new UnregisterMachineIfExists(manager, CleanupMode.Full).apply(vmName);
} }
@Test
public void testCreateImageMachineFromIso() throws Exception { public void testCreateImageMachineFromIso() throws Exception {
VirtualBoxManager manager = (VirtualBoxManager) context.getProviderSpecificContext().getApi(); VirtualBoxManager manager = (VirtualBoxManager) context.getProviderSpecificContext().getApi();

View File

@ -26,10 +26,7 @@ import static org.easymock.classextension.EasyMock.verify;
import org.jclouds.virtualbox.domain.ExecutionType; import org.jclouds.virtualbox.domain.ExecutionType;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import org.virtualbox_4_1.IMachine; import org.virtualbox_4_1.*;
import org.virtualbox_4_1.IProgress;
import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.VirtualBoxManager;
@Test(groups = "unit", testName = "LaunchMachineIfNotAlreadyRunningTest") @Test(groups = "unit", testName = "LaunchMachineIfNotAlreadyRunningTest")
public class LaunchMachineIfNotAlreadyRunningTest { public class LaunchMachineIfNotAlreadyRunningTest {
@ -54,9 +51,11 @@ public class LaunchMachineIfNotAlreadyRunningTest {
IMachine machine = createMock(IMachine.class); IMachine machine = createMock(IMachine.class);
IProgress progress = createMock(IProgress.class); IProgress progress = createMock(IProgress.class);
expect(manager.getSessionObject()).andReturn(session); expect(manager.getSessionObject()).andReturn(session).anyTimes();
expect(machine.launchVMProcess(session, type, environment)).andReturn(progress); expect(machine.launchVMProcess(session, type, environment)).andReturn(progress);
progress.waitForCompletion(-1); progress.waitForCompletion(-1);
expect(session.getState()).andReturn(SessionState.Locked);
session.unlockMachine();
replay(manager, machine, session, progress); replay(manager, machine, session, progress);

View File

@ -0,0 +1,56 @@
/*
* 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.virtualbox.functions.admin;
import org.testng.annotations.Test;
import org.virtualbox_4_1.*;
import java.util.Collections;
import java.util.List;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.expect;
import static org.easymock.classextension.EasyMock.*;
@Test(groups = "unit", testName = "UnregisterMachineIfExistsTest")
public class UnregisterMachineIfExistsTest {
@Test
public void testUnregisterExistingMachine() throws Exception {
VirtualBoxManager manager = createMock(VirtualBoxManager.class);
IVirtualBox vBox = createMock(IVirtualBox.class);
IMachine registeredMachine = createMock(IMachine.class);
List<IMedium> mediums = Collections.emptyList();
CleanupMode mode = CleanupMode.Full;
String vmName = "jclouds-image-example-machine";
expect(manager.getVBox()).andReturn(vBox).anyTimes();
expect(vBox.findMachine(vmName)).andReturn(registeredMachine);
expect(registeredMachine.unregister(mode)).andReturn(mediums);
expectLastCall().anyTimes();
replay(manager, vBox, registeredMachine);
new UnregisterMachineIfExists(manager, mode).apply(vmName);
}
}