This is an automated email from the ASF dual-hosted git repository.
dahn pushed a commit to branch 4.19
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.19 by this push:
new 802bf5fce7c Revert "server: fix attach uploaded volume (#10267)"
(#10323)
802bf5fce7c is described below
commit 802bf5fce7c57b38810308af6b8f75c3a37bab01
Author: dahn <[email protected]>
AuthorDate: Thu Feb 6 11:33:26 2025 +0100
Revert "server: fix attach uploaded volume (#10267)" (#10323)
This reverts commit 1c84ce4e23e3fd243022c6c533fc14c10439c6f3.
---
.../com/cloud/storage/VolumeApiServiceImpl.java | 123 ++++------
.../cloud/storage/VolumeApiServiceImplTest.java | 249 ---------------------
2 files changed, 42 insertions(+), 330 deletions(-)
diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
index 68546f185b7..7f867eb01a9 100644
--- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
@@ -133,9 +133,7 @@ import com.cloud.dc.ClusterDetailsDao;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.Pod;
-import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
import com.cloud.domain.Domain;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEvent;
@@ -155,7 +153,6 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.HypervisorCapabilitiesVO;
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
import com.cloud.offering.DiskOffering;
-import com.cloud.org.Cluster;
import com.cloud.org.Grouping;
import com.cloud.projects.Project;
import com.cloud.projects.ProjectManager;
@@ -326,8 +323,6 @@ public class VolumeApiServiceImpl extends ManagerBase
implements VolumeApiServic
@Inject
private VmWorkJobDao _workJobDao;
@Inject
- ClusterDao clusterDao;
- @Inject
private ClusterDetailsDao _clusterDetailsDao;
@Inject
private StorageManager storageMgr;
@@ -351,8 +346,6 @@ public class VolumeApiServiceImpl extends ManagerBase
implements VolumeApiServic
protected ProjectManager projectManager;
@Inject
protected StoragePoolDetailsDao storagePoolDetailsDao;
- @Inject
- HostPodDao podDao;
protected Gson _gson;
@@ -2387,10 +2380,17 @@ public class VolumeApiServiceImpl extends ManagerBase
implements VolumeApiServic
return attachVolumeToVM(command.getVirtualMachineId(),
command.getId(), command.getDeviceId());
}
- protected VolumeVO getVmExistingVolumeForVolumeAttach(UserVmVO vm,
VolumeInfo volumeToAttach) {
+ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long
deviceId) {
+ VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
+
+ if (volumeToAttach.isAttachedVM()) {
+ throw new CloudRuntimeException("This volume is already attached
to a VM.");
+ }
+
+ UserVmVO vm = _userVmDao.findById(vmId);
VolumeVO existingVolumeOfVm = null;
VMTemplateVO template = _templateDao.findById(vm.getTemplateId());
- List<VolumeVO> rootVolumesOfVm =
_volsDao.findByInstanceAndType(vm.getId(), Volume.Type.ROOT);
+ List<VolumeVO> rootVolumesOfVm = _volsDao.findByInstanceAndType(vmId,
Volume.Type.ROOT);
if (rootVolumesOfVm.size() > 1 && template != null &&
!template.isDeployAsIs()) {
throw new CloudRuntimeException("The VM " + vm.getHostName() + "
has more than one ROOT volume and is in an invalid state.");
} else {
@@ -2398,7 +2398,7 @@ public class VolumeApiServiceImpl extends ManagerBase
implements VolumeApiServic
existingVolumeOfVm = rootVolumesOfVm.get(0);
} else {
// locate data volume of the vm
- List<VolumeVO> diskVolumesOfVm =
_volsDao.findByInstanceAndType(vm.getId(), Volume.Type.DATADISK);
+ List<VolumeVO> diskVolumesOfVm =
_volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
for (VolumeVO diskVolume : diskVolumesOfVm) {
if (diskVolume.getState() != Volume.State.Allocated) {
existingVolumeOfVm = diskVolume;
@@ -2407,89 +2407,45 @@ public class VolumeApiServiceImpl extends ManagerBase
implements VolumeApiServic
}
}
}
- if (existingVolumeOfVm == null) {
- if (s_logger.isTraceEnabled()) {
- s_logger.trace(String.format("No existing volume found for VM
(%s/%s) to attach volume %s/%s",
+ if (s_logger.isTraceEnabled()) {
+ String msg = "attaching volume %s/%s to a VM (%s/%s) with an
existing volume %s/%s on primary storage %s";
+ if (existingVolumeOfVm != null) {
+ s_logger.trace(String.format(msg,
+ volumeToAttach.getName(), volumeToAttach.getUuid(),
vm.getName(), vm.getUuid(),
- volumeToAttach.getName(), volumeToAttach.getUuid()));
+ existingVolumeOfVm.getName(),
existingVolumeOfVm.getUuid(),
+ existingVolumeOfVm.getPoolId()));
}
- return null;
}
- if (s_logger.isTraceEnabled()) {
- String msg = "attaching volume %s/%s to a VM (%s/%s) with an
existing volume %s/%s on primary storage %s";
- s_logger.trace(String.format(msg,
- volumeToAttach.getName(), volumeToAttach.getUuid(),
- vm.getName(), vm.getUuid(),
- existingVolumeOfVm.getName(), existingVolumeOfVm.getUuid(),
- existingVolumeOfVm.getPoolId()));
- }
- return existingVolumeOfVm;
- }
-
- protected StoragePool getPoolForAllocatedOrUploadedVolumeForAttach(final
VolumeInfo volumeToAttach, final UserVmVO vm) {
- DataCenter zone = _dcDao.findById(vm.getDataCenterId());
- Pair<Long, Long> clusterHostId =
virtualMachineManager.findClusterAndHostIdForVm(vm, false);
- long podId = vm.getPodIdToDeployIn();
- if (clusterHostId.first() != null) {
- Cluster cluster = clusterDao.findById(clusterHostId.first());
- podId = cluster.getPodId();
- }
- Pod pod = podDao.findById(podId);
- DiskOfferingVO offering =
_diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- DiskProfile diskProfile = new DiskProfile(volumeToAttach.getId(),
volumeToAttach.getVolumeType(),
- volumeToAttach.getName(), volumeToAttach.getId(),
volumeToAttach.getSize(), offering.getTagsArray(),
- offering.isUseLocalStorage(), offering.isRecreatable(),
- volumeToAttach.getTemplateId());
- diskProfile.setHyperType(vm.getHypervisorType());
- StoragePool pool = _volumeMgr.findStoragePool(diskProfile, zone, pod,
clusterHostId.first(),
- clusterHostId.second(), vm, Collections.emptySet());
- if (pool == null) {
- throw new CloudRuntimeException(String.format("Failed to find a
primary storage for volume in state: %s", volumeToAttach.getState()));
- }
- return pool;
- }
-
- protected VolumeInfo createVolumeOnPrimaryForAttachIfNeeded(final
VolumeInfo volumeToAttach, final UserVmVO vm, VolumeVO existingVolumeOfVm) {
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType =
_volsDao.getHypervisorType(volumeToAttach.getId());
+
VolumeInfo newVolumeOnPrimaryStorage = volumeToAttach;
- boolean volumeOnSecondary = volumeToAttach.getState() ==
Volume.State.Uploaded;
- if (!Arrays.asList(Volume.State.Allocated,
Volume.State.Uploaded).contains(volumeToAttach.getState())) {
- return newVolumeOnPrimaryStorage;
- }
+
//don't create volume on primary storage if its being attached to the
vm which Root's volume hasn't been created yet
- StoragePool destPrimaryStorage = null;
+ StoragePoolVO destPrimaryStorage = null;
if (existingVolumeOfVm != null &&
!existingVolumeOfVm.getState().equals(Volume.State.Allocated)) {
destPrimaryStorage =
_storagePoolDao.findById(existingVolumeOfVm.getPoolId());
if (s_logger.isTraceEnabled() && destPrimaryStorage != null) {
s_logger.trace(String.format("decided on target storage:
%s/%s", destPrimaryStorage.getName(), destPrimaryStorage.getUuid()));
}
}
- if (destPrimaryStorage == null) {
- destPrimaryStorage =
getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
- }
- try {
- if (volumeOnSecondary &&
Storage.StoragePoolType.PowerFlex.equals(destPrimaryStorage.getPoolType())) {
- throw new InvalidParameterValueException("Cannot attach
uploaded volume, this operation is unsupported on storage pool type " +
destPrimaryStorage.getPoolType());
- }
- newVolumeOnPrimaryStorage =
_volumeMgr.createVolumeOnPrimaryStorage(vm, volumeToAttach,
- vm.getHypervisorType(), destPrimaryStorage);
- } catch (NoTransitionException e) {
- s_logger.debug("Failed to create volume on primary storage", e);
- throw new CloudRuntimeException("Failed to create volume on
primary storage", e);
- }
- return newVolumeOnPrimaryStorage;
- }
- private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long
deviceId) {
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
+ boolean volumeOnSecondary = volumeToAttach.getState() ==
Volume.State.Uploaded;
- if (volumeToAttach.isAttachedVM()) {
- throw new CloudRuntimeException("This volume is already attached
to a VM.");
+ if (destPrimaryStorage != null && (volumeToAttach.getState() ==
Volume.State.Allocated || volumeOnSecondary)) {
+ try {
+ if (volumeOnSecondary && destPrimaryStorage.getPoolType() ==
Storage.StoragePoolType.PowerFlex) {
+ throw new InvalidParameterValueException("Cannot attach
uploaded volume, this operation is unsupported on storage pool type " +
destPrimaryStorage.getPoolType());
+ }
+ newVolumeOnPrimaryStorage =
_volumeMgr.createVolumeOnPrimaryStorage(vm, volumeToAttach, rootDiskHyperType,
destPrimaryStorage);
+ } catch (NoTransitionException e) {
+ s_logger.debug("Failed to create volume on primary storage",
e);
+ throw new CloudRuntimeException("Failed to create volume on
primary storage", e);
+ }
}
- UserVmVO vm = _userVmDao.findById(vmId);
- VolumeVO existingVolumeOfVm = getVmExistingVolumeForVolumeAttach(vm,
volumeToAttach);
- VolumeInfo newVolumeOnPrimaryStorage =
createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm, existingVolumeOfVm);
-
// reload the volume from db
newVolumeOnPrimaryStorage =
volFactory.getVolume(newVolumeOnPrimaryStorage.getId());
boolean moveVolumeNeeded = needMoveVolume(existingVolumeOfVm,
newVolumeOnPrimaryStorage);
@@ -2507,17 +2463,19 @@ public class VolumeApiServiceImpl extends ManagerBase
implements VolumeApiServic
StoragePoolVO vmRootVolumePool =
_storagePoolDao.findById(existingVolumeOfVm.getPoolId());
try {
- HypervisorType volumeToAttachHyperType =
_volsDao.getHypervisorType(volumeToAttach.getId());
newVolumeOnPrimaryStorage =
_volumeMgr.moveVolume(newVolumeOnPrimaryStorage,
vmRootVolumePool.getDataCenterId(), vmRootVolumePool.getPodId(),
vmRootVolumePool.getClusterId(),
volumeToAttachHyperType);
- } catch (ConcurrentOperationException |
StorageUnavailableException e) {
+ } catch (ConcurrentOperationException e) {
+ s_logger.debug("move volume failed", e);
+ throw new CloudRuntimeException("move volume failed", e);
+ } catch (StorageUnavailableException e) {
s_logger.debug("move volume failed", e);
throw new CloudRuntimeException("move volume failed", e);
}
}
VolumeVO newVol = _volsDao.findById(newVolumeOnPrimaryStorage.getId());
// Getting the fresh vm object in case of volume migration to check
the current state of VM
- if (moveVolumeNeeded) {
+ if (moveVolumeNeeded || volumeOnSecondary) {
vm = _userVmDao.findById(vmId);
if (vm == null) {
throw new InvalidParameterValueException("VM not found.");
@@ -2701,6 +2659,9 @@ public class VolumeApiServiceImpl extends ManagerBase
implements VolumeApiServic
if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
throw new InvalidParameterValueException("Vm already has root
volume attached to it");
}
+ if (volumeToAttach.getState() == Volume.State.Uploaded) {
+ throw new InvalidParameterValueException("No support for Root
volume attach in state " + Volume.State.Uploaded);
+ }
}
}
diff --git
a/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java
b/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java
index 3e6f9ec63f9..a0f89956df5 100644
--- a/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java
+++ b/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java
@@ -45,7 +45,6 @@ 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;
import org.apache.cloudstack.context.CallContext;
-import
org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
@@ -87,12 +86,8 @@ import org.springframework.test.util.ReflectionTestUtils;
import com.cloud.api.query.dao.ServiceOfferingJoinDao;
import com.cloud.configuration.Resource;
import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
import com.cloud.event.EventTypes;
import com.cloud.event.UsageEventUtils;
import com.cloud.exception.InvalidParameterValueException;
@@ -127,12 +122,10 @@ import com.cloud.utils.Pair;
import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.vm.DiskProfile;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.snapshot.VMSnapshotVO;
@@ -206,15 +199,6 @@ public class VolumeApiServiceImplTest {
private DataStoreManager dataStoreMgr;
@Mock
private SnapshotHelper snapshotHelper;
- @Mock
- VirtualMachineManager virtualMachineManager;
- @Mock
- HostPodDao podDao;
- @Mock
- ClusterDao clusterDao;
- @Mock
- VolumeOrchestrationService volumeOrchestrationService;
-
private DetachVolumeCmd detachCmd = new DetachVolumeCmd();
private Class<?> _detachCmdClass = detachCmd.getClass();
@@ -1836,237 +1820,4 @@ public class VolumeApiServiceImplTest {
volumeApiServiceImpl.validationsForCheckVolumeOperation(volume);
}
-
- private UserVmVO getMockedVm() {
- UserVmVO vm = Mockito.mock(UserVmVO.class);
- Mockito.when(vm.getId()).thenReturn(1L);
- Mockito.when(vm.getTemplateId()).thenReturn(10L);
- Mockito.when(vm.getHostName()).thenReturn("test-vm");
- return vm;
- }
-
- private VMTemplateVO getMockedTemplate() {
- VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
- Mockito.when(template.isDeployAsIs()).thenReturn(false);
- return template;
- }
-
- @Test(expected = CloudRuntimeException.class)
- public void
testGetVmExistingVolumeForVolumeAttach_MultipleRootVolumes_ThrowsException() {
- UserVmVO vm = getMockedVm();
- VMTemplateVO template = getMockedTemplate();
- when(templateDao.findById(10L)).thenReturn(template);
- when(volumeDaoMock.findByInstanceAndType(1L, Volume.Type.ROOT))
- .thenReturn(Arrays.asList(Mockito.mock(VolumeVO.class),
Mockito.mock(VolumeVO.class)));
- volumeApiServiceImpl.getVmExistingVolumeForVolumeAttach(vm,
Mockito.mock(VolumeInfo.class));
- }
-
- @Test
- public void testGetVmExistingVolumeForVolumeAttach_SingleRootVolume() {
- UserVmVO vm = getMockedVm();
- VMTemplateVO template = getMockedTemplate();
- VolumeVO rootVolume = Mockito.mock(VolumeVO.class);
- Mockito.when(rootVolume.getId()).thenReturn(20L);
- Mockito.when(templateDao.findById(10L)).thenReturn(template);
- Mockito.when(volumeDaoMock.findByInstanceAndType(1L, Volume.Type.ROOT))
- .thenReturn(Collections.singletonList(rootVolume));
- VolumeVO result =
volumeApiServiceImpl.getVmExistingVolumeForVolumeAttach(vm,
Mockito.mock(VolumeInfo.class));
- Assert.assertNotNull(result);
- Assert.assertEquals(20L, result.getId());
- }
-
- private VolumeVO getMockedDataVolume() {
- VolumeVO volume = Mockito.mock(VolumeVO.class);
- Mockito.when(volume.getId()).thenReturn(30L);
- Mockito.when(volume.getState()).thenReturn(Volume.State.Ready);
- return volume;
- }
-
- @Test
- public void
testGetVmExistingVolumeForVolumeAttach_NoRootVolume_DataDiskAvailable() {
- UserVmVO vm = getMockedVm();
- VMTemplateVO template = getMockedTemplate();
- VolumeVO dataDisk = getMockedDataVolume();
- List<VolumeVO> rootVolumes = Collections.emptyList();
- List<VolumeVO> dataVolumes = Collections.singletonList(dataDisk);
- Mockito.when(templateDao.findById(10L)).thenReturn(template);
- Mockito.when(volumeDaoMock.findByInstanceAndType(1L,
Volume.Type.ROOT)).thenReturn(rootVolumes);
- Mockito.when(volumeDaoMock.findByInstanceAndType(1L,
Volume.Type.DATADISK)).thenReturn(dataVolumes);
- VolumeVO result =
volumeApiServiceImpl.getVmExistingVolumeForVolumeAttach(vm,
Mockito.mock(VolumeInfo.class));
- Assert.assertNotNull(result);
- Assert.assertEquals(30L, result.getId());
- }
-
- @Test
- public void testGetVmExistingVolumeForVolumeAttach_NoVolumesAtAll() {
- UserVmVO vm = getMockedVm();
- VMTemplateVO template = getMockedTemplate();
- Mockito.when(templateDao.findById(10L)).thenReturn(template);
- Mockito.when(volumeDaoMock.findByInstanceAndType(1L,
Volume.Type.ROOT)).thenReturn(Collections.emptyList());
- Mockito.when(volumeDaoMock.findByInstanceAndType(1L,
Volume.Type.DATADISK)).thenReturn(Collections.emptyList());
- VolumeVO result =
volumeApiServiceImpl.getVmExistingVolumeForVolumeAttach(vm,
Mockito.mock(VolumeInfo.class));
- Assert.assertNull(result);
- }
-
- private void mockDiskOffering() {
- DiskOfferingVO offering = Mockito.mock(DiskOfferingVO.class);
- Mockito.when(_diskOfferingDao.findById(1L)).thenReturn(offering);
- Mockito.when(offering.isUseLocalStorage()).thenReturn(true);
- Mockito.when(offering.isRecreatable()).thenReturn(false);
- }
-
- private DataCenterVO mockZone() {
- DataCenterVO zone = Mockito.mock(DataCenterVO.class);
- Mockito.when(_dcDao.findById(1L)).thenReturn(zone);
- return zone;
- }
-
- @Test
- public void testGetPoolForAllocatedOrUploadedVolumeForAttach_Success() {
- VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
- UserVmVO vm = Mockito.mock(UserVmVO.class);
- ClusterVO cluster = Mockito.mock(ClusterVO.class);
- HostPodVO pod = Mockito.mock(HostPodVO.class);
- DataCenterVO zone = mockZone();
- mockDiskOffering();
- StoragePool pool = Mockito.mock(StoragePool.class);
- when(vm.getDataCenterId()).thenReturn(1L);
- when(virtualMachineManager.findClusterAndHostIdForVm(vm,
false)).thenReturn(new Pair<>(1L, 2L));
- when(clusterDao.findById(1L)).thenReturn(cluster);
- when(cluster.getPodId()).thenReturn(1L);
- when(podDao.findById(1L)).thenReturn(pod);
- when(volumeToAttach.getDiskOfferingId()).thenReturn(1L);
-
when(volumeOrchestrationService.findStoragePool(any(DiskProfile.class),
eq(zone), eq(pod), eq(1L), eq(2L), eq(vm), eq(Collections.emptySet())))
- .thenReturn(pool);
- StoragePool result =
volumeApiServiceImpl.getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach,
vm);
- Assert.assertNotNull(result);
- Assert.assertEquals(pool, result);
- }
-
- @Test(expected = CloudRuntimeException.class)
- public void
testGetPoolForAllocatedOrUploadedVolumeForAttach_NoPoolFound_ThrowsException() {
- VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
- UserVmVO vm = Mockito.mock(UserVmVO.class);
- DataCenterVO zone = mockZone();
- Pair<Long, Long> clusterHostId = new Pair<>(1L, 2L);
- ClusterVO cluster = Mockito.mock(ClusterVO.class);
- HostPodVO pod = Mockito.mock(HostPodVO.class);
- mockDiskOffering();
- when(vm.getDataCenterId()).thenReturn(1L);
- when(clusterDao.findById(1L)).thenReturn(cluster);
- when(virtualMachineManager.findClusterAndHostIdForVm(vm,
false)).thenReturn(clusterHostId);
- when(podDao.findById(anyLong())).thenReturn(pod);
- when(volumeToAttach.getDiskOfferingId()).thenReturn(1L);
-
when(volumeOrchestrationService.findStoragePool(any(DiskProfile.class),
eq(zone), eq(pod), eq(1L), eq(2L), eq(vm), eq(Collections.emptySet())))
- .thenReturn(null);
-
volumeApiServiceImpl.getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach,
vm);
- }
-
- @Test
- public void testGetPoolForAllocatedOrUploadedVolumeForAttach_NoCluster() {
- VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
- UserVmVO vm = Mockito.mock(UserVmVO.class);
- DataCenterVO zone = mockZone();
- HostPodVO pod = Mockito.mock(HostPodVO.class);
- mockDiskOffering();
- StoragePool pool = Mockito.mock(StoragePool.class);
- when(vm.getDataCenterId()).thenReturn(1L);
- when(vm.getPodIdToDeployIn()).thenReturn(2L);
- when(virtualMachineManager.findClusterAndHostIdForVm(vm,
false)).thenReturn(new Pair<>(null, 2L));
- when(podDao.findById(2L)).thenReturn(pod);
- when(volumeToAttach.getDiskOfferingId()).thenReturn(1L);
-
when(volumeOrchestrationService.findStoragePool(any(DiskProfile.class),
eq(zone), eq(pod), eq(null), eq(2L), eq(vm), eq(Collections.emptySet())))
- .thenReturn(pool);
- StoragePool result =
volumeApiServiceImpl.getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach,
vm);
- Assert.assertNotNull(result);
- Assert.assertEquals(pool, result);
- }
-
-
- @Test
- public void
testCreateVolumeOnSecondaryForAttachIfNeeded_VolumeNotAllocatedOrUploaded() {
- VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
- Mockito.when(volumeToAttach.getState()).thenReturn(Volume.State.Ready);
- VolumeInfo result =
volumeApiServiceImpl.createVolumeOnPrimaryForAttachIfNeeded(
- volumeToAttach, Mockito.mock(UserVmVO.class), null);
- Assert.assertSame(volumeToAttach, result);
- Mockito.verifyNoInteractions(primaryDataStoreDaoMock,
volumeOrchestrationService);
- }
-
- @Test
- public void
testCreateVolumeOnSecondaryForAttachIfNeeded_ExistingVolumeDeterminesStoragePool()
{
- VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
-
Mockito.when(volumeToAttach.getState()).thenReturn(Volume.State.Uploaded);
- UserVmVO vm = Mockito.mock(UserVmVO.class);
- VolumeVO existingVolume = Mockito.mock(VolumeVO.class);
- Mockito.when(existingVolume.getState()).thenReturn(Volume.State.Ready);
- when(existingVolume.getPoolId()).thenReturn(1L);
- StoragePoolVO destPrimaryStorage = Mockito.mock(StoragePoolVO.class);
-
Mockito.when(destPrimaryStorage.getPoolType()).thenReturn(Storage.StoragePoolType.NetworkFilesystem);
-
Mockito.when(primaryDataStoreDaoMock.findById(1L)).thenReturn(destPrimaryStorage);
- VolumeInfo newVolumeOnPrimaryStorage = Mockito.mock(VolumeInfo.class);
- try {
-
Mockito.when(volumeOrchestrationService.createVolumeOnPrimaryStorage(vm,
volumeToAttach, vm.getHypervisorType(), destPrimaryStorage))
- .thenReturn(newVolumeOnPrimaryStorage);
- } catch (NoTransitionException nte) {
- Assert.fail(nte.getMessage());
- }
- VolumeInfo result =
volumeApiServiceImpl.createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm,
existingVolume);
- Assert.assertSame(newVolumeOnPrimaryStorage, result);
- Mockito.verify(primaryDataStoreDaoMock).findById(1L);
- }
-
- @Test
- public void
testCreateVolumeOnPrimaryForAttachIfNeeded_UsesGetPoolForAttach() {
- VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
-
Mockito.when(volumeToAttach.getState()).thenReturn(Volume.State.Allocated);
- UserVmVO vm = Mockito.mock(UserVmVO.class);
- StoragePool destPrimaryStorage = Mockito.mock(StoragePool.class);
- Mockito.doReturn(destPrimaryStorage).when(volumeApiServiceImpl)
- .getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach,
vm);
- VolumeInfo newVolumeOnPrimaryStorage = Mockito.mock(VolumeInfo.class);
- try {
-
Mockito.when(volumeOrchestrationService.createVolumeOnPrimaryStorage(
- vm, volumeToAttach, vm.getHypervisorType(),
destPrimaryStorage))
- .thenReturn(newVolumeOnPrimaryStorage);
- } catch (NoTransitionException nte) {
- Assert.fail(nte.getMessage());
- }
- VolumeInfo result =
volumeApiServiceImpl.createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm,
null);
- Assert.assertSame(newVolumeOnPrimaryStorage, result);
-
verify(volumeApiServiceImpl).getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach,
vm);
- }
-
- @Test(expected = InvalidParameterValueException.class)
- public void
testCreateVolumeOnPrimaryForAttachIfNeeded_UnsupportedPoolType_ThrowsException()
{
- VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
- when(volumeToAttach.getState()).thenReturn(Volume.State.Uploaded);
- UserVmVO vm = Mockito.mock(UserVmVO.class);
- StoragePool destPrimaryStorage = Mockito.mock(StoragePool.class);
-
when(destPrimaryStorage.getPoolType()).thenReturn(Storage.StoragePoolType.PowerFlex);
- Mockito.doReturn(destPrimaryStorage).when(volumeApiServiceImpl)
- .getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach,
vm);
-
volumeApiServiceImpl.createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm,
null);
- }
-
- @Test
- public void
testCreateVolumeOnSecondaryForAttachIfNeeded_CreateVolumeFails_ThrowsException()
{
- VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
-
Mockito.when(volumeToAttach.getState()).thenReturn(Volume.State.Uploaded);
- UserVmVO vm = Mockito.mock(UserVmVO.class);
- StoragePool destPrimaryStorage = Mockito.mock(StoragePool.class);
-
Mockito.when(destPrimaryStorage.getPoolType()).thenReturn(Storage.StoragePoolType.NetworkFilesystem);
- Mockito.doReturn(destPrimaryStorage).when(volumeApiServiceImpl)
- .getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach,
vm);
- try {
-
Mockito.when(volumeOrchestrationService.createVolumeOnPrimaryStorage(vm,
volumeToAttach, vm.getHypervisorType(), destPrimaryStorage))
- .thenThrow(new NoTransitionException("Mocked exception"));
- } catch (NoTransitionException nte) {
- Assert.fail(nte.getMessage());
- }
- CloudRuntimeException exception =
Assert.assertThrows(CloudRuntimeException.class, () ->
-
volumeApiServiceImpl.createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm,
null)
- );
- Assert.assertTrue(exception.getMessage().contains("Failed to create
volume on primary storage"));
- }
}