mirror of https://github.com/apache/cloudstack.git
Refactoring the LibvirtComputingResource
- Adding LibvirtStopCommandWrapper - LibvirtRequestWrapper - 1 unit tests Refactored the RequestWrapper to make it better. - Changes also applied to the CitrixRequestWrapper
This commit is contained in:
parent
c3e8d3d047
commit
508f10527f
|
|
@ -19,14 +19,93 @@
|
|||
|
||||
package com.cloud.resource;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
|
||||
public abstract class RequestWrapper {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
protected Hashtable<Class<? extends ServerResource>, Hashtable<Class<? extends Command>, CommandWrapper>> resources = new Hashtable<Class<? extends ServerResource>, Hashtable<Class<? extends Command>, CommandWrapper>>();
|
||||
|
||||
/**
|
||||
* @param command to be executed.
|
||||
* @return an Answer for the executed command.
|
||||
*/
|
||||
public abstract Answer execute(Command command, ServerResource serverResource);
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected Hashtable<Class<? extends Command>, CommandWrapper> retrieveResource(final Command command, final Class<? extends ServerResource> resourceClass) {
|
||||
Class<? extends ServerResource> keepResourceClass = resourceClass;
|
||||
Hashtable<Class<? extends Command>, CommandWrapper> resource = resources.get(keepResourceClass);
|
||||
while (resource == null) {
|
||||
try {
|
||||
final Class<? extends ServerResource> keepResourceClass2 = (Class<? extends ServerResource>) keepResourceClass.getSuperclass();
|
||||
resource = resources.get(keepResourceClass2);
|
||||
|
||||
keepResourceClass = keepResourceClass2;
|
||||
} catch (final ClassCastException e) {
|
||||
throw new NullPointerException("No key found for '" + command.getClass() + "' in the Map!");
|
||||
}
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected CommandWrapper<Command, Answer, ServerResource> retrieveCommands(final Class<? extends Command> commandClass,
|
||||
final Hashtable<Class<? extends Command>, CommandWrapper> resourceCommands) {
|
||||
|
||||
Class<? extends Command> keepCommandClass = commandClass;
|
||||
CommandWrapper<Command, Answer, ServerResource> commandWrapper = resourceCommands.get(keepCommandClass);
|
||||
while (commandWrapper == null) {
|
||||
try {
|
||||
final Class<? extends Command> commandClass2 = (Class<? extends Command>) keepCommandClass.getSuperclass();
|
||||
|
||||
if (commandClass2 == null) {
|
||||
throw new NullPointerException("All the COMMAND hierarchy tree has been visited but no compliant key has been found for '" + commandClass + "'.");
|
||||
}
|
||||
|
||||
commandWrapper = resourceCommands.get(commandClass2);
|
||||
|
||||
keepCommandClass = commandClass2;
|
||||
} catch (final NullPointerException e) {
|
||||
// Will now traverse all the resource hierarchy. Returning null
|
||||
// is not a problem.
|
||||
// It is all being nicely checked and in case we do not have a
|
||||
// resource, an Unsupported answer will be thrown by the base
|
||||
// class.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return commandWrapper;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected CommandWrapper<Command, Answer, ServerResource> retryWhenAllFails(final Command command, final Class<? extends ServerResource> resourceClass,
|
||||
final Hashtable<Class<? extends Command>, CommandWrapper> resourceCommands) {
|
||||
|
||||
Class<? extends ServerResource> keepResourceClass = resourceClass;
|
||||
CommandWrapper<Command, Answer, ServerResource> commandWrapper = resourceCommands.get(command.getClass());
|
||||
while (commandWrapper == null) {
|
||||
// Could not find the command in the given resource, will traverse
|
||||
// the family tree.
|
||||
try {
|
||||
final Class<? extends ServerResource> resourceClass2 = (Class<? extends ServerResource>) keepResourceClass.getSuperclass();
|
||||
|
||||
if (resourceClass2 == null) {
|
||||
throw new NullPointerException("All the SERVER-RESOURCE hierarchy tree has been visited but no compliant key has been found for '" + command.getClass() + "'.");
|
||||
}
|
||||
|
||||
final Hashtable<Class<? extends Command>, CommandWrapper> resourceCommands2 = retrieveResource(command,
|
||||
(Class<? extends ServerResource>) keepResourceClass.getSuperclass());
|
||||
keepResourceClass = resourceClass2;
|
||||
|
||||
commandWrapper = retrieveCommands(command.getClass(), resourceCommands2);
|
||||
} catch (final NullPointerException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return commandWrapper;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,72 @@
|
|||
//
|
||||
// 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 com.cloud.hypervisor.kvm.resource.wrapper;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.StopCommand;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
|
||||
import com.cloud.resource.CommandWrapper;
|
||||
import com.cloud.resource.RequestWrapper;
|
||||
import com.cloud.resource.ServerResource;
|
||||
|
||||
public class LibvirtRequestWrapper extends RequestWrapper {
|
||||
|
||||
private static LibvirtRequestWrapper instance;
|
||||
|
||||
static {
|
||||
instance = new LibvirtRequestWrapper();
|
||||
}
|
||||
|
||||
private LibvirtRequestWrapper() {
|
||||
init();
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private void init() {
|
||||
// LibvirtComputingResource commands
|
||||
final Hashtable<Class<? extends Command>, CommandWrapper> linbvirtCommands = new Hashtable<Class<? extends Command>, CommandWrapper>();
|
||||
|
||||
linbvirtCommands.put(StopCommand.class, new LibvirtStopCommandWrapper());
|
||||
resources.put(LibvirtComputingResource.class, linbvirtCommands);
|
||||
}
|
||||
|
||||
public static LibvirtRequestWrapper getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes" })
|
||||
@Override
|
||||
public Answer execute(final Command command, final ServerResource serverResource) {
|
||||
final Class<? extends ServerResource> resourceClass = serverResource.getClass();
|
||||
|
||||
final Hashtable<Class<? extends Command>, CommandWrapper> resourceCommands = retrieveResource(command, resourceClass);
|
||||
|
||||
CommandWrapper<Command, Answer, ServerResource> commandWrapper = retrieveCommands(command.getClass(), resourceCommands);
|
||||
|
||||
while (commandWrapper == null) {
|
||||
//Could not find the command in the given resource, will traverse the family tree.
|
||||
commandWrapper = retryWhenAllFails(command, resourceClass, resourceCommands);
|
||||
}
|
||||
|
||||
return commandWrapper.execute(command, serverResource);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
//
|
||||
// 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 com.cloud.hypervisor.kvm.resource.wrapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.libvirt.Connect;
|
||||
import org.libvirt.Domain;
|
||||
import org.libvirt.DomainInfo.DomainState;
|
||||
import org.libvirt.LibvirtException;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.StopAnswer;
|
||||
import com.cloud.agent.api.StopCommand;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
|
||||
import com.cloud.hypervisor.kvm.resource.VifDriver;
|
||||
import com.cloud.resource.CommandWrapper;
|
||||
|
||||
public final class LibvirtStopCommandWrapper extends CommandWrapper<StopCommand, Answer, LibvirtComputingResource> {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(LibvirtStopCommandWrapper.class);
|
||||
|
||||
@Override
|
||||
public Answer execute(final StopCommand command, final LibvirtComputingResource citrixResourceBase) {
|
||||
final String vmName = command.getVmName();
|
||||
|
||||
if (command.checkBeforeCleanup()) {
|
||||
try {
|
||||
final Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
|
||||
final Domain vm = conn.domainLookupByName(command.getVmName());
|
||||
if (vm != null && vm.getInfo().state == DomainState.VIR_DOMAIN_RUNNING) {
|
||||
return new StopAnswer(command, "vm is still running on host", false);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
s_logger.debug("Failed to get vm status in case of checkboforecleanup is true", e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
final Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
|
||||
|
||||
final List<DiskDef> disks = citrixResourceBase.getDisks(conn, vmName);
|
||||
final List<InterfaceDef> ifaces = citrixResourceBase.getInterfaces(conn, vmName);
|
||||
|
||||
citrixResourceBase.destroyNetworkRulesForVM(conn, vmName);
|
||||
final String result = citrixResourceBase.stopVM(conn, vmName);
|
||||
if (result == null) {
|
||||
for (final DiskDef disk : disks) {
|
||||
citrixResourceBase.cleanupDisk(disk);
|
||||
}
|
||||
for (final InterfaceDef iface : ifaces) {
|
||||
// We don't know which "traffic type" is associated with
|
||||
// each interface at this point, so inform all vif drivers
|
||||
for (final VifDriver vifDriver : citrixResourceBase.getAllVifDrivers()) {
|
||||
vifDriver.unplug(iface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new StopAnswer(command, result, true);
|
||||
} catch (final LibvirtException e) {
|
||||
return new StopAnswer(command, e.getMessage(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -38,6 +38,7 @@ import org.apache.commons.lang.SystemUtils;
|
|||
import org.junit.Assert;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.libvirt.Connect;
|
||||
import org.libvirt.Domain;
|
||||
import org.libvirt.DomainBlockStats;
|
||||
|
|
@ -46,22 +47,29 @@ import org.libvirt.DomainInterfaceStats;
|
|||
import org.libvirt.LibvirtException;
|
||||
import org.libvirt.NodeInfo;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.cloud.agent.api.StopCommand;
|
||||
import com.cloud.agent.api.VmStatsEntry;
|
||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
|
||||
import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper;
|
||||
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
public class LibvirtComputingResourceTest {
|
||||
|
||||
@Mock
|
||||
private LibvirtComputingResource libvirtComputingResource;
|
||||
|
||||
String _hyperVisorType = "kvm";
|
||||
Random _random = new Random();
|
||||
|
||||
|
|
@ -71,28 +79,28 @@ public class LibvirtComputingResourceTest {
|
|||
|
||||
The overcommit feature has not been merged in there and thus
|
||||
only 'speed' is set.
|
||||
*/
|
||||
*/
|
||||
@Test
|
||||
public void testCreateVMFromSpecLegacy() {
|
||||
int id = _random.nextInt(65534);
|
||||
String name = "test-instance-1";
|
||||
final int id = _random.nextInt(65534);
|
||||
final String name = "test-instance-1";
|
||||
|
||||
int cpus = _random.nextInt(2) + 1;
|
||||
int speed = 1024;
|
||||
int minRam = 256 * 1024;
|
||||
int maxRam = 512 * 1024;
|
||||
final int cpus = _random.nextInt(2) + 1;
|
||||
final int speed = 1024;
|
||||
final int minRam = 256 * 1024;
|
||||
final int maxRam = 512 * 1024;
|
||||
|
||||
String os = "Ubuntu";
|
||||
final String os = "Ubuntu";
|
||||
|
||||
String vncAddr = "";
|
||||
String vncPassword = "mySuperSecretPassword";
|
||||
final String vncAddr = "";
|
||||
final String vncPassword = "mySuperSecretPassword";
|
||||
|
||||
LibvirtComputingResource lcr = new LibvirtComputingResource();
|
||||
VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, speed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
|
||||
final LibvirtComputingResource lcr = new LibvirtComputingResource();
|
||||
final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, speed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
|
||||
to.setVncAddr(vncAddr);
|
||||
to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9");
|
||||
|
||||
LibvirtVMDef vm = lcr.createVMFromSpec(to);
|
||||
final LibvirtVMDef vm = lcr.createVMFromSpec(to);
|
||||
vm.setHvsType(_hyperVisorType);
|
||||
|
||||
verifyVm(to, vm);
|
||||
|
|
@ -100,29 +108,29 @@ public class LibvirtComputingResourceTest {
|
|||
|
||||
/**
|
||||
This test verifies that CPU topology is properly set for hex-core
|
||||
*/
|
||||
*/
|
||||
@Test
|
||||
public void testCreateVMFromSpecWithTopology6() {
|
||||
int id = _random.nextInt(65534);
|
||||
String name = "test-instance-1";
|
||||
final int id = _random.nextInt(65534);
|
||||
final String name = "test-instance-1";
|
||||
|
||||
int cpus = 12;
|
||||
int minSpeed = 1024;
|
||||
int maxSpeed = 2048;
|
||||
int minRam = 256 * 1024;
|
||||
int maxRam = 512 * 1024;
|
||||
final int cpus = 12;
|
||||
final int minSpeed = 1024;
|
||||
final int maxSpeed = 2048;
|
||||
final int minRam = 256 * 1024;
|
||||
final int maxRam = 512 * 1024;
|
||||
|
||||
String os = "Ubuntu";
|
||||
final String os = "Ubuntu";
|
||||
|
||||
String vncAddr = "";
|
||||
String vncPassword = "mySuperSecretPassword";
|
||||
final String vncAddr = "";
|
||||
final String vncPassword = "mySuperSecretPassword";
|
||||
|
||||
LibvirtComputingResource lcr = new LibvirtComputingResource();
|
||||
VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
|
||||
final LibvirtComputingResource lcr = new LibvirtComputingResource();
|
||||
final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
|
||||
to.setVncAddr(vncAddr);
|
||||
to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9");
|
||||
|
||||
LibvirtVMDef vm = lcr.createVMFromSpec(to);
|
||||
final LibvirtVMDef vm = lcr.createVMFromSpec(to);
|
||||
vm.setHvsType(_hyperVisorType);
|
||||
|
||||
verifyVm(to, vm);
|
||||
|
|
@ -130,29 +138,29 @@ public class LibvirtComputingResourceTest {
|
|||
|
||||
/**
|
||||
This test verifies that CPU topology is properly set for quad-core
|
||||
*/
|
||||
*/
|
||||
@Test
|
||||
public void testCreateVMFromSpecWithTopology4() {
|
||||
int id = _random.nextInt(65534);
|
||||
String name = "test-instance-1";
|
||||
final int id = _random.nextInt(65534);
|
||||
final String name = "test-instance-1";
|
||||
|
||||
int cpus = 8;
|
||||
int minSpeed = 1024;
|
||||
int maxSpeed = 2048;
|
||||
int minRam = 256 * 1024;
|
||||
int maxRam = 512 * 1024;
|
||||
final int cpus = 8;
|
||||
final int minSpeed = 1024;
|
||||
final int maxSpeed = 2048;
|
||||
final int minRam = 256 * 1024;
|
||||
final int maxRam = 512 * 1024;
|
||||
|
||||
String os = "Ubuntu";
|
||||
final String os = "Ubuntu";
|
||||
|
||||
String vncAddr = "";
|
||||
String vncPassword = "mySuperSecretPassword";
|
||||
final String vncAddr = "";
|
||||
final String vncPassword = "mySuperSecretPassword";
|
||||
|
||||
LibvirtComputingResource lcr = new LibvirtComputingResource();
|
||||
VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
|
||||
final LibvirtComputingResource lcr = new LibvirtComputingResource();
|
||||
final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
|
||||
to.setVncAddr(vncAddr);
|
||||
to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9");
|
||||
|
||||
LibvirtVMDef vm = lcr.createVMFromSpec(to);
|
||||
final LibvirtVMDef vm = lcr.createVMFromSpec(to);
|
||||
vm.setHvsType(_hyperVisorType);
|
||||
|
||||
verifyVm(to, vm);
|
||||
|
|
@ -164,37 +172,37 @@ public class LibvirtComputingResourceTest {
|
|||
|
||||
It tests if the Agent can handle a vmSpec with overcommit
|
||||
data like minSpeed and maxSpeed in there
|
||||
*/
|
||||
*/
|
||||
@Test
|
||||
public void testCreateVMFromSpec() {
|
||||
int id = _random.nextInt(65534);
|
||||
String name = "test-instance-1";
|
||||
final int id = _random.nextInt(65534);
|
||||
final String name = "test-instance-1";
|
||||
|
||||
int cpus = _random.nextInt(2) + 1;
|
||||
int minSpeed = 1024;
|
||||
int maxSpeed = 2048;
|
||||
int minRam = 256 * 1024;
|
||||
int maxRam = 512 * 1024;
|
||||
final int cpus = _random.nextInt(2) + 1;
|
||||
final int minSpeed = 1024;
|
||||
final int maxSpeed = 2048;
|
||||
final int minRam = 256 * 1024;
|
||||
final int maxRam = 512 * 1024;
|
||||
|
||||
String os = "Ubuntu";
|
||||
final String os = "Ubuntu";
|
||||
|
||||
String vncAddr = "";
|
||||
String vncPassword = "mySuperSecretPassword";
|
||||
final String vncAddr = "";
|
||||
final String vncPassword = "mySuperSecretPassword";
|
||||
|
||||
LibvirtComputingResource lcr = new LibvirtComputingResource();
|
||||
VirtualMachineTO to =
|
||||
new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
|
||||
final LibvirtComputingResource lcr = new LibvirtComputingResource();
|
||||
final VirtualMachineTO to =
|
||||
new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
|
||||
to.setVncAddr(vncAddr);
|
||||
to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9");
|
||||
|
||||
LibvirtVMDef vm = lcr.createVMFromSpec(to);
|
||||
final LibvirtVMDef vm = lcr.createVMFromSpec(to);
|
||||
vm.setHvsType(_hyperVisorType);
|
||||
|
||||
verifyVm(to, vm);
|
||||
}
|
||||
|
||||
private void verifyVm(VirtualMachineTO to, LibvirtVMDef vm) {
|
||||
Document domainDoc = parse(vm.toString());
|
||||
private void verifyVm(final VirtualMachineTO to, final LibvirtVMDef vm) {
|
||||
final Document domainDoc = parse(vm.toString());
|
||||
assertXpath(domainDoc, "/domain/@type", vm.getHvsType());
|
||||
assertXpath(domainDoc, "/domain/name/text()", to.getName());
|
||||
assertXpath(domainDoc, "/domain/uuid/text()", to.getUuid());
|
||||
|
|
@ -246,7 +254,7 @@ public class LibvirtComputingResourceTest {
|
|||
try {
|
||||
Assert.assertNotNull(XPathFactory.newInstance().newXPath()
|
||||
.evaluate(xPathExpr, doc, XPathConstants.NODE));
|
||||
} catch (XPathExpressionException e) {
|
||||
} catch (final XPathExpressionException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
|
@ -256,7 +264,7 @@ public class LibvirtComputingResourceTest {
|
|||
try {
|
||||
Assert.assertEquals(expected, XPathFactory.newInstance().newXPath()
|
||||
.evaluate(xPathExpr, doc));
|
||||
} catch (XPathExpressionException e) {
|
||||
} catch (final XPathExpressionException e) {
|
||||
Assert.fail("Could not evaluate xpath" + xPathExpr + ":"
|
||||
+ e.getMessage());
|
||||
}
|
||||
|
|
@ -267,18 +275,18 @@ public class LibvirtComputingResourceTest {
|
|||
//this test is only working on linux because of the loopback interface name
|
||||
//also the tested code seems to work only on linux
|
||||
Assume.assumeTrue(SystemUtils.IS_OS_LINUX);
|
||||
Pair<Double, Double> stats = LibvirtComputingResource.getNicStats("lo");
|
||||
final Pair<Double, Double> stats = LibvirtComputingResource.getNicStats("lo");
|
||||
assertNotNull(stats);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUUID() {
|
||||
String uuid = "1";
|
||||
LibvirtComputingResource lcr = new LibvirtComputingResource();
|
||||
final LibvirtComputingResource lcr = new LibvirtComputingResource();
|
||||
uuid = lcr.getUuid(uuid);
|
||||
Assert.assertTrue(!uuid.equals("1"));
|
||||
|
||||
String oldUuid = UUID.randomUUID().toString();
|
||||
final String oldUuid = UUID.randomUUID().toString();
|
||||
uuid = oldUuid;
|
||||
uuid = lcr.getUuid(uuid);
|
||||
Assert.assertTrue(uuid.equals(oldUuid));
|
||||
|
|
@ -288,12 +296,12 @@ public class LibvirtComputingResourceTest {
|
|||
|
||||
@Test
|
||||
public void testGetVmStat() throws LibvirtException {
|
||||
Connect connect = Mockito.mock(Connect.class);
|
||||
Domain domain = Mockito.mock(Domain.class);
|
||||
DomainInfo domainInfo = new DomainInfo();
|
||||
final Connect connect = Mockito.mock(Connect.class);
|
||||
final Domain domain = Mockito.mock(Domain.class);
|
||||
final DomainInfo domainInfo = new DomainInfo();
|
||||
Mockito.when(domain.getInfo()).thenReturn(domainInfo);
|
||||
Mockito.when(connect.domainLookupByName(VMNAME)).thenReturn(domain);
|
||||
NodeInfo nodeInfo = new NodeInfo();
|
||||
final NodeInfo nodeInfo = new NodeInfo();
|
||||
nodeInfo.cpus = 8;
|
||||
nodeInfo.memory = 8 * 1024 * 1024;
|
||||
nodeInfo.sockets = 2;
|
||||
|
|
@ -301,24 +309,24 @@ public class LibvirtComputingResourceTest {
|
|||
nodeInfo.model = "Foo processor";
|
||||
Mockito.when(connect.nodeInfo()).thenReturn(nodeInfo);
|
||||
// this is testing the interface stats, returns an increasing number of sent and received bytes
|
||||
Mockito.when(domain.interfaceStats(Matchers.anyString())).thenAnswer(new Answer<DomainInterfaceStats>() {
|
||||
Mockito.when(domain.interfaceStats(Matchers.anyString())).thenAnswer(new org.mockito.stubbing.Answer<DomainInterfaceStats>() {
|
||||
// increment with less than a KB, so this should be less than 1 KB
|
||||
final static int increment = 1000;
|
||||
int rxBytes = 1000;
|
||||
int txBytes = 1000;
|
||||
|
||||
@Override
|
||||
public DomainInterfaceStats answer(InvocationOnMock invocation) throws Throwable {
|
||||
DomainInterfaceStats domainInterfaceStats = new DomainInterfaceStats();
|
||||
domainInterfaceStats.rx_bytes = (rxBytes += increment);
|
||||
domainInterfaceStats.tx_bytes = (txBytes += increment);
|
||||
public DomainInterfaceStats answer(final InvocationOnMock invocation) throws Throwable {
|
||||
final DomainInterfaceStats domainInterfaceStats = new DomainInterfaceStats();
|
||||
domainInterfaceStats.rx_bytes = rxBytes += increment;
|
||||
domainInterfaceStats.tx_bytes = txBytes += increment;
|
||||
return domainInterfaceStats;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Mockito.when(domain.blockStats(Matchers.anyString())).thenAnswer(new Answer<DomainBlockStats>() {
|
||||
Mockito.when(domain.blockStats(Matchers.anyString())).thenAnswer(new org.mockito.stubbing.Answer<DomainBlockStats>() {
|
||||
// a little less than a KB
|
||||
final static int increment = 1000;
|
||||
|
||||
|
|
@ -326,32 +334,32 @@ public class LibvirtComputingResourceTest {
|
|||
int wrBytes = 1024;
|
||||
|
||||
@Override
|
||||
public DomainBlockStats answer(InvocationOnMock invocation) throws Throwable {
|
||||
DomainBlockStats domainBlockStats = new DomainBlockStats();
|
||||
public DomainBlockStats answer(final InvocationOnMock invocation) throws Throwable {
|
||||
final DomainBlockStats domainBlockStats = new DomainBlockStats();
|
||||
|
||||
domainBlockStats.rd_bytes = (rdBytes += increment);
|
||||
domainBlockStats.wr_bytes = (wrBytes += increment);
|
||||
domainBlockStats.rd_bytes = rdBytes += increment;
|
||||
domainBlockStats.wr_bytes = wrBytes += increment;
|
||||
return domainBlockStats;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource() {
|
||||
final LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource() {
|
||||
@Override
|
||||
protected List<InterfaceDef> getInterfaces(Connect conn, String vmName) {
|
||||
InterfaceDef interfaceDef = new InterfaceDef();
|
||||
public List<InterfaceDef> getInterfaces(final Connect conn, final String vmName) {
|
||||
final InterfaceDef interfaceDef = new InterfaceDef();
|
||||
return Arrays.asList(interfaceDef);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DiskDef> getDisks(Connect conn, String vmName) {
|
||||
DiskDef diskDef = new DiskDef();
|
||||
public List<DiskDef> getDisks(final Connect conn, final String vmName) {
|
||||
final DiskDef diskDef = new DiskDef();
|
||||
return Arrays.asList(diskDef);
|
||||
}
|
||||
|
||||
};
|
||||
libvirtComputingResource.getVmStat(connect, VMNAME);
|
||||
VmStatsEntry vmStat = libvirtComputingResource.getVmStat(connect, VMNAME);
|
||||
final VmStatsEntry vmStat = libvirtComputingResource.getVmStat(connect, VMNAME);
|
||||
// network traffic as generated by the logic above, must be greater than zero
|
||||
Assert.assertTrue(vmStat.getNetworkReadKBs() > 0);
|
||||
Assert.assertTrue(vmStat.getNetworkWriteKBs() > 0);
|
||||
|
|
@ -363,7 +371,24 @@ public class LibvirtComputingResourceTest {
|
|||
@Test
|
||||
public void getCpuSpeed() {
|
||||
Assume.assumeTrue(SystemUtils.IS_OS_LINUX);
|
||||
NodeInfo nodeInfo = Mockito.mock(NodeInfo.class);
|
||||
final NodeInfo nodeInfo = Mockito.mock(NodeInfo.class);
|
||||
LibvirtComputingResource.getCpuSpeed(nodeInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* New Tests
|
||||
*/
|
||||
|
||||
@Test(expected = UnsatisfiedLinkError.class)
|
||||
public void testStopCommand() {
|
||||
// We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need
|
||||
// a better way to mock stuff!
|
||||
final String vmName = "Test";
|
||||
final StopCommand stopCommand = new StopCommand(vmName, false, false);
|
||||
|
||||
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
|
||||
assertNotNull(wrapper);
|
||||
|
||||
wrapper.execute(stopCommand, libvirtComputingResource);
|
||||
}
|
||||
}
|
||||
|
|
@ -107,12 +107,7 @@ public class CitrixRequestWrapper extends RequestWrapper {
|
|||
instance = new CitrixRequestWrapper();
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private final Hashtable<Class<? extends ServerResource>, Hashtable<Class<? extends Command>, CommandWrapper>> resources;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private CitrixRequestWrapper() {
|
||||
resources = new Hashtable<Class<? extends ServerResource>, Hashtable<Class<? extends Command>, CommandWrapper>>();
|
||||
init();
|
||||
}
|
||||
|
||||
|
|
@ -232,73 +227,4 @@ public class CitrixRequestWrapper extends RequestWrapper {
|
|||
|
||||
return commandWrapper.execute(command, serverResource);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected Hashtable<Class<? extends Command>, CommandWrapper> retrieveResource(final Command command, final Class<? extends ServerResource> resourceClass) {
|
||||
Class<? extends ServerResource> keepResourceClass = resourceClass;
|
||||
Hashtable<Class<? extends Command>, CommandWrapper> resource = resources.get(keepResourceClass);
|
||||
while (resource == null) {
|
||||
try {
|
||||
final Class<? extends ServerResource> keepResourceClass2 = (Class<? extends ServerResource>) keepResourceClass.getSuperclass();
|
||||
resource = resources.get(keepResourceClass2);
|
||||
|
||||
keepResourceClass = keepResourceClass2;
|
||||
} catch (final ClassCastException e) {
|
||||
throw new NullPointerException("No key found for '" + command.getClass() + "' in the Map!");
|
||||
}
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected CommandWrapper<Command, Answer, ServerResource> retrieveCommands(final Class<? extends Command> commandClass,
|
||||
final Hashtable<Class<? extends Command>, CommandWrapper> resourceCommands) {
|
||||
|
||||
Class<? extends Command> keepCommandClass = commandClass;
|
||||
CommandWrapper<Command, Answer, ServerResource> commandWrapper = resourceCommands.get(keepCommandClass);
|
||||
while (commandWrapper == null) {
|
||||
try {
|
||||
final Class<? extends Command> commandClass2 = (Class<? extends Command>) keepCommandClass.getSuperclass();
|
||||
|
||||
if (commandClass2 == null) {
|
||||
throw new NullPointerException("All the COMMAND hierarchy tree has been visited but no compliant key has been found for '" + commandClass +"'.");
|
||||
}
|
||||
|
||||
commandWrapper = resourceCommands.get(commandClass2);
|
||||
|
||||
keepCommandClass = commandClass2;
|
||||
} catch (final NullPointerException e) {
|
||||
// Will now traverse all the resource hierarchy. Returning null is not a problem.
|
||||
// It is all being nicely checked and in case we do not have a resource, an Unsupported answer will be thrown by the base class.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return commandWrapper;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected CommandWrapper<Command, Answer, ServerResource> retryWhenAllFails(final Command command, final Class<? extends ServerResource> resourceClass,
|
||||
final Hashtable<Class<? extends Command>, CommandWrapper> resourceCommands) {
|
||||
|
||||
Class<? extends ServerResource> keepResourceClass = resourceClass;
|
||||
CommandWrapper<Command, Answer, ServerResource> commandWrapper = resourceCommands.get(command.getClass());
|
||||
while (commandWrapper == null) {
|
||||
//Could not find the command in the given resource, will traverse the family tree.
|
||||
try {
|
||||
final Class<? extends ServerResource> resourceClass2 = (Class<? extends ServerResource>) keepResourceClass.getSuperclass();
|
||||
|
||||
if (resourceClass2 == null) {
|
||||
throw new NullPointerException("All the SERVER-RESOURCE hierarchy tree has been visited but no compliant key has been found for '" + command.getClass() +"'.");
|
||||
}
|
||||
|
||||
final Hashtable<Class<? extends Command>, CommandWrapper> resourceCommands2 = retrieveResource(command, (Class<? extends ServerResource>) keepResourceClass.getSuperclass());
|
||||
keepResourceClass = resourceClass2;
|
||||
|
||||
commandWrapper = retrieveCommands(command.getClass(), resourceCommands2);
|
||||
} catch (final NullPointerException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return commandWrapper;
|
||||
}
|
||||
}
|
||||
|
|
@ -42,7 +42,6 @@ import org.junit.runner.RunWith;
|
|||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
|
|
@ -136,7 +135,6 @@ import com.xensource.xenapi.Types.BadServerResponse;
|
|||
import com.xensource.xenapi.Types.XenAPIException;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({ Connection.class, Host.Record.class })
|
||||
public class CitrixRequestWrapperTest {
|
||||
|
||||
@Mock
|
||||
|
|
@ -279,7 +277,7 @@ public class CitrixRequestWrapperTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testStopCommandCommand() {
|
||||
public void testStopCommand() {
|
||||
final StopCommand stopCommand = new StopCommand("Test", false, false);
|
||||
|
||||
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
|
||||
|
|
|
|||
Loading…
Reference in New Issue