refactored tests so that admin starts first via @BeforeSuite

This commit is contained in:
Adrian Cole 2011-10-10 23:43:57 -07:00
parent b2ade042bc
commit 0f73d04fca
4 changed files with 789 additions and 895 deletions

View File

@ -0,0 +1,215 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.virtualbox.experiment;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
import static org.testng.Assert.assertEquals;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.logging.Logger;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closeables;
public class SetupVirtualBoxForLiveTest {
private String provider = "virtualbox";
private URI endpoint;
private String apiVersion;
private String workingDir;
private URI gaIsoUrl;
private String gaIsoName;
private URI distroIsoUrl;
private String distroIsoName;
private ComputeServiceContext context;
private String hostId = "host";
private String guestId = "guest";
private String majorVersion;
private URI vboxDmg;
private String vboxVersionName;
public void setupCredentials() {
endpoint = URI.create(System.getProperty("test." + provider + ".endpoint", "http://localhost:18083/"));
apiVersion = System.getProperty("test." + provider + ".apiversion", "4.1.2r73507");
majorVersion = Iterables.get(Splitter.on('r').split(apiVersion), 0);
}
public Logger logger() {
return context.utils().loggerFactory().getLogger("jclouds.compute");
}
public void setupConfigurationProperties() {
workingDir = System.getProperty("user.home") + File.separator
+ System.getProperty("test." + provider + ".workingDir", "jclouds-virtualbox-test");
if (new File(workingDir).mkdir())
;
gaIsoName = System.getProperty("test." + provider + ".gaIsoName", "VBoxGuestAdditions_" + majorVersion + ".iso");
gaIsoUrl = URI.create(System.getProperty("test." + provider + ".gaIsoUrl",
"http://download.virtualbox.org/virtualbox/" + majorVersion + "/" + gaIsoName));
distroIsoName = System.getProperty("test." + provider + ".distroIsoName", "ubuntu-11.04-server-i386.iso");
distroIsoUrl = URI.create(System.getProperty("test." + provider + ".distroIsoUrl",
"http://releases.ubuntu.com/11.04/ubuntu-11.04-server-i386.iso"));
vboxDmg = URI.create(System.getProperty("test." + provider + ".vboxDmg",
"http://download.virtualbox.org/virtualbox/4.1.2/VirtualBox-4.1.2-73507-OSX.dmg"));
vboxVersionName = System.getProperty("test" + provider + ".vboxVersionName", "VirtualBox-4.1.2-73507-OSX.dmg");
}
public void configureJettyServer() throws Exception {
Server server = new Server(8080);
ResourceHandler resource_handler = new ResourceHandler();
resource_handler.setDirectoriesListed(true);
resource_handler.setWelcomeFiles(new String[] { "index.html" });
resource_handler.setResourceBase(".");
logger().info("serving " + resource_handler.getBaseResource());
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
server.setHandler(handlers);
server.start();
}
@BeforeSuite
public void setupClient() throws Exception {
context = TestUtils.computeServiceForLocalhostAndGuest();
setupCredentials();
setupConfigurationProperties();
downloadFileUnlessPresent(distroIsoUrl, workingDir, distroIsoName);
downloadFileUnlessPresent(gaIsoUrl, workingDir, gaIsoName);
installVbox();
checkVboxVersionExpected();
if (!new InetSocketAddressConnect().apply(new IPSocket(endpoint.getHost(), endpoint.getPort())))
startupVboxWebServer();
configureJettyServer();
}
public void installVbox() throws Exception {
if (runScriptOnNode(hostId, "VBoxManage --version", runAsRoot(false).wrapInInitScript(false)).getExitCode() != 0) {
logger().debug("installing virtualbox");
if (isOSX(hostId)) {
downloadFileUnlessPresent(vboxDmg, workingDir, vboxVersionName);
runScriptOnNode(hostId, "hdiutil attach " + workingDir + "/" + vboxVersionName);
runScriptOnNode(hostId,
"installer -pkg /Volumes/VirtualBox/VirtualBox.mpkg -target /Volumes/Macintosh\\ HD");
} else {
// TODO other platforms
runScriptOnNode(hostId, "cat > /etc/apt/sources.list.d/TODO");
runScriptOnNode(hostId,
"wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | apt-key add -");
runScriptOnNode(hostId, "apt-get update");
runScriptOnNode(hostId, "apt-get --yes install virtualbox-4.1");
}
}
}
public void checkVboxVersionExpected() throws IOException, InterruptedException {
logger().debug("checking virtualbox version");
assertEquals(runScriptOnNode(hostId, "VBoxManage -version").getOutput().trim(), apiVersion);
}
/**
*
* @param command
* absolute path to command. For ubuntu 10.04: /usr/bin/vboxwebsrv
* @throws IOException
* @throws InterruptedException
*/
public void startupVboxWebServer() {
logger().debug("disabling password access");
runScriptOnNode(hostId, "VBoxManage setproperty websrvauthlibrary null", runAsRoot(false).wrapInInitScript(false));
logger().debug("starting vboxwebsrv");
String vboxwebsrv = "vboxwebsrv -t 10000 -v -b";
if (isOSX(hostId))
vboxwebsrv = "cd /Applications/VirtualBox.app/Contents/MacOS/ && " + vboxwebsrv;
runScriptOnNode(hostId, vboxwebsrv, runAsRoot(false).wrapInInitScript(false).blockOnPort(endpoint.getPort(), 10)
.blockOnComplete(false).nameTask("vboxwebsrv"));
}
public boolean isOSX(String id) {
return context.getComputeService().getNodeMetadata(hostId).getOperatingSystem().getDescription().equals(
"Mac OS X");
}
public File downloadFileUnlessPresent(URI sourceURL, String destinationDir, String filename) throws Exception {
File iso = new File(destinationDir, filename);
if (!iso.exists()) {
InputStream is = context.utils().http().get(sourceURL);
checkNotNull(is, "%s not found", sourceURL);
try {
ByteStreams.copy(is, new FileOutputStream(iso));
} finally {
Closeables.closeQuietly(is);
}
}
return iso;
}
@AfterSuite
public void stopVboxWebServer() throws IOException {
runScriptOnNode(guestId, "pidof vboxwebsrv | xargs kill");
}
public ExecResponse runScriptOnNode(String nodeId, String command, RunScriptOptions options) {
ExecResponse toReturn = context.getComputeService().runScriptOnNode(nodeId, command, options);
assert toReturn.getExitCode() == 0 : toReturn;
return toReturn;
}
public ExecResponse runScriptOnNode(String nodeId, String command) {
return runScriptOnNode(nodeId, command, wrapInInitScript(false));
}
}

View File

@ -18,7 +18,6 @@
*/ */
package org.jclouds.virtualbox.experiment; package org.jclouds.virtualbox.experiment;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.propagate; import static com.google.common.base.Throwables.propagate;
import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot; import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript; import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
@ -27,35 +26,21 @@ import static org.testng.Assert.assertNotNull;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI;
import java.rmi.RemoteException; import java.rmi.RemoteException;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.ExecResponse; import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.options.RunScriptOptions; import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.logging.Logger;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.scriptbuilder.domain.OsFamily; import org.jclouds.scriptbuilder.domain.OsFamily;
import org.jclouds.scriptbuilder.statements.login.AdminAccess; import org.jclouds.scriptbuilder.statements.login.AdminAccess;
import org.jclouds.scriptbuilder.statements.login.DefaultConfiguration; import org.jclouds.scriptbuilder.statements.login.DefaultConfiguration;
import org.jclouds.ssh.SshException; import org.jclouds.ssh.SshException;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.jclouds.virtualbox.settings.KeyboardScancodes; import org.jclouds.virtualbox.settings.KeyboardScancodes;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import org.virtualbox_4_1.AccessMode; import org.virtualbox_4_1.AccessMode;
@ -74,583 +59,374 @@ import org.virtualbox_4_1.StorageBus;
import org.virtualbox_4_1.VirtualBoxManager; import org.virtualbox_4_1.VirtualBoxManager;
import org.virtualbox_4_1.jaxws.MediumVariant; import org.virtualbox_4_1.jaxws.MediumVariant;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closeables;
@Test(groups = "live", testName = "virtualbox.VirtualboxAdministrationKickstartTest") @Test(groups = "live", testName = "virtualbox.VirtualboxAdministrationKickstartTest")
public class VirtualboxAdministrationKickstartLiveTest { public class VirtualboxAdministrationKickstartLiveTest extends BaseVirtualBoxClientLiveTest {
protected String provider = "virtualbox"; private String hostId = "host"; // TODO: shared between classes; move to iTestContext
protected String identity; private String guestId = "guest"; // TODO: ^^
protected String credential; private String distroIsoName; // TODO: ^^
protected URI endpoint; private String workingDir;// TODO: ^^
protected String apiVersion;
protected String vmName; private String settingsFile; // Fully qualified path where the settings
private String keyboardSequence;
VirtualBoxManager manager = VirtualBoxManager.createInstance("");
private String vmId; // Machine UUID
protected Predicate<IPSocket> socketTester; private String vmName;
private String controllerIDE;
protected String settingsFile; // Fully qualified path where the settings private String osTypeId; // Guest OS Type ID.
protected String osTypeId; // Guest OS Type ID. private boolean forceOverwrite;
protected String vmId; // Machine UUID (optional). private String diskFormat;
protected boolean forceOverwrite; private String adminDisk;
protected String diskFormat; private String guestAdditionsDvd;
private String snapshotDescription;
protected String workingDir;
protected String adminDisk; private VirtualBoxManager manager = VirtualBoxManager.createInstance("");
protected String guestAdditionsDvd; protected boolean isUbuntu(String id) {
private URI gaIsoUrl; return context.getComputeService().getNodeMetadata(id).getOperatingSystem().getDescription().contains("ubuntu");
}
private String gaIsoName;
private URI distroIsoUrl; @BeforeMethod
private String distroIsoName; protected void setupManager() {
private String controllerIDE; manager.connect(endpoint, identity, credential);
private String controllerSATA; }
private String keyboardSequence;
private String preseedUrl; @BeforeClass
void setupConfigurationProperties() {
private ComputeServiceContext context;
private String hostId = "host"; controllerIDE = System.getProperty("test." + provider + ".controllerIde", "IDE Controller");
private String guestId = "guest"; diskFormat = System.getProperty("test." + provider + ".diskformat", "");
private String majorVersion;
private String minorVersion; // VBOX
private URI vboxDmg; settingsFile = null;
private String vboxVersionName; osTypeId = System.getProperty("test." + provider + ".osTypeId", "");
private String snapshotDescription; vmId = System.getProperty("test." + provider + ".vmId", null);
forceOverwrite = true;
protected void setupCredentials() { vmName = System.getProperty("test." + provider + ".vmname", "jclouds-virtualbox-kickstart-admin");
identity = System.getProperty("test." + provider + ".identity",
"administrator"); workingDir = System.getProperty("user.home") + File.separator
credential = System.getProperty("test." + provider + ".credential", + System.getProperty("test." + provider + ".workingDir", "jclouds-virtualbox-test");
"12345"); if (new File(workingDir).mkdir())
endpoint = URI.create(System.getProperty("test." + provider ;
+ ".endpoint", "http://localhost:18083/")); distroIsoName = System.getProperty("test." + provider + ".distroIsoName", "ubuntu-11.04-server-i386.iso");
apiVersion = System.getProperty("test." + provider + ".apiversion", adminDisk = workingDir + File.separator + System.getProperty("test." + provider + ".adminDisk", "admin.vdi");
"4.1.2r73507"); String majorVersion = Iterables.get(Splitter.on('r').split(apiversion), 0);
majorVersion = Iterables.get(Splitter.on('r').split(apiVersion), 0); guestAdditionsDvd = workingDir
minorVersion = Iterables.get(Splitter.on('r').split(apiVersion), 1); + File.separator
} + System.getProperty("test." + provider + ".guestAdditionsDvd", "VBoxGuestAdditions_" + majorVersion
+ ".iso");
protected Logger logger() { snapshotDescription = System
return context.utils().loggerFactory().getLogger("jclouds.compute"); .getProperty("test." + provider + "snapshotdescription", "jclouds-virtualbox-snaphot");
}
keyboardSequence = System.getProperty("test." + provider + ".keyboardSequence", "<Esc><Esc><Enter> "
protected void setupConfigurationProperties() { + "/install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg "
+ "debian-installer=en_US auto locale=en_US kbd-chooser/method=us " + "hostname=" + vmName + " "
controllerIDE = System.getProperty("test." + provider + "fb=false debconf/frontend=noninteractive "
+ ".controllerIde", "IDE Controller"); + "keyboard-configuration/layout=USA keyboard-configuration/variant=USA console-setup/ask_detect=false "
controllerSATA = System.getProperty("test." + provider + "initrd=/install/initrd.gz -- <Enter>");
+ ".controllerSata", "SATA Controller");
diskFormat = System.getProperty("test." + provider + ".diskformat", ""); }
// VBOX public void sendKeyboardSequence(String keyboardSequence) throws InterruptedException {
settingsFile = null; String[] sequenceSplited = keyboardSequence.split(" ");
osTypeId = System.getProperty("test." + provider + ".osTypeId", ""); StringBuilder sb = new StringBuilder();
vmId = System.getProperty("test." + provider + ".vmId", null); for (String line : sequenceSplited) {
forceOverwrite = true; String converted = stringToKeycode(line);
vmName = System.getProperty("test." + provider + ".vmname", for (String word : converted.split(" ")) {
"jclouds-virtualbox-kickstart-admin"); sb.append("vboxmanage controlvm " + vmName + " keyboardputscancode " + word + "; ");
workingDir = System.getProperty("user.home") if (word.endsWith(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<Enter>"))) {
+ File.separator runScriptOnNode(hostId, sb.toString(), runAsRoot(false).wrapInInitScript(false));
+ System.getProperty("test." + provider + ".workingDir", sb.delete(0, sb.length() - 1);
"jclouds-virtualbox-test"); }
if (new File(workingDir).mkdir());
gaIsoName = System.getProperty("test." + provider + ".gaIsoName", if (word.endsWith(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<Return>"))) {
"VBoxGuestAdditions_" + majorVersion + ".iso"); runScriptOnNode(hostId, sb.toString(), runAsRoot(false).wrapInInitScript(false));
gaIsoUrl = URI.create(System.getProperty("test." + provider sb.delete(0, sb.length() - 1);
+ ".gaIsoUrl", "http://download.virtualbox.org/virtualbox/" }
+ majorVersion + "/" + gaIsoName));
}
distroIsoName = System.getProperty("test." + provider }
+ ".distroIsoName", "ubuntu-11.04-server-i386.iso"); }
distroIsoUrl = URI
.create(System public ExecResponse runScriptOnNode(String nodeId, String command, RunScriptOptions options) {
.getProperty("test." + provider + ".distroIsoUrl", ExecResponse toReturn = context.getComputeService().runScriptOnNode(nodeId, command, options);
"http://releases.ubuntu.com/11.04/ubuntu-11.04-server-i386.iso")); assert toReturn.getExitCode() == 0 : toReturn;
vboxDmg = URI.create(System.getProperty("test." + provider + ".vboxDmg","http://download.virtualbox.org/virtualbox/4.1.2/VirtualBox-4.1.2-73507-OSX.dmg")); return toReturn;
vboxVersionName = System.getProperty("test" + provider + ".vboxVersionName", "VirtualBox-4.1.2-73507-OSX.dmg"); }
adminDisk = workingDir public ExecResponse runScriptOnNode(String nodeId, String command) {
+ File.separator return runScriptOnNode(nodeId, command, wrapInInitScript(false));
+ System.getProperty("test." + provider + ".adminDisk", }
"admin.vdi");
guestAdditionsDvd = workingDir public String stringToKeycode(String s) {
+ File.separator StringBuilder keycodes = new StringBuilder();
+ System.getProperty("test." + provider + ".guestAdditionsDvd", if (s.startsWith("<")) {
"VBoxGuestAdditions_" + majorVersion + ".iso"); String[] specials = s.split("<");
for (int i = 1; i < specials.length; i++) {
preseedUrl = System.getProperty("test." + provider + ".preseedurl", keycodes.append(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<" + specials[i]) + " ");
"http://dl.dropbox.com/u/693111/preseed.cfg"); }
return keycodes.toString();
snapshotDescription = System.getProperty("test." + provider + "snapshotdescription", "jclouds-virtualbox-snaphot"); }
keyboardSequence = System int i = 0;
.getProperty( while (i < s.length()) {
"test." + provider + ".keyboardSequence", String digit = s.substring(i, i + 1);
"<Esc><Esc><Enter> " String hex = KeyboardScancodes.NORMAL_KEYBOARD_BUTTON_MAP.get(digit);
+ "/install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg " keycodes.append(hex + " ");
+ "debian-installer=en_US auto locale=en_US kbd-chooser/method=us " if (i != 0 && i % 14 == 0)
+ "hostname=" keycodes.append(" ");
+ vmName i++;
+ " " }
+ "fb=false debconf/frontend=noninteractive " keycodes.append(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<Spacebar>") + " ");
+ "keyboard-configuration/layout=USA keyboard-configuration/variant=USA console-setup/ask_detect=false "
+ "initrd=/install/initrd.gz -- <Enter>"); return keycodes.toString();
}
} @AfterMethod
protected void disconnectAndClenaupManager() throws RemoteException, MalformedURLException {
@BeforeGroups(groups = "live") manager.disconnect();
protected void setupClient() throws Exception { manager.cleanup();
context = TestUtils.computeServiceForLocalhostAndGuest(); }
socketTester = new RetryablePredicate<IPSocket>(
new InetSocketAddressConnect(), 130, 10, TimeUnit.SECONDS); @Test
setupCredentials(); public void testCreateVirtualMachine() {
setupConfigurationProperties(); IMachine newVM = manager.getVBox().createMachine(settingsFile, vmName, osTypeId, vmId, forceOverwrite);
downloadFileUnlessPresent(distroIsoUrl, workingDir, distroIsoName); manager.getVBox().registerMachine(newVM);
downloadFileUnlessPresent(gaIsoUrl, workingDir, gaIsoName); assertNotNull(newVM.getName());
}
installVbox();
checkVboxVersionExpected(); @Test(dependsOnMethods = "testCreateVirtualMachine")
if (!new InetSocketAddressConnect().apply(new IPSocket(endpoint public void testChangeRAM() {
.getHost(), endpoint.getPort()))) Long memorySize = new Long(1024);
startupVboxWebServer(); ISession session = manager.getSessionObject();
configureJettyServer(); IMachine machine = manager.getVBox().findMachine(vmName);
} machine.lockMachine(session, LockType.Write);
IMachine mutable = session.getMachine();
private void configureJettyServer() throws Exception { mutable.setMemorySize(memorySize);
Server server = new Server(8080); mutable.saveSettings();
session.unlockMachine();
ResourceHandler resource_handler = new ResourceHandler(); assertEquals(manager.getVBox().findMachine(vmName).getMemorySize(), memorySize);
resource_handler.setDirectoriesListed(true); }
resource_handler.setWelcomeFiles(new String[] { "index.html" });
@Test(dependsOnMethods = "testChangeRAM")
resource_handler.setResourceBase("."); public void testCreateIdeController() {
logger().info("serving " + resource_handler.getBaseResource()); ISession session = manager.getSessionObject();
IMachine machine = manager.getVBox().findMachine(vmName);
HandlerList handlers = new HandlerList(); machine.lockMachine(session, LockType.Write);
handlers.setHandlers(new Handler[] { resource_handler, IMachine mutable = session.getMachine();
new DefaultHandler() }); mutable.addStorageController(controllerIDE, StorageBus.IDE);
server.setHandler(handlers); mutable.saveSettings();
session.unlockMachine();
server.start(); assertEquals(manager.getVBox().findMachine(vmName).getStorageControllers().size(), 1);
} }
void installVbox() throws Exception { @Test(dependsOnMethods = "testCreateIdeController")
if (runScriptOnNode(hostId, "VBoxManage --version", runAsRoot(false).wrapInInitScript(false)).getExitCode() != 0) { public void testAttachIsoDvd() {
logger().debug("installing virtualbox"); IMedium distroMedium = manager.getVBox().openMedium(workingDir + "/" + distroIsoName, DeviceType.DVD,
if (isOSX(hostId)) { AccessMode.ReadOnly, forceOverwrite);
downloadFileUnlessPresent(vboxDmg, workingDir, vboxVersionName);
runScriptOnNode(hostId, "hdiutil attach " + workingDir + "/" + vboxVersionName); ISession session = manager.getSessionObject();
runScriptOnNode(hostId, "installer -pkg /Volumes/VirtualBox/VirtualBox.mpkg -target /Volumes/Macintosh\\ HD"); IMachine machine = manager.getVBox().findMachine(vmName);
} else { machine.lockMachine(session, LockType.Write);
// TODO other platforms IMachine mutable = session.getMachine();
runScriptOnNode(hostId, "cat > /etc/apt/sources.list.d/TODO"); mutable.attachDevice(controllerIDE, 0, 0, DeviceType.DVD, distroMedium);
runScriptOnNode( mutable.saveSettings();
hostId, session.unlockMachine();
"wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | apt-key add -"); assertEquals(distroMedium.getId().equals(""), false);
runScriptOnNode(hostId, "apt-get update"); }
runScriptOnNode(hostId, "apt-get --yes install virtualbox-4.1");
} @Test(dependsOnMethods = "testAttachIsoDvd")
} public void testCreateAndAttachHardDisk() throws InterruptedException {
} IMedium hd = null;
if (new File(adminDisk).exists()) {
void checkVboxVersionExpected() throws IOException, InterruptedException { new File(adminDisk).delete();
logger().debug("checking virtualbox version"); }
assertEquals(runScriptOnNode(hostId, "VBoxManage -version").getOutput() hd = manager.getVBox().createHardDisk(diskFormat, adminDisk);
.trim(), apiVersion); long size = 4L * 1024L * 1024L * 1024L - 4L;
} IProgress progress = hd.createBaseStorage(new Long(size), new Long(MediumVariant.STANDARD.ordinal()));
// TODO: poll?
/**
* ISession session = manager.getSessionObject();
* @param command IMachine machine = manager.getVBox().findMachine(vmName);
* absolute path to command. For ubuntu 10.04: machine.lockMachine(session, LockType.Write);
* /usr/bin/vboxwebsrv IMachine mutable = session.getMachine();
* @throws IOException mutable.attachDevice(controllerIDE, 0, 1, DeviceType.HardDisk, hd);
* @throws InterruptedException mutable.saveSettings();
*/ session.unlockMachine();
void startupVboxWebServer() { assertEquals(hd.getId().equals(""), false);
logger().debug("disabling password access"); }
runScriptOnNode(hostId, "VBoxManage setproperty websrvauthlibrary null", runAsRoot(false).wrapInInitScript(false));
logger().debug("starting vboxwebsrv"); @Test(dependsOnMethods = "testCreateAndAttachHardDisk")
String vboxwebsrv = "vboxwebsrv -t 10000 -v -b"; public void testConfigureNIC() {
if (isOSX(hostId)) ISession session = manager.getSessionObject();
vboxwebsrv = "cd /Applications/VirtualBox.app/Contents/MacOS/ && " IMachine machine = manager.getVBox().findMachine(vmName);
+ vboxwebsrv; machine.lockMachine(session, LockType.Write);
IMachine mutable = session.getMachine();
runScriptOnNode(
hostId, // NAT
vboxwebsrv, mutable.getNetworkAdapter(new Long(0)).setAttachmentType(NetworkAttachmentType.NAT);
runAsRoot(false).wrapInInitScript(false) machine.getNetworkAdapter(new Long(0)).getNatDriver().addRedirect("guestssh", NATProtocol.TCP, "127.0.0.1", 2222,
.blockOnPort(endpoint.getPort(), 10) "", 22);
.blockOnComplete(false) mutable.getNetworkAdapter(new Long(0)).setEnabled(true);
.nameTask("vboxwebsrv"));
} mutable.saveSettings();
session.unlockMachine();
protected boolean isOSX(String id) { }
return context.getComputeService().getNodeMetadata(hostId)
.getOperatingSystem().getDescription().equals("Mac OS X"); @Test(dependsOnMethods = "testConfigureNIC")
} public void testAttachGuestAdditions() {
ISession session = manager.getSessionObject();
protected boolean isUbuntu(String id) { IMachine machine = manager.getVBox().findMachine(vmName);
return context.getComputeService().getNodeMetadata(id)
.getOperatingSystem().getDescription().contains("ubuntu"); IMedium distroMedium = manager.getVBox().openMedium(guestAdditionsDvd, DeviceType.DVD, AccessMode.ReadOnly,
} forceOverwrite);
machine.lockMachine(session, LockType.Write);
@BeforeMethod IMachine mutable = session.getMachine();
protected void setupManager() { mutable.attachDevice(controllerIDE, 1, 1, DeviceType.DVD, distroMedium);
manager.connect(endpoint.toASCIIString(), identity, credential); mutable.saveSettings(); // write settings to xml
} session.unlockMachine();
assertEquals(distroMedium.getId().equals(""), false);
@AfterMethod }
protected void disconnectAndClenaupManager() throws RemoteException,
MalformedURLException { @Test(dependsOnMethods = "testAttachGuestAdditions")
manager.disconnect(); public void testStartVirtualMachine() throws InterruptedException {
manager.cleanup(); IMachine machine = manager.getVBox().findMachine(vmName);
} ISession session = manager.getSessionObject();
launchVMProcess(machine, session);
@Test assertEquals(machine.getState(), MachineState.Running);
public void testCreateVirtualMachine() { try {
IMachine newVM = manager.getVBox().createMachine(settingsFile, vmName, Thread.sleep(5000);
osTypeId, vmId, forceOverwrite); } catch (InterruptedException e) {
manager.getVBox().registerMachine(newVM); propagate(e);
assertNotNull(newVM.getName()); }
}
sendKeyboardSequence(keyboardSequence);
@Test(dependsOnMethods = "testCreateVirtualMachine")
public void testChangeRAM() { // test if the sshd on the guest is ready and meanwhile apply AdminAccess
Long memorySize = new Long(1024); boolean sshDeamonIsRunning = false;
ISession session = manager.getSessionObject(); while (!sshDeamonIsRunning) {
IMachine machine = manager.getVBox().findMachine(vmName); try {
machine.lockMachine(session, LockType.Write); AdminAccess.standard().init(new DefaultConfiguration()).render(OsFamily.UNIX);
IMachine mutable = session.getMachine(); if (runScriptOnNode(guestId, "id").getExitCode() == 0)
mutable.setMemorySize(memorySize); sshDeamonIsRunning = true;
mutable.saveSettings(); } catch (SshException e) {
session.unlockMachine(); System.err.println("connection reset");
assertEquals(manager.getVBox().findMachine(vmName).getMemorySize(), }
memorySize); }
} }
@Test(dependsOnMethods = "testChangeRAM") @Test(dependsOnMethods = "testStartVirtualMachine")
public void testCreateIdeController() { public void testConfigureGuestAdditions() {
ISession session = manager.getSessionObject(); // TODO generalize
IMachine machine = manager.getVBox().findMachine(vmName); if (isUbuntu(guestId)) {
machine.lockMachine(session, LockType.Write); /*
IMachine mutable = session.getMachine(); * runScriptOnNode(guestId, "m-a prepare -i"); runScriptOnNode(guestId,
mutable.addStorageController(controllerIDE, StorageBus.IDE); * "mount -o loop /dev/dvd /media/cdrom"); runScriptOnNode(guestId,
mutable.saveSettings(); * "sh /media/cdrom/VBoxLinuxAdditions.run");
session.unlockMachine(); *
assertEquals(manager.getVBox().findMachine(vmName) * runScriptOnNode(guestId, "/etc/init.d/vboxadd setup");
.getStorageControllers().size(), 1); */
} runScriptOnNode(guestId, "rm /etc/udev/rules.d/70-persistent-net.rules");
runScriptOnNode(guestId, "mkdir /etc/udev/rules.d/70-persistent-net.rules");
@Test(dependsOnMethods = "testCreateIdeController") runScriptOnNode(guestId, "rm -rf /dev/.udev/");
public void testAttachIsoDvd() { runScriptOnNode(guestId, "rm /lib/udev/rules.d/75-persistent-net-generator.rules");
IMedium distroMedium = manager.getVBox().openMedium( }
workingDir + "/" + distroIsoName, DeviceType.DVD, }
AccessMode.ReadOnly, forceOverwrite);
@Test(dependsOnMethods = "testConfigureGuestAdditions")
ISession session = manager.getSessionObject(); public void testStopVirtualMachine() {
IMachine machine = manager.getVBox().findMachine(vmName); IMachine machine = manager.getVBox().findMachine(vmName);
machine.lockMachine(session, LockType.Write); powerDownMachine(machine);
IMachine mutable = session.getMachine(); assertEquals(machine.getState(), MachineState.PoweredOff);
mutable.attachDevice(controllerIDE, 0, 0, DeviceType.DVD, distroMedium); }
mutable.saveSettings();
session.unlockMachine(); @Test(dependsOnMethods = "testStopVirtualMachine")
assertEquals(distroMedium.getId().equals(""), false); public void testChangeNICtoBridged() {
} ISession session = manager.getSessionObject();
IMachine adminNode = manager.getVBox().findMachine(vmName);
@Test(dependsOnMethods = "testAttachIsoDvd") adminNode.lockMachine(session, LockType.Write);
public void testCreateAndAttachHardDisk() throws InterruptedException { IMachine mutable = session.getMachine();
IMedium hd = null; // network
if (new File(adminDisk).exists()) { String hostInterface = null;
new File(adminDisk).delete(); String command = "vboxmanage list bridgedifs";
} try {
hd = manager.getVBox().createHardDisk(diskFormat, adminDisk); Process child = Runtime.getRuntime().exec(command);
long size = 4L * 1024L * 1024L * 1024L - 4L; BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(child.getInputStream()));
IProgress progress = hd.createBaseStorage(new Long(size), new Long( String line = "";
MediumVariant.STANDARD.ordinal())); boolean found = false;
ISession session = manager.getSessionObject(); while ((line = bufferedReader.readLine()) != null && !found) {
IMachine machine = manager.getVBox().findMachine(vmName); if (line.split(":")[0].contains("Name")) {
machine.lockMachine(session, LockType.Write); hostInterface = line.split(":")[1];
IMachine mutable = session.getMachine(); }
mutable.attachDevice(controllerIDE, 0, 1, DeviceType.HardDisk, hd); if (line.split(":")[0].contains("Status") && line.split(":")[1].contains("Up")) {
mutable.saveSettings(); System.out.println("bridge: " + hostInterface.trim());
session.unlockMachine(); found = true;
assertEquals(hd.getId().equals(""), false); }
} }
} catch (IOException e) {
@Test(dependsOnMethods = "testCreateAndAttachHardDisk") // TODO Auto-generated catch block
public void testConfigureNIC() { e.printStackTrace();
ISession session = manager.getSessionObject(); }
IMachine machine = manager.getVBox().findMachine(vmName);
machine.lockMachine(session, LockType.Write); mutable.getNetworkAdapter(new Long(0)).setAttachmentType(NetworkAttachmentType.Bridged);
IMachine mutable = session.getMachine(); mutable.getNetworkAdapter(new Long(0)).setAdapterType(NetworkAdapterType.Am79C973);
mutable.getNetworkAdapter(new Long(0)).setMACAddress(manager.getVBox().getHost().generateMACAddress());
// NAT mutable.getNetworkAdapter(new Long(0)).setBridgedInterface(hostInterface.trim());
mutable.getNetworkAdapter(new Long(0)).setAttachmentType( mutable.getNetworkAdapter(new Long(0)).setEnabled(true);
NetworkAttachmentType.NAT); mutable.saveSettings();
machine.getNetworkAdapter(new Long(0)) session.unlockMachine();
.getNatDriver() }
.addRedirect("guestssh", NATProtocol.TCP, "127.0.0.1", 2222,
"", 22); @Test(dependsOnMethods = "testChangeNICtoBridged")
mutable.getNetworkAdapter(new Long(0)).setEnabled(true); public void testTakeAdminNodeSnapshot() {
ISession session = manager.getSessionObject();
mutable.saveSettings(); IMachine adminNode = manager.getVBox().findMachine(vmName);
session.unlockMachine(); adminNode.lockMachine(session, LockType.Write);
} if (adminNode.getCurrentSnapshot() == null
|| !adminNode.getCurrentSnapshot().getDescription().equals(snapshotDescription)) {
@Test(dependsOnMethods = "testConfigureNIC") manager.getSessionObject().getConsole().takeSnapshot(adminNode.getId(), snapshotDescription);
public void testAttachGuestAdditions() { }
ISession session = manager.getSessionObject(); session.unlockMachine();
IMachine machine = manager.getVBox().findMachine(vmName); }
IMedium distroMedium = manager.getVBox().openMedium(guestAdditionsDvd, DeviceType.DVD, /**
AccessMode.ReadOnly, forceOverwrite); *
machine.lockMachine(session, LockType.Write); * @param machine
IMachine mutable = session.getMachine(); * @param session
mutable.attachDevice(controllerIDE, 1, 1, DeviceType.DVD, distroMedium); */
mutable.saveSettings(); // write settings to xml public void launchVMProcess(IMachine machine, ISession session) {
session.unlockMachine(); IProgress prog = machine.launchVMProcess(session, "gui", "");
assertEquals(distroMedium.getId().equals(""), false); prog.waitForCompletion(-1);
} session.unlockMachine();
}
@Test(dependsOnMethods = "testAttachGuestAdditions") /**
public void testStartVirtualMachine() throws InterruptedException { * @param machine
IMachine machine = manager.getVBox().findMachine(vmName); */
ISession session = manager.getSessionObject(); public void powerDownMachine(IMachine machine) {
launchVMProcess(machine, session); try {
assertEquals(machine.getState(), MachineState.Running); ISession machineSession = manager.openMachineSession(machine);
try { IProgress progress = machineSession.getConsole().powerDown();
Thread.sleep(5000); progress.waitForCompletion(-1);
} catch (InterruptedException e) { machineSession.unlockMachine();
propagate(e);
} while (!machine.getSessionState().equals(SessionState.Unlocked)) {
try {
sendKeyboardSequence(keyboardSequence); System.out.println("waiting for unlocking session - session state: " + machine.getSessionState());
Thread.sleep(1000);
// test if the sshd on the guest is ready and meanwhile apply AdminAccess } catch (InterruptedException e) {
boolean sshDeamonIsRunning = false; }
while(!sshDeamonIsRunning) { }
try {
AdminAccess.standard().init(new DefaultConfiguration()).render(OsFamily.UNIX); } catch (Exception e) {
if(runScriptOnNode(guestId, "id").getExitCode() == 0) e.printStackTrace();
sshDeamonIsRunning = true; e.printStackTrace();
} catch(SshException e) { }
System.err.println("connection reset"); }
}
} }
}
@Test(dependsOnMethods = "testStartVirtualMachine")
public void testConfigureGuestAdditions() {
// TODO generalize
if(isUbuntu(guestId)) {
/*
runScriptOnNode(guestId,
"m-a prepare -i");
runScriptOnNode(guestId,
"mount -o loop /dev/dvd /media/cdrom");
runScriptOnNode(guestId,
"sh /media/cdrom/VBoxLinuxAdditions.run");
runScriptOnNode(guestId, "/etc/init.d/vboxadd setup");
*/
runScriptOnNode(guestId, "rm /etc/udev/rules.d/70-persistent-net.rules");
runScriptOnNode(guestId, "mkdir /etc/udev/rules.d/70-persistent-net.rules");
runScriptOnNode(guestId, "rm -rf /dev/.udev/");
runScriptOnNode(guestId, "rm /lib/udev/rules.d/75-persistent-net-generator.rules");
}
}
@Test(dependsOnMethods = "testConfigureGuestAdditions")
public void testStopVirtualMachine() {
IMachine machine = manager.getVBox().findMachine(vmName);
powerDownMachine(machine);
assertEquals(machine.getState(), MachineState.PoweredOff);
}
@Test(dependsOnMethods = "testStopVirtualMachine")
public void testChangeNICtoBridged() {
ISession session = manager.getSessionObject();
IMachine adminNode = manager.getVBox().findMachine(vmName);
adminNode.lockMachine(session, LockType.Write);
IMachine mutable = session.getMachine();
// network
String hostInterface = null;
String command = "vboxmanage list bridgedifs";
try {
Process child = Runtime.getRuntime().exec(command);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(child.getInputStream()));
String line = "";
boolean found = false;
while ((line = bufferedReader.readLine()) != null && !found) {
if (line.split(":")[0].contains("Name")) {
hostInterface = line.split(":")[1];
}
if (line.split(":")[0].contains("Status") && line.split(":")[1].contains("Up")) {
System.out.println("bridge: " + hostInterface.trim());
found = true;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mutable.getNetworkAdapter(new Long(0)).setAttachmentType(NetworkAttachmentType.Bridged);
mutable.getNetworkAdapter(new Long(0)).setAdapterType(NetworkAdapterType.Am79C973);
mutable.getNetworkAdapter(new Long(0)).setMACAddress(manager.getVBox().getHost().generateMACAddress());
mutable.getNetworkAdapter(new Long(0)).setBridgedInterface(hostInterface.trim());
mutable.getNetworkAdapter(new Long(0)).setEnabled(true);
mutable.saveSettings();
session.unlockMachine();
}
@Test(dependsOnMethods = "testChangeNICtoBridged")
public void testTakeAdminNodeSnapshot() {
ISession session = manager.getSessionObject();
IMachine adminNode = manager.getVBox().findMachine(vmName);
adminNode.lockMachine(session, LockType.Write);
if(adminNode.getCurrentSnapshot() == null || !adminNode.getCurrentSnapshot().getDescription().equals(snapshotDescription)) {
manager.getSessionObject().getConsole().takeSnapshot(adminNode.getId(), snapshotDescription);
}
session.unlockMachine();
}
@AfterClass
void stopVboxWebServer() throws IOException {
runScriptOnNode(guestId, "pidof vboxwebsrv | xargs kill");
}
protected ExecResponse runScriptOnNode(String nodeId, String command,
RunScriptOptions options) {
ExecResponse toReturn = context.getComputeService().runScriptOnNode(
nodeId, command, options);
assert toReturn.getExitCode() == 0 : toReturn;
return toReturn;
}
protected ExecResponse runScriptOnNode(String nodeId, String command) {
return runScriptOnNode(nodeId, command, wrapInInitScript(false));
}
private File downloadFileUnlessPresent(URI sourceURL,
String destinationDir, String filename) throws Exception {
File iso = new File(destinationDir, filename);
if (!iso.exists()) {
InputStream is = context.utils().http().get(sourceURL);
checkNotNull(is, "%s not found", sourceURL);
try {
ByteStreams.copy(is, new FileOutputStream(iso));
} finally {
Closeables.closeQuietly(is);
}
}
return iso;
}
private void sendKeyboardSequence(String keyboardSequence)
throws InterruptedException {
String[] sequenceSplited = keyboardSequence.split(" ");
StringBuilder sb = new StringBuilder();
for (String line : sequenceSplited) {
String converted = stringToKeycode(line);
for (String word : converted.split(" ")) {
sb.append("vboxmanage controlvm " + vmName
+ " keyboardputscancode " + word + "; ");
if (word.endsWith(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<Enter>"))) {
runScriptOnNode(hostId, sb.toString(), runAsRoot(false)
.wrapInInitScript(false));
sb.delete(0, sb.length()-1);
}
if (word.endsWith(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<Return>"))) {
runScriptOnNode(hostId, sb.toString(), runAsRoot(false)
.wrapInInitScript(false));
sb.delete(0, sb.length()-1);
}
}
}
}
private String stringToKeycode(String s) {
StringBuilder keycodes = new StringBuilder();
if (s.startsWith("<")) {
String[] specials = s.split("<");
for (int i = 1; i < specials.length; i++) {
keycodes.append(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP
.get("<" + specials[i]) + " ");
}
return keycodes.toString();
}
int i = 0;
while (i < s.length()) {
String digit = s.substring(i, i + 1);
String hex = KeyboardScancodes.NORMAL_KEYBOARD_BUTTON_MAP
.get(digit);
keycodes.append(hex + " ");
if (i != 0 && i % 14 == 0)
keycodes.append(" ");
i++;
}
keycodes.append(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP
.get("<Spacebar>") + " ");
return keycodes.toString();
}
/**
*
* @param machine
* @param session
*/
private void launchVMProcess(IMachine machine, ISession session) {
IProgress prog = machine.launchVMProcess(session, "gui", "");
prog.waitForCompletion(-1);
session.unlockMachine();
}
/**
* @param machine
*/
private void powerDownMachine(IMachine machine) {
try {
ISession machineSession = manager.openMachineSession(machine);
IProgress progress = machineSession.getConsole().powerDown();
progress.waitForCompletion(-1);
machineSession.unlockMachine();
while (!machine.getSessionState().equals(SessionState.Unlocked)) {
try {
System.out
.println("waiting for unlocking session - session state: "
+ machine.getSessionState());
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
} catch (Exception e) {
e.printStackTrace();
e.printStackTrace();
}
}
}

View File

@ -20,42 +20,23 @@ package org.jclouds.virtualbox.experiment;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot; import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.rmi.RemoteException; import java.rmi.RemoteException;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.util.log.Log;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ExecResponse; import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.options.RunScriptOptions; import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.domain.Credentials;
import org.jclouds.encryption.bouncycastle.config.BouncyCastleCryptoModule;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect; import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.scriptbuilder.domain.OsFamily;
import org.jclouds.scriptbuilder.statements.login.AdminAccess;
import org.jclouds.scriptbuilder.statements.login.DefaultConfiguration;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshException;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeMethod;
@ -67,317 +48,241 @@ import org.virtualbox_4_1.IProgress;
import org.virtualbox_4_1.ISession; import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.LockType; import org.virtualbox_4_1.LockType;
import org.virtualbox_4_1.MachineState; import org.virtualbox_4_1.MachineState;
import org.virtualbox_4_1.NetworkAdapterType;
import org.virtualbox_4_1.NetworkAttachmentType; import org.virtualbox_4_1.NetworkAttachmentType;
import org.virtualbox_4_1.SessionState; import org.virtualbox_4_1.SessionState;
import org.virtualbox_4_1.VirtualBoxManager; import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.inject.Injector;
import com.google.inject.Module;
@Test(groups = "live", testName = "virtualbox.VirtualboxLiveTest") @Test(groups = "live", testName = "virtualbox.VirtualboxLiveTest")
public class VirtualboxLiveTest { public class VirtualboxLiveTest {
protected String provider = "virtualbox"; private String provider = "virtualbox";
protected String identity; private String identity;
protected String credential; private String credential;
protected URI endpoint; private URI endpoint;
protected String apiversion; private String vmName;
protected String vmName;
VirtualBoxManager manager = VirtualBoxManager.createInstance(""); private VirtualBoxManager manager = VirtualBoxManager.createInstance("");
protected Injector injector; private String settingsFile;
protected Predicate<IPSocket> socketTester; private String osTypeId;
protected SshClient.Factory sshFactory; private String vmId;
private boolean forceOverwrite;
private int numberOfVirtualMachine;
private ComputeServiceContext context;
protected String osUsername; private String hostId = "host";
protected String osPassword; private String adminNodeName;
protected String controller;
protected String diskFormat;
protected String settingsFile; private Logger logger() {
protected String osTypeId; return context.utils().loggerFactory().getLogger("jclouds.compute");
protected String vmId; }
protected boolean forceOverwrite;
protected String workingDir;
protected String clonedDiskPath;
protected String format = "vdi";
protected int numberOfVirtualMachine;
protected String originalDisk;
private String clonedDisk;
private ComputeServiceContext context;
private String hostId = "host"; private void setupCredentials() {
private String guestId = "guest"; identity = System.getProperty("test." + provider + ".identity", "administrator");
private String majorVersion; credential = System.getProperty("test." + provider + ".credential", "12345");
private String minorVersion; endpoint = URI.create(System.getProperty("test." + provider + ".endpoint", "http://localhost:18083/"));
private String apiVersion; }
private String adminNodeName;
private String snapshotDescription;
private String originalDiskPath;
protected Logger logger() { private void setupConfigurationProperties() {
return context.utils().loggerFactory().getLogger("jclouds.compute"); // VBOX
} settingsFile = null;
osTypeId = System.getProperty("test." + provider + ".osTypeId", "");
vmId = System.getProperty("test." + provider + ".vmId", null);
forceOverwrite = true;
// OS specific information
adminNodeName = System.getProperty("test." + provider + ".adminnodename", "jclouds-virtualbox-kickstart-admin");
vmName = checkNotNull(System.getProperty("test." + provider + ".vmname", "jclouds-virtualbox-node"));
numberOfVirtualMachine = Integer.parseInt(checkNotNull(System.getProperty("test." + provider
+ ".numberOfVirtualMachine", "1")));
}
protected void setupCredentials() { @BeforeGroups(groups = "live")
identity = System.getProperty("test." + provider + ".identity", public void setupClient() throws Exception {
"administrator"); context = TestUtils.computeServiceForLocalhostAndGuest();
credential = System.getProperty("test." + provider + ".credential", setupCredentials();
"12345"); setupConfigurationProperties();
endpoint = URI.create(System.getProperty("test." + provider if (!new InetSocketAddressConnect().apply(new IPSocket(endpoint.getHost(), endpoint.getPort())))
+ ".endpoint", "http://localhost:18083/")); startupVboxWebServer();
apiVersion = System.getProperty("test." + provider + ".apiversion", }
"4.1.2r73507");
majorVersion = Iterables.get(Splitter.on('r').split(apiVersion), 0);
minorVersion = Iterables.get(Splitter.on('r').split(apiVersion), 1);
}
protected void setupConfigurationProperties() { @BeforeMethod
// VBOX public void setupManager() throws RemoteException, MalformedURLException {
settingsFile = null; manager.connect(endpoint.toASCIIString(), identity, credential);
osTypeId = System.getProperty("test." + provider + ".osTypeId", ""); }
vmId = System.getProperty("test." + provider + ".vmId", null);
forceOverwrite = true;
// OS specific information
adminNodeName = System.getProperty("test." + provider + ".adminnodename", "jclouds-virtualbox-kickstart-admin");
vmName = checkNotNull(System.getProperty("test." + provider + ".vmname", "jclouds-virtualbox-node"));
osUsername = System.getProperty("test." + provider + ".osusername", "toor");
osPassword = System.getProperty("test." + provider + ".ospassword", "password");
controller = System.getProperty("test." + provider + ".controller", "IDE Controller");
diskFormat = System.getProperty("test." + provider + ".diskformat", "");
workingDir = System.getProperty("user.home") @AfterMethod
+ File.separator public void disconnectAndClenaupManager() throws RemoteException, MalformedURLException {
+ System.getProperty("test." + provider + ".workingDir", manager.disconnect();
"jclouds-virtualbox-test"); manager.cleanup();
}
originalDisk = System.getProperty("test." + provider + ".originalDisk", "admin.vdi"); @Test
originalDiskPath = workingDir + File.separator + originalDisk; public void testStartAndValidateVirtualMachines() throws InterruptedException {
for (int i = 1; i < numberOfVirtualMachine + 1; i++) {
createVirtualMachine(i);
}
}
clonedDisk = System.getProperty("test." + provider + ".clonedDisk", "clone.vdi"); private void createVirtualMachine(int i) throws InterruptedException {
clonedDiskPath = workingDir + File.separator + clonedDisk; String instanceName = vmName + "_" + i;
numberOfVirtualMachine = Integer.parseInt(checkNotNull(System.getProperty("test." + provider IMachine adminNode = manager.getVBox().findMachine(adminNodeName);
+ ".numberOfVirtualMachine", "1")));
}
@BeforeGroups(groups = "live") IMachine clonedVM = manager.getVBox().createMachine(settingsFile, instanceName, osTypeId, vmId, forceOverwrite);
protected void setupClient() throws Exception { List<CloneOptions> options = new ArrayList<CloneOptions>();
context = TestUtils.computeServiceForLocalhostAndGuest(); options.add(CloneOptions.Link);
socketTester = new RetryablePredicate<IPSocket>( IProgress progress = adminNode.getCurrentSnapshot().getMachine().cloneTo(clonedVM, CloneMode.MachineState,
new InetSocketAddressConnect(), 130, 10, TimeUnit.SECONDS); options);
setupCredentials();
setupConfigurationProperties();
if (!new InetSocketAddressConnect().apply(new IPSocket(endpoint.getHost(), endpoint.getPort())))
startupVboxWebServer();
}
if (progress.getCompleted())
logger().debug("clone done");
@BeforeMethod manager.getVBox().registerMachine(clonedVM);
protected void setupManager() throws RemoteException, MalformedURLException {
manager.connect(endpoint.toASCIIString(), identity, credential);
}
@AfterMethod ISession session = manager.getSessionObject();
protected void disconnectAndClenaupManager() throws RemoteException, MalformedURLException { clonedVM.lockMachine(session, LockType.Write);
manager.disconnect(); IMachine mutable = session.getMachine();
manager.cleanup();
}
@Test mutable.getNetworkAdapter(new Long(0)).setAttachmentType(NetworkAttachmentType.Bridged);
public void testStartAndValidateVirtualMachines() throws InterruptedException { String mac_address = manager.getVBox().getHost().generateMACAddress();
for (int i = 1; i < numberOfVirtualMachine + 1; i++) { System.out.println("mac_address " + mac_address);
createVirtualMachine(i); mutable.getNetworkAdapter(new Long(0)).setMACAddress(mac_address);
}
}
private void createVirtualMachine(int i) throws InterruptedException { if (isOSX(hostId)) {
String instanceName = vmName + "_" + i; mutable.getNetworkAdapter(new Long(0)).setBridgedInterface(findBridgeInUse());
IMachine adminNode = manager.getVBox().findMachine(adminNodeName); } else {
mutable.getNetworkAdapter(new Long(0)).setBridgedInterface("virbr0");
IMachine clonedVM = manager.getVBox().createMachine(settingsFile, instanceName, osTypeId, vmId, forceOverwrite); }
List<CloneOptions> options = new ArrayList<CloneOptions>(); mutable.getNetworkAdapter(new Long(0)).setEnabled(true);
options.add(CloneOptions.Link); mutable.saveSettings();
IProgress progress = adminNode.getCurrentSnapshot().getMachine().cloneTo(clonedVM,CloneMode.MachineState , options); session.unlockMachine();
if(progress.getCompleted())
logger().debug("clone done");
manager.getVBox().registerMachine(clonedVM); System.out.println("\nLaunching VM named " + clonedVM.getName() + " ...");
launchVMProcess(clonedVM, manager.getSessionObject());
ISession session = manager.getSessionObject();
clonedVM.lockMachine(session, LockType.Write);
IMachine mutable = session.getMachine();
mutable.getNetworkAdapter(new Long(0)).setAttachmentType(NetworkAttachmentType.Bridged); clonedVM = manager.getVBox().findMachine(instanceName);
String mac_address = manager.getVBox().getHost().generateMACAddress(); String macAddressOfClonedVM = clonedVM.getNetworkAdapter(new Long(0)).getMACAddress();
System.out.println("mac_address " + mac_address);
mutable.getNetworkAdapter(new Long(0)).setMACAddress(mac_address);
if(isOSX(hostId)) {
mutable.getNetworkAdapter(new Long(0)).setBridgedInterface(findBridgeInUse());
} else {
mutable.getNetworkAdapter(new Long(0)).setBridgedInterface("virbr0");
}
mutable.getNetworkAdapter(new Long(0)).setEnabled(true);
mutable.saveSettings();
session.unlockMachine();
System.out.println("\nLaunching VM named " + clonedVM.getName() + " ..."); int offset = 0, step = 2;
launchVMProcess(clonedVM, manager.getSessionObject()); for (int j = 1; j <= 5; j++) {
macAddressOfClonedVM = new StringBuffer(macAddressOfClonedVM).insert(j * step + offset, ":").toString()
clonedVM = manager.getVBox().findMachine(instanceName); .toLowerCase();
String macAddressOfClonedVM = clonedVM.getNetworkAdapter(new Long(0)).getMACAddress(); offset++;
}
int offset = 0, step = 2; String simplifiedMacAddressOfClonedVM = macAddressOfClonedVM;
for (int j = 1; j <= 5; j++) {
macAddressOfClonedVM = new StringBuffer(macAddressOfClonedVM).insert(j * step + offset, ":").toString().toLowerCase();
offset++;
}
String simplifiedMacAddressOfClonedVM = macAddressOfClonedVM;
if(isOSX(hostId)) {
if(simplifiedMacAddressOfClonedVM.contains("00"))
simplifiedMacAddressOfClonedVM = new StringBuffer(simplifiedMacAddressOfClonedVM).delete(simplifiedMacAddressOfClonedVM.indexOf("00"), simplifiedMacAddressOfClonedVM.indexOf("00") + 1).toString();
if(simplifiedMacAddressOfClonedVM.contains("0"))
if(simplifiedMacAddressOfClonedVM.indexOf("0") + 1 != ':' && simplifiedMacAddressOfClonedVM.indexOf("0") - 1 != ':')
simplifiedMacAddressOfClonedVM = new StringBuffer(simplifiedMacAddressOfClonedVM).delete(simplifiedMacAddressOfClonedVM.indexOf("0"), simplifiedMacAddressOfClonedVM.indexOf("0") + 1).toString();
}
// TODO as we don't know the hostname (nor the IP address) of the cloned machine we can't use "ssh check" to check that the machine is up and running
// we need to find another way to check the machine is up: only at that stage a new IP would be used by the machine and arp will answer correctly if (isOSX(hostId)) {
Thread.sleep(35000); // TODO to be removed asap if (simplifiedMacAddressOfClonedVM.contains("00"))
runScriptOnNode(hostId, "for i in $(seq 1 254) ; do ping -c 1 -t 1 192.168.122.$i & done", runAsRoot(false).wrapInInitScript(false)); simplifiedMacAddressOfClonedVM = new StringBuffer(simplifiedMacAddressOfClonedVM).delete(
String arpLine = runScriptOnNode(hostId, "arp -an | grep " + simplifiedMacAddressOfClonedVM, runAsRoot(false).wrapInInitScript(false)).getOutput(); simplifiedMacAddressOfClonedVM.indexOf("00"), simplifiedMacAddressOfClonedVM.indexOf("00") + 1)
String ipAddress = arpLine.substring(arpLine.indexOf("(") + 1, arpLine.indexOf(")")); .toString();
System.out.println("IP address " + ipAddress);
// TODO we need to redifine guest node at runtinme: in particular hostnmane and ssh port
//runScriptOnNode(guestId, "echo ciao");
}
/** if (simplifiedMacAddressOfClonedVM.contains("0"))
if (simplifiedMacAddressOfClonedVM.indexOf("0") + 1 != ':'
&& simplifiedMacAddressOfClonedVM.indexOf("0") - 1 != ':')
simplifiedMacAddressOfClonedVM = new StringBuffer(simplifiedMacAddressOfClonedVM).delete(
simplifiedMacAddressOfClonedVM.indexOf("0"), simplifiedMacAddressOfClonedVM.indexOf("0") + 1)
.toString();
}
// TODO as we don't know the hostname (nor the IP address) of the cloned machine we can't use
// "ssh check" to check that the machine is up and running
// we need to find another way to check the machine is up: only at that stage a new IP would
// be used by the machine and arp will answer correctly
Thread.sleep(35000); // TODO to be removed asap
runScriptOnNode(hostId, "for i in $(seq 1 254) ; do ping -c 1 -t 1 192.168.122.$i & done", runAsRoot(false)
.wrapInInitScript(false));
String arpLine = runScriptOnNode(hostId, "arp -an | grep " + simplifiedMacAddressOfClonedVM,
runAsRoot(false).wrapInInitScript(false)).getOutput();
String ipAddress = arpLine.substring(arpLine.indexOf("(") + 1, arpLine.indexOf(")"));
System.out.println("IP address " + ipAddress);
// TODO we need to redifine guest node at runtinme: in particular hostnmane and ssh port
// runScriptOnNode(guestId, "echo ciao");
}
/**
* *
*/ */
protected String findBridgeInUse() { private String findBridgeInUse() {
// network // network
String hostInterface = null; String hostInterface = null;
String command = "vboxmanage list bridgedifs"; String command = "vboxmanage list bridgedifs";
try { try {
Process child = Runtime.getRuntime().exec(command); Process child = Runtime.getRuntime().exec(command);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(child.getInputStream())); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(child.getInputStream()));
String line = ""; String line = "";
boolean found = false; boolean found = false;
while ((line = bufferedReader.readLine()) != null && !found) { while ((line = bufferedReader.readLine()) != null && !found) {
System.out.println("- " + line); System.out.println("- " + line);
if (line.split(":")[0].contains("Name")) { if (line.split(":")[0].contains("Name")) {
hostInterface = line.substring(line.indexOf(":") +1); hostInterface = line.substring(line.indexOf(":") + 1);
} }
if (line.split(":")[0].contains("Status") && line.split(":")[1].contains("Up")) { if (line.split(":")[0].contains("Status") && line.split(":")[1].contains("Up")) {
found = true; found = true;
} }
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
return hostInterface.trim(); return hostInterface.trim();
} }
private void launchVMProcess(IMachine machine, ISession session) { private void launchVMProcess(IMachine machine, ISession session) {
IProgress prog = machine.launchVMProcess(session, "gui", ""); IProgress prog = machine.launchVMProcess(session, "gui", "");
prog.waitForCompletion(-1); prog.waitForCompletion(-1);
session.unlockMachine(); session.unlockMachine();
} }
protected void checkSSH(IPSocket socket) { @Test(dependsOnMethods = "testStartAndValidateVirtualMachines")
socketTester.apply(socket); public void testStopVirtualMachines() {
SshClient client = sshFactory.create(socket, new Credentials(osUsername, osPassword)); for (int i = 1; i < numberOfVirtualMachine + 1; i++) {
try { String instanceName = vmName + "_" + i;
client.connect(); IMachine machine = manager.getVBox().findMachine(instanceName);
ExecResponse exec = client.exec("touch /tmp/hello_" + System.currentTimeMillis());
exec = client.exec("echo hello");
System.out.println(exec);
assertEquals(exec.getOutput().trim(), "hello");
} finally {
if (client != null)
client.disconnect();
}
}
@Test(dependsOnMethods = "testStartAndValidateVirtualMachines") try {
public void testStopVirtualMachines() { ISession machineSession = manager.openMachineSession(machine);
for (int i = 1; i < numberOfVirtualMachine + 1; i++) { IProgress progress = machineSession.getConsole().powerDown();
String instanceName = vmName + "_" + i; progress.waitForCompletion(-1);
IMachine machine = manager.getVBox().findMachine(instanceName); machineSession.unlockMachine();
try { while (!machine.getSessionState().equals(SessionState.Unlocked)) {
ISession machineSession = manager.openMachineSession(machine); try {
IProgress progress = machineSession.getConsole().powerDown(); System.out.println("waiting for unlocking session - session state: " + machine.getSessionState());
progress.waitForCompletion(-1); Thread.sleep(1000);
machineSession.unlockMachine(); } catch (InterruptedException e) {
e.printStackTrace();
}
}
assertEquals(machine.getState(), MachineState.PoweredOff);
} catch (Exception e) {
e.printStackTrace();
}
}
}
while (!machine.getSessionState().equals(SessionState.Unlocked)) { private ExecResponse runScriptOnNode(String nodeId, String command, RunScriptOptions options) {
try { ExecResponse toReturn = context.getComputeService().runScriptOnNode(nodeId, command, options);
System.out.println("waiting for unlocking session - session state: " + machine.getSessionState()); assert toReturn.getExitCode() == 0 : toReturn;
Thread.sleep(1000); return toReturn;
} catch (InterruptedException e) { }
e.printStackTrace();
}
}
assertEquals(machine.getState(), MachineState.PoweredOff);
} catch (Exception e) {
e.printStackTrace();
}
}
}
protected ExecResponse runScriptOnNode(String nodeId, String command, private boolean isOSX(String id) {
RunScriptOptions options) { return context.getComputeService().getNodeMetadata(hostId).getOperatingSystem().getDescription().equals(
ExecResponse toReturn = context.getComputeService().runScriptOnNode( "Mac OS X");
nodeId, command, options); }
assert toReturn.getExitCode() == 0 : toReturn;
return toReturn;
}
protected ExecResponse runScriptOnNode(String nodeId, String command) { private void startupVboxWebServer() {
return runScriptOnNode(nodeId, command, wrapInInitScript(false)); logger().debug("disabling password access");
} runScriptOnNode(hostId, "VBoxManage setproperty websrvauthlibrary null", runAsRoot(false).wrapInInitScript(false));
logger().debug("starting vboxwebsrv");
String vboxwebsrv = "vboxwebsrv -t 10000 -v -b";
if (isOSX(hostId))
vboxwebsrv = "cd /Applications/VirtualBox.app/Contents/MacOS/ && " + vboxwebsrv;
protected boolean isOSX(String id) { runScriptOnNode(hostId, vboxwebsrv, runAsRoot(false).wrapInInitScript(false).blockOnPort(endpoint.getPort(), 10)
return context.getComputeService().getNodeMetadata(hostId) .blockOnComplete(false).nameTask("vboxwebsrv"));
.getOperatingSystem().getDescription().equals("Mac OS X"); }
}
protected boolean isUbuntu(String id) {
return context.getComputeService().getNodeMetadata(id)
.getOperatingSystem().getDescription().contains("ubuntu");
}
void startupVboxWebServer() {
logger().debug("disabling password access");
runScriptOnNode(hostId, "VBoxManage setproperty websrvauthlibrary null", runAsRoot(false).wrapInInitScript(false));
logger().debug("starting vboxwebsrv");
String vboxwebsrv = "vboxwebsrv -t 10000 -v -b";
if (isOSX(hostId))
vboxwebsrv = "cd /Applications/VirtualBox.app/Contents/MacOS/ && "
+ vboxwebsrv;
runScriptOnNode(
hostId,
vboxwebsrv,
runAsRoot(false).wrapInInitScript(false)
.blockOnPort(endpoint.getPort(), 10)
.blockOnComplete(false)
.nameTask("vboxwebsrv"));
}
} }

View File

@ -25,26 +25,24 @@ package org.jclouds.virtualbox.functions;
* @author Andrea Turli, Mattias Holmqvist * @author Andrea Turli, Mattias Holmqvist
*/ */
import com.google.common.collect.Iterables; import static com.google.common.base.Predicates.equalTo;
import static com.google.common.collect.Iterables.any;
import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest;
import static org.testng.Assert.assertTrue;
import java.util.Set;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest; import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import org.virtualbox_4_1.IMachine; import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.VirtualBoxManager; import org.virtualbox_4_1.VirtualBoxManager;
import java.util.Set; @Test(groups = "live", singleThreaded = true, testName = "IsoToIMachineLiveTest")
public class IsoToIMachineLiveTest extends BaseVirtualBoxClientLiveTest {
import static com.google.common.base.Predicates.equalTo;
import static com.google.common.collect.Iterables.*;
import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest;
import static org.testng.Assert.assertTrue;
@Test(groups = "live", singleThreaded = true, testName = "IsoToIMachineTest")
public class IsoToIMachineTest extends BaseVirtualBoxClientLiveTest {
private String settingsFile = null; private String settingsFile = null;
private boolean forceOverwrite = true; private boolean forceOverwrite = true;