From b3913ca1fbd3b400961608a4434cd7619cf1606d Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Tue, 5 May 2015 12:53:10 +0200 Subject: [PATCH] Refactoring the LibvirtComputingResource - Adding LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper - 5 unit tests added - KVM hypervisor plugin with 19.5% coverage --- .../resource/LibvirtComputingResource.java | 67 +--- .../wrapper/LibvirtConnectionWrapper.java | 33 +- ...ateTemplateFromSnapshotCommandWrapper.java | 113 ++++++ .../wrapper/LibvirtRequestWrapper.java | 2 + .../LibvirtComputingResourceTest.java | 354 ++++++++++++++++++ 5 files changed, 502 insertions(+), 67 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 4e8b4cf0c81..977288b2c86 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -64,7 +64,6 @@ import org.libvirt.StorageVol; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; -import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.HostVmStateReportEntry; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; @@ -84,7 +83,6 @@ import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.SetSourceNatCommand; import com.cloud.agent.api.storage.CopyVolumeAnswer; import com.cloud.agent.api.storage.CopyVolumeCommand; -import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; import com.cloud.agent.api.storage.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; @@ -140,10 +138,6 @@ import com.cloud.storage.StorageLayer; import com.cloud.storage.Volume; import com.cloud.storage.resource.StorageSubsystemCommandHandler; import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase; -import com.cloud.storage.template.Processor; -import com.cloud.storage.template.Processor.FormatInfo; -import com.cloud.storage.template.QCOW2Processor; -import com.cloud.storage.template.TemplateLocation; import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -1252,9 +1246,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) { - return execute((CreatePrivateTemplateFromSnapshotCommand)cmd); - } else if (cmd instanceof StartCommand) { + if (cmd instanceof StartCommand) { return execute((StartCommand)cmd); } else if (cmd instanceof NetworkElementCommand) { return _virtRouterResource.executeRequest((NetworkElementCommand)cmd); @@ -1884,63 +1876,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new ExecutionResult(true, null); } - protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromSnapshotCommand cmd) { - final String templateFolder = cmd.getAccountId() + File.separator + cmd.getNewTemplateId(); - final String templateInstallFolder = "template/tmpl/" + templateFolder; - final String tmplName = UUID.randomUUID().toString(); - final String tmplFileName = tmplName + ".qcow2"; - KVMStoragePool secondaryPool = null; - KVMStoragePool snapshotPool = null; - try { - String snapshotPath = cmd.getSnapshotUuid(); - final int index = snapshotPath.lastIndexOf("/"); - snapshotPath = snapshotPath.substring(0, index); - snapshotPool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl() + snapshotPath); - final KVMPhysicalDisk snapshot = snapshotPool.getPhysicalDisk(cmd.getSnapshotName()); - - secondaryPool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl()); - - final String templatePath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; - - _storage.mkdirs(templatePath); - - final String tmplPath = templateInstallFolder + File.separator + tmplFileName; - final Script command = new Script(_createTmplPath, _cmdsTimeout, s_logger); - command.add("-t", templatePath); - command.add("-n", tmplFileName); - command.add("-f", snapshot.getPath()); - command.execute(); - - final Map params = new HashMap(); - params.put(StorageLayer.InstanceConfigKey, _storage); - final Processor qcow2Processor = new QCOW2Processor(); - qcow2Processor.configure("QCOW2 Processor", params); - final FormatInfo info = qcow2Processor.process(templatePath, null, tmplName); - - final TemplateLocation loc = new TemplateLocation(_storage, templatePath); - loc.create(1, true, tmplName); - loc.addFormat(info); - loc.save(); - - return new CreatePrivateTemplateAnswer(cmd, true, "", tmplPath, info.virtualSize, info.size, tmplName, info.format); - } catch (final ConfigurationException e) { - return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage()); - } catch (final InternalErrorException e) { - return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage()); - } catch (final IOException e) { - return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage()); - } catch (final CloudRuntimeException e) { - return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage()); - } finally { - if (secondaryPool != null) { - _storagePoolMgr.deleteStoragePool(secondaryPool.getType(), secondaryPool.getUuid()); - } - if (snapshotPool != null) { - _storagePoolMgr.deleteStoragePool(snapshotPool.getType(), snapshotPool.getUuid()); - } - } - } - protected PowerState convertToPowerState(final DomainState ps) { final PowerState state = s_powerStatesTable.get(ps); return state == null ? PowerState.PowerUnknown : state; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java index e6743ace118..3a51a37e376 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java @@ -16,13 +16,25 @@ // under the License. package com.cloud.hypervisor.kvm.resource.wrapper; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import javax.naming.ConfigurationException; + import org.libvirt.Connect; import org.libvirt.LibvirtException; import com.cloud.hypervisor.kvm.resource.LibvirtConnection; +import com.cloud.storage.StorageLayer; +import com.cloud.storage.template.Processor; +import com.cloud.storage.template.QCOW2Processor; +import com.cloud.storage.template.TemplateLocation; /** - * This class is used to wrap the calls to LibvirtConnection and ease the burden of the unit tests. + * This class is used to wrap the calls to several static methods. By doing so, we make easier to mock this class + * and the methods wrapped here. + * * Please do not instantiate this class directly, but inject it using the {@code @Inject} annotation. */ public class LibvirtConnectionWrapper { @@ -34,4 +46,23 @@ public class LibvirtConnectionWrapper { public Connect getConnection() throws LibvirtException { return LibvirtConnection.getConnection(); } + + public TemplateLocation buildTemplateLocation(final StorageLayer storage, final String templatePath) { + final TemplateLocation location = new TemplateLocation(storage, templatePath); + return location; + } + + public Processor buildQCOW2Processor(final StorageLayer storage) throws ConfigurationException { + final Map params = new HashMap(); + params.put(StorageLayer.InstanceConfigKey, storage); + + final Processor qcow2Processor = new QCOW2Processor(); + qcow2Processor.configure("QCOW2 Processor", params); + + return qcow2Processor; + } + + public String buildTemplateUUIDName() { + return UUID.randomUUID().toString(); + } } \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java new file mode 100644 index 00000000000..20bebad81d4 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java @@ -0,0 +1,113 @@ +// +// 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.io.File; +import java.io.IOException; + +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; +import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; +import com.cloud.exception.InternalErrorException; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; +import com.cloud.hypervisor.kvm.storage.KVMStoragePool; +import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager; +import com.cloud.resource.CommandWrapper; +import com.cloud.storage.StorageLayer; +import com.cloud.storage.template.Processor; +import com.cloud.storage.template.Processor.FormatInfo; +import com.cloud.storage.template.TemplateLocation; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.script.Script; + +public final class LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.class); + + @Override + public Answer execute(final CreatePrivateTemplateFromSnapshotCommand command, final LibvirtComputingResource libvirtComputingResource) { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + + final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId(); + final String templateInstallFolder = "template/tmpl/" + templateFolder; + final String tmplName = libvirtConnectionWrapper.buildTemplateUUIDName(); + final String tmplFileName = tmplName + ".qcow2"; + + KVMStoragePool secondaryPool = null; + KVMStoragePool snapshotPool = null; + final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); + + try { + String snapshotPath = command.getSnapshotUuid(); + final int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + + snapshotPool = storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath); + secondaryPool = storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl()); + + final KVMPhysicalDisk snapshot = snapshotPool.getPhysicalDisk(command.getSnapshotName()); + + final String templatePath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; + + final StorageLayer storage = libvirtComputingResource.getStorage(); + storage.mkdirs(templatePath); + + final String tmplPath = templateInstallFolder + File.separator + tmplFileName; + final String createTmplPath = libvirtComputingResource.createTmplPath(); + final int cmdsTimeout = libvirtComputingResource.getCmdsTimeout(); + + final Script scriptCommand = new Script(createTmplPath, cmdsTimeout, s_logger); + scriptCommand.add("-t", templatePath); + scriptCommand.add("-n", tmplFileName); + scriptCommand.add("-f", snapshot.getPath()); + scriptCommand.execute(); + + final Processor qcow2Processor = libvirtConnectionWrapper.buildQCOW2Processor(storage); + final FormatInfo info = qcow2Processor.process(templatePath, null, tmplName); + final TemplateLocation loc = libvirtConnectionWrapper.buildTemplateLocation(storage, templatePath); + + loc.create(1, true, tmplName); + loc.addFormat(info); + loc.save(); + + return new CreatePrivateTemplateAnswer(command, true, "", tmplPath, info.virtualSize, info.size, tmplName, info.format); + } catch (final ConfigurationException e) { + return new CreatePrivateTemplateAnswer(command, false, e.getMessage()); + } catch (final InternalErrorException e) { + return new CreatePrivateTemplateAnswer(command, false, e.getMessage()); + } catch (final IOException e) { + return new CreatePrivateTemplateAnswer(command, false, e.getMessage()); + } catch (final CloudRuntimeException e) { + return new CreatePrivateTemplateAnswer(command, false, e.getMessage()); + } finally { + if (secondaryPool != null) { + storagePoolMgr.deleteStoragePool(secondaryPool.getType(), secondaryPool.getUuid()); + } + if (snapshotPool != null) { + storagePoolMgr.deleteStoragePool(snapshotPool.getType(), snapshotPool.getUuid()); + } + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java index 2656037f456..7e732640c50 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java @@ -30,6 +30,7 @@ import com.cloud.agent.api.CheckOnHostCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; import com.cloud.agent.api.Command; +import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; @@ -142,6 +143,7 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(CreatePrivateTemplateFromVolumeCommand.class, new LibvirtCreatePrivateTemplateFromVolumeCommandWrapper()); linbvirtCommands.put(ManageSnapshotCommand.class, new LibvirtManageSnapshotCommandWrapper()); linbvirtCommands.put(BackupSnapshotCommand.class, new LibvirtBackupSnapshotCommandWrapper()); + linbvirtCommands.put(CreatePrivateTemplateFromSnapshotCommand.class, new LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper()); resources.put(LibvirtComputingResource.class, linbvirtCommands); } diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java index b0c273404b7..5f9c50ad012 100644 --- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java +++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java @@ -29,6 +29,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; +import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; @@ -37,6 +38,7 @@ import java.util.List; import java.util.Random; import java.util.UUID; +import javax.naming.ConfigurationException; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPathConstants; @@ -72,6 +74,7 @@ import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; +import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; @@ -139,8 +142,12 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetworkSetupInfo; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.StorageLayer; import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; +import com.cloud.storage.template.Processor; +import com.cloud.storage.template.Processor.FormatInfo; +import com.cloud.storage.template.TemplateLocation; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.Pair; import com.cloud.utils.exception.CloudRuntimeException; @@ -3536,4 +3543,351 @@ public class LibvirtComputingResourceTest { fail(e.getMessage()); } } + + @Test + public void testCreatePrivateTemplateFromSnapshotCommand() { + final StoragePool pool = Mockito.mock(StoragePool.class); + final String secondaryStoragePoolURL = "nfs:/192.168.2.2/storage/secondary"; + final Long dcId = 1l; + final Long accountId = 1l; + final Long volumeId = 1l; + final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/"; + final String backedUpSnapshotName = "snap"; + final String origTemplateInstallPath = "/install/path/"; + final Long newTemplateId = 2l; + final String templateName = "templ"; + final int wait = 0; + + final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait); + + final String templatePath = "/template/path"; + final String localPath = "/mnt/local"; + final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab"; + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class); + final StorageLayer storage = Mockito.mock(StorageLayer.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final TemplateLocation location = Mockito.mock(TemplateLocation.class); + final Processor qcow2Processor = Mockito.mock(Processor.class); + final FormatInfo info = Mockito.mock(FormatInfo.class); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + + String snapshotPath = command.getSnapshotUuid(); + final int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool); + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool); + when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot); + when(secondaryPool.getLocalPath()).thenReturn(localPath); + when(libvirtComputingResource.getStorage()).thenReturn(storage); + + when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath); + when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1); + + final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId(); + final String templateInstallFolder = "template/tmpl/" + templateFolder; + final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtConnectionWrapper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); + when(libvirtConnectionWrapper.buildTemplateUUIDName()).thenReturn(tmplName); + + try { + when(libvirtConnectionWrapper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor); + when(qcow2Processor.process(tmplPath, null, tmplName)).thenReturn(info); + } catch (final ConfigurationException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl()); + } + + @SuppressWarnings("unchecked") + @Test + public void testCreatePrivateTemplateFromSnapshotCommandConfigurationException() { + final StoragePool pool = Mockito.mock(StoragePool.class); + final String secondaryStoragePoolURL = "nfs:/192.168.2.2/storage/secondary"; + final Long dcId = 1l; + final Long accountId = 1l; + final Long volumeId = 1l; + final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/"; + final String backedUpSnapshotName = "snap"; + final String origTemplateInstallPath = "/install/path/"; + final Long newTemplateId = 2l; + final String templateName = "templ"; + final int wait = 0; + + final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait); + + final String templatePath = "/template/path"; + final String localPath = "/mnt/local"; + final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab"; + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class); + final StorageLayer storage = Mockito.mock(StorageLayer.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final TemplateLocation location = Mockito.mock(TemplateLocation.class); + final Processor qcow2Processor = Mockito.mock(Processor.class); + final FormatInfo info = Mockito.mock(FormatInfo.class); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + + String snapshotPath = command.getSnapshotUuid(); + final int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool); + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool); + when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot); + when(secondaryPool.getLocalPath()).thenReturn(localPath); + when(libvirtComputingResource.getStorage()).thenReturn(storage); + + when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath); + when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1); + + final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId(); + final String templateInstallFolder = "template/tmpl/" + templateFolder; + final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtConnectionWrapper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); + when(libvirtConnectionWrapper.buildTemplateUUIDName()).thenReturn(tmplName); + + try { + when(libvirtConnectionWrapper.buildQCOW2Processor(storage)).thenThrow(ConfigurationException.class); + when(qcow2Processor.process(tmplPath, null, tmplName)).thenReturn(info); + } catch (final ConfigurationException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl()); + } + + @SuppressWarnings("unchecked") + @Test + public void testCreatePrivateTemplateFromSnapshotCommandInternalErrorException() { + final StoragePool pool = Mockito.mock(StoragePool.class); + final String secondaryStoragePoolURL = "nfs:/192.168.2.2/storage/secondary"; + final Long dcId = 1l; + final Long accountId = 1l; + final Long volumeId = 1l; + final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/"; + final String backedUpSnapshotName = "snap"; + final String origTemplateInstallPath = "/install/path/"; + final Long newTemplateId = 2l; + final String templateName = "templ"; + final int wait = 0; + + final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait); + + final String templatePath = "/template/path"; + final String localPath = "/mnt/local"; + final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab"; + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class); + final StorageLayer storage = Mockito.mock(StorageLayer.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final TemplateLocation location = Mockito.mock(TemplateLocation.class); + final Processor qcow2Processor = Mockito.mock(Processor.class); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + + String snapshotPath = command.getSnapshotUuid(); + final int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool); + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool); + when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot); + when(secondaryPool.getLocalPath()).thenReturn(localPath); + when(libvirtComputingResource.getStorage()).thenReturn(storage); + + when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath); + when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1); + + final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId(); + final String templateInstallFolder = "template/tmpl/" + templateFolder; + final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtConnectionWrapper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); + when(libvirtConnectionWrapper.buildTemplateUUIDName()).thenReturn(tmplName); + + try { + when(libvirtConnectionWrapper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor); + when(qcow2Processor.process(tmplPath, null, tmplName)).thenThrow(InternalErrorException.class); + } catch (final ConfigurationException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl()); + } + + @SuppressWarnings("unchecked") + @Test + public void testCreatePrivateTemplateFromSnapshotCommandIOException() { + final StoragePool pool = Mockito.mock(StoragePool.class); + final String secondaryStoragePoolURL = "nfs:/192.168.2.2/storage/secondary"; + final Long dcId = 1l; + final Long accountId = 1l; + final Long volumeId = 1l; + final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/"; + final String backedUpSnapshotName = "snap"; + final String origTemplateInstallPath = "/install/path/"; + final Long newTemplateId = 2l; + final String templateName = "templ"; + final int wait = 0; + + final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait); + + final String templatePath = "/template/path"; + final String localPath = "/mnt/local"; + final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab"; + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class); + final StorageLayer storage = Mockito.mock(StorageLayer.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final TemplateLocation location = Mockito.mock(TemplateLocation.class); + final Processor qcow2Processor = Mockito.mock(Processor.class); + final FormatInfo info = Mockito.mock(FormatInfo.class); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + + String snapshotPath = command.getSnapshotUuid(); + final int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool); + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool); + when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot); + when(secondaryPool.getLocalPath()).thenReturn(localPath); + when(libvirtComputingResource.getStorage()).thenReturn(storage); + + when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath); + when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1); + + final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId(); + final String templateInstallFolder = "template/tmpl/" + templateFolder; + final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtConnectionWrapper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); + when(libvirtConnectionWrapper.buildTemplateUUIDName()).thenReturn(tmplName); + + try { + when(libvirtConnectionWrapper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor); + when(qcow2Processor.process(tmplPath, null, tmplName)).thenReturn(info); + + when(location.create(1, true, tmplName)).thenThrow(IOException.class); + + } catch (final ConfigurationException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } catch (final IOException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl()); + } + + @SuppressWarnings("unchecked") + @Test + public void testCreatePrivateTemplateFromSnapshotCommandCloudRuntime() { + final StoragePool pool = Mockito.mock(StoragePool.class); + final String secondaryStoragePoolURL = "nfs:/192.168.2.2/storage/secondary"; + final Long dcId = 1l; + final Long accountId = 1l; + final Long volumeId = 1l; + final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/"; + final String backedUpSnapshotName = "snap"; + final String origTemplateInstallPath = "/install/path/"; + final Long newTemplateId = 2l; + final String templateName = "templ"; + final int wait = 0; + + final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab"; + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + + String snapshotPath = command.getSnapshotUuid(); + final int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtConnectionWrapper.buildTemplateUUIDName()).thenReturn(tmplName); + + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool); + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool); + when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenThrow(CloudRuntimeException.class); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl()); + } } \ No newline at end of file