This is an automated email from the ASF dual-hosted git repository. harikrishna pushed a commit to branch CheckVolumeAPI in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit 702aa801c9e22361a9f290e8a13587077d73858d Author: Harikrishna Patnala <harikrishna.patn...@gmail.com> AuthorDate: Tue Jan 30 13:05:54 2024 +0530 Added unit tests --- .../storage/volume/VolumeServiceImpl.java | 2 +- .../storage/volume/VolumeServiceTest.java | 73 +++++++++++ .../LibvirtCheckVolumeAndRepairCommandWrapper.java | 4 +- ...virtCheckVolumeAndRepairCommandWrapperTest.java | 103 +++++++++++++++ .../apache/cloudstack/utils/qemu/QemuImgTest.java | 17 +++ .../com/cloud/storage/VolumeApiServiceImpl.java | 2 +- .../cloud/storage/VolumeApiServiceImplTest.java | 146 +++++++++++++++++++++ 7 files changed, 343 insertions(+), 4 deletions(-) diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 698a585b987..e89c0cfb117 100644 --- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -201,7 +201,7 @@ public class VolumeServiceImpl implements VolumeService { @Inject private VolumeOrchestrationService _volumeMgr; @Inject - private StorageManager _storageMgr; + protected StorageManager _storageMgr; @Inject private AnnotationDao annotationDao; @Inject diff --git a/engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/VolumeServiceTest.java b/engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/VolumeServiceTest.java index f4c6df7dd40..ddcfcefc890 100644 --- a/engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/VolumeServiceTest.java +++ b/engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/VolumeServiceTest.java @@ -19,14 +19,24 @@ package org.apache.cloudstack.storage.volume; +import com.cloud.agent.api.storage.CheckVolumeAndRepairAnswer; +import com.cloud.agent.api.storage.CheckVolumeAndRepairCommand; +import com.cloud.agent.api.to.StorageFilerTO; +import com.cloud.exception.StorageUnavailableException; +import com.cloud.storage.CheckAndRepairVolumePayload; +import com.cloud.storage.StorageManager; +import com.cloud.storage.StoragePool; import com.cloud.storage.Storage; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.snapshot.SnapshotManager; +import com.cloud.utils.Pair; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.ExecutionException; + import junit.framework.TestCase; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; @@ -66,6 +76,9 @@ public class VolumeServiceTest extends TestCase{ @Mock SnapshotManager snapshotManagerMock; + @Mock + StorageManager storageManagerMock; + @Mock VolumeVO volumeVoMock; @@ -75,6 +88,7 @@ public class VolumeServiceTest extends TestCase{ volumeServiceImplSpy.volFactory = volumeDataFactoryMock; volumeServiceImplSpy.volDao = volumeDaoMock; volumeServiceImplSpy.snapshotMgr = snapshotManagerMock; + volumeServiceImplSpy._storageMgr = storageManagerMock; } @Test(expected = InterruptedException.class) @@ -213,4 +227,63 @@ public class VolumeServiceTest extends TestCase{ volumeServiceImplSpy.destroySourceVolumeAfterMigration(ObjectInDataStoreStateMachine.Event.DestroyRequested, null, volumeObject, volumeObject, true); } + + @Test + public void testCheckAndRepairVolume() throws StorageUnavailableException { + VolumeInfo volume = Mockito.mock(VolumeInfo.class); + Mockito.when(volume.getPoolId()).thenReturn(1L); + StoragePool pool = Mockito.mock(StoragePool.class); + Mockito.when(storageManagerMock.getStoragePool(1L)).thenReturn(pool); + CheckAndRepairVolumePayload payload = new CheckAndRepairVolumePayload(false); + Mockito.when(volume.getpayload()).thenReturn(payload); + Mockito.when(volume.getPath()).thenReturn("cbac516a-0f1f-4559-921c-1a7c6c408ccf"); + Mockito.when(volume.getPassphrase()).thenReturn(new byte[] {3, 1, 2, 3}); + Mockito.when(volume.getEncryptFormat()).thenReturn("LUKS"); + + String checkResult = "{\n" + + " \"image-end-offset\": 6442582016,\n" + + " \"total-clusters\": 163840,\n" + + " \"check-errors\": 0,\n" + + " \"leaks\": 124,\n" + + " \"allocated-clusters\": 98154,\n" + + " \"filename\": \"/var/lib/libvirt/images/26be20c7-b9d0-43f6-a76e-16c70737a0e0\",\n" + + " \"format\": \"qcow2\",\n" + + " \"fragmented-clusters\": 96135\n" + + "}"; + + CheckVolumeAndRepairCommand command = new CheckVolumeAndRepairCommand(volume.getPath(), new StorageFilerTO(pool), payload.isRepair(), + volume.getPassphrase(), volume.getEncryptFormat()); + + CheckVolumeAndRepairAnswer answer = new CheckVolumeAndRepairAnswer(command, true, checkResult); + answer.setVolumeCheckExecutionResult(checkResult); + Mockito.when(storageManagerMock.sendToPool(pool, null, command)).thenReturn(answer); + + Pair<String, String> result = volumeServiceImplSpy.checkAndRepairVolume(volume); + + Assert.assertEquals(result.first(), checkResult); + Assert.assertEquals(result.second(), null); + } + + @Test + public void testCheckAndRepairVolumeWhenFailure() throws StorageUnavailableException { + VolumeInfo volume = Mockito.mock(VolumeInfo.class); + Mockito.when(volume.getPoolId()).thenReturn(1L); + StoragePool pool = Mockito.mock(StoragePool.class); + Mockito.when(storageManagerMock.getStoragePool(1L)).thenReturn(pool); + CheckAndRepairVolumePayload payload = new CheckAndRepairVolumePayload(false); + Mockito.when(volume.getpayload()).thenReturn(payload); + Mockito.when(volume.getPath()).thenReturn("cbac516a-0f1f-4559-921c-1a7c6c408ccf"); + Mockito.when(volume.getPassphrase()).thenReturn(new byte[] {3, 1, 2, 3}); + Mockito.when(volume.getEncryptFormat()).thenReturn("LUKS"); + + CheckVolumeAndRepairCommand command = new CheckVolumeAndRepairCommand(volume.getPath(), new StorageFilerTO(pool), payload.isRepair(), + volume.getPassphrase(), volume.getEncryptFormat()); + + CheckVolumeAndRepairAnswer answer = new CheckVolumeAndRepairAnswer(command, false, "Unable to execute qemu command"); + Mockito.when(storageManagerMock.sendToPool(pool, null, command)).thenReturn(answer); + + Pair<String, String> result = volumeServiceImplSpy.checkAndRepairVolume(volume); + + Assert.assertEquals(null, result); + } } diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVolumeAndRepairCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVolumeAndRepairCommandWrapper.java index 553de2953c1..42fd020d9bc 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVolumeAndRepairCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVolumeAndRepairCommandWrapper.java @@ -47,7 +47,7 @@ import java.util.Arrays; import java.util.List; @ResourceWrapper(handles = CheckVolumeAndRepairCommand.class) -public final class LibvirtCheckVolumeAndRepairCommandWrapper extends CommandWrapper<CheckVolumeAndRepairCommand, Answer, LibvirtComputingResource> { +public class LibvirtCheckVolumeAndRepairCommandWrapper extends CommandWrapper<CheckVolumeAndRepairCommand, Answer, LibvirtComputingResource> { private static final Logger s_logger = Logger.getLogger(LibvirtCheckVolumeAndRepairCommandWrapper.class); @@ -87,7 +87,7 @@ public final class LibvirtCheckVolumeAndRepairCommandWrapper extends CommandWrap } } - private String checkVolumeAndRepair(final KVMPhysicalDisk vol, final boolean repair, final QemuObject.EncryptFormat encryptFormat, byte[] passphrase, final LibvirtComputingResource libvirtComputingResource) throws CloudRuntimeException { + protected String checkVolumeAndRepair(final KVMPhysicalDisk vol, final boolean repair, final QemuObject.EncryptFormat encryptFormat, byte[] passphrase, final LibvirtComputingResource libvirtComputingResource) throws CloudRuntimeException { List<QemuObject> passphraseObjects = new ArrayList<>(); QemuImageOptions imgOptions = null; if (ArrayUtils.isEmpty(passphrase)) { diff --git a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVolumeAndRepairCommandWrapperTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVolumeAndRepairCommandWrapperTest.java new file mode 100644 index 00000000000..ae0f75c76ca --- /dev/null +++ b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVolumeAndRepairCommandWrapperTest.java @@ -0,0 +1,103 @@ +/* + * Licensed 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 com.cloud.agent.api.storage.CheckVolumeAndRepairAnswer; +import com.cloud.agent.api.storage.CheckVolumeAndRepairCommand; +import com.cloud.agent.api.to.StorageFilerTO; +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.storage.Storage; + +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.utils.qemu.QemuImg; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +public class LibvirtCheckVolumeAndRepairCommandWrapperTest { + + @Spy + LibvirtCheckVolumeAndRepairCommandWrapper libvirtCheckVolumeAndRepairCommandWrapperSpy = Mockito.spy(LibvirtCheckVolumeAndRepairCommandWrapper.class); + + @Mock + LibvirtComputingResource libvirtComputingResourceMock; + + @Mock + CheckVolumeAndRepairCommand checkVolumeAndRepairCommand; + + @Mock + QemuImg qemuImgMock; + + @Before + public void init() { + Mockito.when(libvirtComputingResourceMock.getCmdsTimeout()).thenReturn(60); + } + + @Test + @PrepareForTest(LibvirtCheckVolumeAndRepairCommandWrapper.class) + public void testCheckAndRepairVolume() throws Exception { + + CheckVolumeAndRepairCommand cmd = Mockito.mock(CheckVolumeAndRepairCommand.class); + Mockito.when(cmd.getPath()).thenReturn("cbac516a-0f1f-4559-921c-1a7c6c408ccf"); + Mockito.when(cmd.needRepair()).thenReturn(false); + StorageFilerTO spool = Mockito.mock(StorageFilerTO.class); + Mockito.when(cmd.getPool()).thenReturn(spool); + + KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + Mockito.when(libvirtComputingResourceMock.getStoragePoolMgr()).thenReturn(storagePoolMgr); + KVMStoragePool pool = Mockito.mock(KVMStoragePool.class); + Mockito.when(spool.getType()).thenReturn(Storage.StoragePoolType.PowerFlex); + Mockito.when(spool.getUuid()).thenReturn("b6be258b-42b8-49a4-ad51-3634ef8ff76a"); + Mockito.when(storagePoolMgr.getStoragePool(Storage.StoragePoolType.PowerFlex, "b6be258b-42b8-49a4-ad51-3634ef8ff76a")).thenReturn(pool); + Mockito.when(pool.connectPhysicalDisk("cbac516a-0f1f-4559-921c-1a7c6c408ccf", null)).thenReturn(true); + + KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class); + Mockito.when(pool.getPhysicalDisk("cbac516a-0f1f-4559-921c-1a7c6c408ccf")).thenReturn(vol); + + VolumeInfo volume = Mockito.mock(VolumeInfo.class); + Mockito.when(volume.getPoolId()).thenReturn(1L); + Mockito.when(volume.getPath()).thenReturn("cbac516a-0f1f-4559-921c-1a7c6c408ccf"); + + String checkResult = "{\n" + + " \"image-end-offset\": 6442582016,\n" + + " \"total-clusters\": 163840,\n" + + " \"check-errors\": 0,\n" + + " \"leaks\": 124,\n" + + " \"allocated-clusters\": 98154,\n" + + " \"filename\": \"/var/lib/libvirt/images/26be20c7-b9d0-43f6-a76e-16c70737a0e0\",\n" + + " \"format\": \"qcow2\",\n" + + " \"fragmented-clusters\": 96135\n" + + "}"; + + PowerMockito.whenNew(QemuImg.class).withArguments(Mockito.anyInt()).thenReturn(qemuImgMock); + Mockito.when(qemuImgMock.checkAndRepair(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyBoolean())).thenReturn(checkResult); // Replace with the desired result + + CheckVolumeAndRepairAnswer result = (CheckVolumeAndRepairAnswer) libvirtCheckVolumeAndRepairCommandWrapperSpy.execute(cmd, libvirtComputingResourceMock); + + Assert.assertEquals(checkResult, result.getVolumeCheckExecutionResult()); + } + +} diff --git a/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/qemu/QemuImgTest.java b/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/qemu/QemuImgTest.java index 8bb762cca85..aa74df57b24 100644 --- a/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/qemu/QemuImgTest.java +++ b/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/qemu/QemuImgTest.java @@ -368,4 +368,21 @@ public class QemuImgTest { Assert.assertTrue("should support qcow2", QemuImg.helpSupportsImageFormat(partialHelp, PhysicalDiskFormat.QCOW2)); Assert.assertFalse("should not support http", QemuImg.helpSupportsImageFormat(partialHelp, PhysicalDiskFormat.SHEEPDOG)); } + + @Test + public void testCheckAndRepair() throws LibvirtException { + String filename = "/tmp/" + UUID.randomUUID() + ".qcow2"; + + QemuImgFile file = new QemuImgFile(filename); + + try { + QemuImg qemu = new QemuImg(0); + qemu.checkAndRepair(file, null, null, false); + } catch (QemuImgException e) { + fail(e.getMessage()); + } + + File f = new File(filename); + f.delete(); + } } diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index 50d1a400664..efef67587d0 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -1887,7 +1887,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic } } - private void validationsForCheckVolumeOperation(long volumeId) { + protected void validationsForCheckVolumeOperation(long volumeId) { final VolumeVO volume = _volsDao.findById(volumeId); Account caller = CallContext.current().getCallingAccount(); _accountMgr.checkAccess(caller, null, true, volume); diff --git a/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java b/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java index a41cbb82704..7631ade441f 100644 --- a/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java +++ b/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java @@ -25,6 +25,7 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -39,6 +40,7 @@ import java.util.concurrent.ExecutionException; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.api.command.user.volume.CheckVolumeAndRepairCmd; import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd; @@ -1660,4 +1662,148 @@ public class VolumeApiServiceImplTest { // test passed } } + + @Test + public void testValidationsForCheckVolumeAPI() { + VolumeVO volume = mock(VolumeVO.class); + when(volumeDaoMock.findById(1L)).thenReturn(volume); + + AccountVO account = new AccountVO("admin", 1L, "networkDomain", Account.Type.NORMAL, "uuid"); + UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN); + CallContext.register(user, account); + + lenient().doNothing().when(accountManagerMock).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class)); + + when(volume.getInstanceId()).thenReturn(1L); + UserVmVO vm = mock(UserVmVO.class); + when(userVmDaoMock.findById(1L)).thenReturn(vm); + when(vm.getState()).thenReturn(State.Stopped); + when(volume.getState()).thenReturn(Volume.State.Ready); + when(volume.getId()).thenReturn(1L); + when(volumeDaoMock.getHypervisorType(1L)).thenReturn(HypervisorType.KVM); + + volumeApiServiceImpl.validationsForCheckVolumeOperation(1L); + } + + @Test(expected = InvalidParameterValueException.class) + public void testValidationsForCheckVolumeAPIWithRunningVM() { + VolumeVO volume = mock(VolumeVO.class); + when(volumeDaoMock.findById(1L)).thenReturn(volume); + + AccountVO account = new AccountVO("admin", 1L, "networkDomain", Account.Type.NORMAL, "uuid"); + UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN); + CallContext.register(user, account); + + lenient().doNothing().when(accountManagerMock).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class)); + + when(volume.getInstanceId()).thenReturn(1L); + UserVmVO vm = mock(UserVmVO.class); + when(userVmDaoMock.findById(1L)).thenReturn(vm); + when(vm.getState()).thenReturn(State.Running); + + volumeApiServiceImpl.validationsForCheckVolumeOperation(1L); + } + + @Test(expected = InvalidParameterValueException.class) + public void testValidationsForCheckVolumeAPIWithNonexistedVM() { + VolumeVO volume = mock(VolumeVO.class); + when(volumeDaoMock.findById(1L)).thenReturn(volume); + + AccountVO account = new AccountVO("admin", 1L, "networkDomain", Account.Type.NORMAL, "uuid"); + UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN); + CallContext.register(user, account); + + lenient().doNothing().when(accountManagerMock).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class)); + + when(volume.getInstanceId()).thenReturn(1L); + when(userVmDaoMock.findById(1L)).thenReturn(null); + + volumeApiServiceImpl.validationsForCheckVolumeOperation(1L); + } + + @Test(expected = InvalidParameterValueException.class) + public void testValidationsForCheckVolumeAPIWithAllocatedVolume() { + VolumeVO volume = mock(VolumeVO.class); + when(volumeDaoMock.findById(1L)).thenReturn(volume); + + AccountVO account = new AccountVO("admin", 1L, "networkDomain", Account.Type.NORMAL, "uuid"); + UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN); + CallContext.register(user, account); + + lenient().doNothing().when(accountManagerMock).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class)); + + when(volume.getInstanceId()).thenReturn(1L); + UserVmVO vm = mock(UserVmVO.class); + when(userVmDaoMock.findById(1L)).thenReturn(vm); + when(vm.getState()).thenReturn(State.Stopped); + when(volume.getState()).thenReturn(Volume.State.Allocated); + + volumeApiServiceImpl.validationsForCheckVolumeOperation(1L); + } + + @Test(expected = InvalidParameterValueException.class) + public void testValidationsForCheckVolumeAPIWithNonKVMhypervisor() { + VolumeVO volume = mock(VolumeVO.class); + when(volumeDaoMock.findById(1L)).thenReturn(volume); + + AccountVO account = new AccountVO("admin", 1L, "networkDomain", Account.Type.NORMAL, "uuid"); + UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN); + CallContext.register(user, account); + + lenient().doNothing().when(accountManagerMock).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class)); + + when(volume.getInstanceId()).thenReturn(1L); + UserVmVO vm = mock(UserVmVO.class); + when(userVmDaoMock.findById(1L)).thenReturn(vm); + when(vm.getState()).thenReturn(State.Stopped); + when(volume.getState()).thenReturn(Volume.State.Ready); + when(volume.getId()).thenReturn(1L); + when(volumeDaoMock.getHypervisorType(1L)).thenReturn(HypervisorType.VMware); + + volumeApiServiceImpl.validationsForCheckVolumeOperation(1L); + } + + @Test + public void testCheckAndRepairVolume() throws ResourceAllocationException { + + CheckVolumeAndRepairCmd cmd = mock(CheckVolumeAndRepairCmd.class); + when(cmd.getId()).thenReturn(1L); + when(cmd.getRepair()).thenReturn(false); + + VolumeVO volume = mock(VolumeVO.class); + when(volumeDaoMock.findById(1L)).thenReturn(volume); + + AccountVO account = new AccountVO("admin", 1L, "networkDomain", Account.Type.NORMAL, "uuid"); + UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN); + CallContext.register(user, account); + + lenient().doNothing().when(accountManagerMock).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class)); + + when(volume.getInstanceId()).thenReturn(null); + when(volume.getState()).thenReturn(Volume.State.Ready); + when(volume.getId()).thenReturn(1L); + when(volumeDaoMock.getHypervisorType(1L)).thenReturn(HypervisorType.KVM); + + VolumeInfo volumeInfo = mock(VolumeInfo.class); + when(volumeDataFactoryMock.getVolume(1L)).thenReturn(volumeInfo); + + String checkResult = "{\n" + + " \"image-end-offset\": 6442582016,\n" + + " \"total-clusters\": 163840,\n" + + " \"check-errors\": 0,\n" + + " \"leaks\": 124,\n" + + " \"allocated-clusters\": 98154,\n" + + " \"filename\": \"/var/lib/libvirt/images/26be20c7-b9d0-43f6-a76e-16c70737a0e0\",\n" + + " \"format\": \"qcow2\",\n" + + " \"fragmented-clusters\": 96135\n" + + "}"; + + String repairResult = null; + Pair<String, String> result = new Pair<>(checkResult, repairResult); + when(volumeServiceMock.checkAndRepairVolume(volumeInfo)).thenReturn(result); + + Pair<String, String> finalresult = volumeApiServiceImpl.checkAndRepairVolume(cmd); + + Assert.assertEquals(result, finalresult); + } }