This is an automated email from the ASF dual-hosted git repository.
dahn pushed a commit to branch 4.18
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.18 by this push:
new e65c9ffe700 Fix: Select another pod if all hosts in the pod becomes
unavailable (#8085)
e65c9ffe700 is described below
commit e65c9ffe70059b51a327a4d05f47a73a4ea411fd
Author: Vishesh <[email protected]>
AuthorDate: Tue Nov 7 19:41:00 2023 +0530
Fix: Select another pod if all hosts in the pod becomes unavailable (#8085)
---
.../com/cloud/vm/VirtualMachineManagerImpl.java | 21 +-
.../cloud/vm/VirtualMachineManagerImplTest.java | 302 ++++++++++++++++++---
2 files changed, 283 insertions(+), 40 deletions(-)
diff --git
a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java
b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java
index ca453ed0de1..7792afd2c63 100755
---
a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java
+++
b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -569,7 +569,7 @@ public class VirtualMachineManagerImpl extends ManagerBase
implements VirtualMac
allocate(vmInstanceName, template, serviceOffering, new
DiskOfferingInfo(diskOffering), new ArrayList<>(), networks, plan, hyperType,
null, null);
}
- private VirtualMachineGuru getVmGuru(final VirtualMachine vm) {
+ VirtualMachineGuru getVmGuru(final VirtualMachine vm) {
if(vm != null) {
return _vmGurus.get(vm.getType());
}
@@ -1443,6 +1443,7 @@ public class VirtualMachineManagerImpl extends
ManagerBase implements VirtualMac
}
if (canRetry) {
try {
+ conditionallySetPodToDeployIn(vm);
changeState(vm, Event.OperationFailed, null, work,
Step.Done);
} catch (final NoTransitionException e) {
throw new ConcurrentOperationException(e.getMessage());
@@ -1460,6 +1461,24 @@ public class VirtualMachineManagerImpl extends
ManagerBase implements VirtualMac
}
}
+ /**
+ * Setting pod id to null can result in migration of Volumes across pods.
This is not desirable for VMs which
+ * have a volume in Ready state (happens when a VM is shutdown and started
again).
+ * So, we set it to null only when
+ * migration of VM across cluster is enabled
+ * Or, volumes are still in allocated state for that VM (happens when VM
is Starting/deployed for the first time)
+ */
+ private void conditionallySetPodToDeployIn(VMInstanceVO vm) {
+ if (MIGRATE_VM_ACROSS_CLUSTERS.valueIn(vm.getDataCenterId()) ||
areAllVolumesAllocated(vm.getId())) {
+ vm.setPodIdToDeployIn(null);
+ }
+ }
+
+ boolean areAllVolumesAllocated(long vmId) {
+ final List<VolumeVO> vols = _volsDao.findByInstance(vmId);
+ return CollectionUtils.isEmpty(vols) || vols.stream().allMatch(v ->
Volume.State.Allocated.equals(v.getState()));
+ }
+
private void logBootModeParameters(Map<VirtualMachineProfile.Param,
Object> params) {
if (params == null) {
return;
diff --git
a/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java
b/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java
index 15a2f2c0ac1..20af10ed338 100644
---
a/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java
+++
b/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java
@@ -19,9 +19,12 @@ package com.cloud.vm;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
@@ -35,6 +38,23 @@ import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.ClusterDetailsVO;
+import com.cloud.dc.Pod;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlanningManager;
+import com.cloud.hypervisor.HypervisorGuruManager;
+import com.cloud.org.Cluster;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+import com.cloud.user.User;
+import com.cloud.utils.Journal;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.vm.dao.UserVmDetailsDao;
+import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
@@ -49,7 +69,6 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.stubbing.Answer;
-import org.mockito.runners.MockitoJUnitRunner;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Command;
@@ -88,13 +107,20 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
-
-@RunWith(MockitoJUnitRunner.class)
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.springframework.test.util.ReflectionTestUtils;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(CallContext.class)
+@PowerMockIgnore({"javax.xml.*", "org.w3c.dom.*", "org.apache.xerces.*",
"org.xml.*"})
public class VirtualMachineManagerImplTest {
@Spy
@InjectMocks
- private VirtualMachineManagerImpl virtualMachineManagerImpl;
+ private VirtualMachineManagerImpl virtualMachineManagerImpl = new
VirtualMachineManagerImpl();
@Mock
private AgentManager agentManagerMock;
@Mock
@@ -155,6 +181,20 @@ public class VirtualMachineManagerImplTest {
private UserVmDao userVmDaoMock;
@Mock
private UserVmVO userVmMock;
+ @Mock
+ private EntityManager _entityMgr;
+ @Mock
+ private DeploymentPlanningManager _dpMgr;
+ @Mock
+ private HypervisorGuruManager _hvGuruMgr;
+ @Mock
+ private ClusterDetailsDao _clusterDetailsDao;
+ @Mock
+ private UserVmDetailsDao userVmDetailsDao;
+ @Mock
+ private ItWorkDao _workDao;
+ @Mock
+ protected StateMachine2<State, VirtualMachine.Event, VirtualMachine>
_stateMachine;
@Before
public void setup() {
@@ -433,7 +473,7 @@ public class VirtualMachineManagerImplTest {
HashMap<Long, Long> userDefinedVolumeToStoragePoolMap = new
HashMap<>();
userDefinedVolumeToStoragePoolMap.put(volumeMockId,
storagePoolVoMockId);
-
Mockito.doNothing().when(virtualMachineManagerImpl).executeManagedStorageChecksWhenTargetStoragePoolProvided(Mockito.any(StoragePoolVO.class),
Mockito.any(VolumeVO.class), Mockito.any(StoragePoolVO.class));
+
Mockito.doNothing().when(virtualMachineManagerImpl).executeManagedStorageChecksWhenTargetStoragePoolProvided(any(StoragePoolVO.class),
any(VolumeVO.class), any(StoragePoolVO.class));
Mockito.doReturn(null).when(storagePoolHostDaoMock).findByPoolHost(storagePoolVoMockId,
hostMockId);
virtualMachineManagerImpl.buildMapUsingUserInformation(virtualMachineProfileMock,
hostMock, userDefinedVolumeToStoragePoolMap);
@@ -445,8 +485,8 @@ public class VirtualMachineManagerImplTest {
HashMap<Long, Long> userDefinedVolumeToStoragePoolMap =
Mockito.spy(new HashMap<>());
userDefinedVolumeToStoragePoolMap.put(volumeMockId,
storagePoolVoMockId);
-
Mockito.doNothing().when(virtualMachineManagerImpl).executeManagedStorageChecksWhenTargetStoragePoolProvided(Mockito.any(StoragePoolVO.class),
Mockito.any(VolumeVO.class),
- Mockito.any(StoragePoolVO.class));
+
Mockito.doNothing().when(virtualMachineManagerImpl).executeManagedStorageChecksWhenTargetStoragePoolProvided(any(StoragePoolVO.class),
any(VolumeVO.class),
+ any(StoragePoolVO.class));
Mockito.doReturn(Mockito.mock(StoragePoolHostVO.class)).when(storagePoolHostDaoMock).findByPoolHost(storagePoolVoMockId,
hostMockId);
Map<Volume, StoragePool> volumeToPoolObjectMap =
virtualMachineManagerImpl.buildMapUsingUserInformation(virtualMachineProfileMock,
hostMock, userDefinedVolumeToStoragePoolMap);
@@ -482,7 +522,7 @@ public class VirtualMachineManagerImplTest {
virtualMachineManagerImpl.executeManagedStorageChecksWhenTargetStoragePoolNotProvided(hostMock,
storagePoolVoMock, volumeVoMock);
Mockito.verify(storagePoolVoMock).isManaged();
- Mockito.verify(storagePoolHostDaoMock,
Mockito.times(0)).findByPoolHost(Mockito.anyLong(), Mockito.anyLong());
+ Mockito.verify(storagePoolHostDaoMock,
Mockito.times(0)).findByPoolHost(anyLong(), anyLong());
}
@Test
@@ -506,15 +546,15 @@ public class VirtualMachineManagerImplTest {
@Test
public void getCandidateStoragePoolsToMigrateLocalVolumeTestLocalVolume() {
-
Mockito.doReturn(Mockito.mock(DiskOfferingVO.class)).when(diskOfferingDaoMock).findById(Mockito.anyLong());
+
Mockito.doReturn(Mockito.mock(DiskOfferingVO.class)).when(diskOfferingDaoMock).findById(anyLong());
Mockito.doReturn(true).when(storagePoolVoMock).isLocal();
List<StoragePool> poolListMock = new ArrayList<>();
poolListMock.add(storagePoolVoMock);
-
Mockito.doReturn(poolListMock).when(storagePoolAllocatorMock).allocateToPool(Mockito.any(DiskProfile.class),
Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
- Mockito.any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+
Mockito.doReturn(poolListMock).when(storagePoolAllocatorMock).allocateToPool(any(DiskProfile.class),
any(VirtualMachineProfile.class), any(DeploymentPlan.class),
+ any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
List<StoragePool> poolList =
virtualMachineManagerImpl.getCandidateStoragePoolsToMigrateLocalVolume(virtualMachineProfileMock,
dataCenterDeploymentMock, volumeVoMock);
@@ -524,15 +564,15 @@ public class VirtualMachineManagerImplTest {
@Test
public void
getCandidateStoragePoolsToMigrateLocalVolumeTestCrossClusterMigration() {
-
Mockito.doReturn(Mockito.mock(DiskOfferingVO.class)).when(diskOfferingDaoMock).findById(Mockito.anyLong());
+
Mockito.doReturn(Mockito.mock(DiskOfferingVO.class)).when(diskOfferingDaoMock).findById(anyLong());
Mockito.doReturn(false).when(storagePoolVoMock).isLocal();
List<StoragePool> poolListMock = new ArrayList<>();
poolListMock.add(storagePoolVoMock);
-
Mockito.doReturn(poolListMock).when(storagePoolAllocatorMock).allocateToPool(Mockito.any(DiskProfile.class),
Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
- Mockito.any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+
Mockito.doReturn(poolListMock).when(storagePoolAllocatorMock).allocateToPool(any(DiskProfile.class),
any(VirtualMachineProfile.class), any(DeploymentPlan.class),
+ any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
Mockito.doReturn(true).when(virtualMachineManagerImpl).isStorageCrossClusterMigration(clusterMockId,
storagePoolVoMock);
List<StoragePool> poolList =
virtualMachineManagerImpl.getCandidateStoragePoolsToMigrateLocalVolume(virtualMachineProfileMock,
dataCenterDeploymentMock, volumeVoMock);
@@ -543,15 +583,15 @@ public class VirtualMachineManagerImplTest {
@Test
public void
getCandidateStoragePoolsToMigrateLocalVolumeTestWithinClusterMigration() {
-
Mockito.doReturn(Mockito.mock(DiskOfferingVO.class)).when(diskOfferingDaoMock).findById(Mockito.anyLong());
+
Mockito.doReturn(Mockito.mock(DiskOfferingVO.class)).when(diskOfferingDaoMock).findById(anyLong());
Mockito.doReturn(false).when(storagePoolVoMock).isLocal();
List<StoragePool> poolListMock = new ArrayList<>();
poolListMock.add(storagePoolVoMock);
-
Mockito.doReturn(poolListMock).when(storagePoolAllocatorMock).allocateToPool(Mockito.any(DiskProfile.class),
Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
- Mockito.any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+
Mockito.doReturn(poolListMock).when(storagePoolAllocatorMock).allocateToPool(any(DiskProfile.class),
any(VirtualMachineProfile.class), any(DeploymentPlan.class),
+ any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
Mockito.doReturn(false).when(virtualMachineManagerImpl).isStorageCrossClusterMigration(clusterMockId,
storagePoolVoMock);
List<StoragePool> poolList =
virtualMachineManagerImpl.getCandidateStoragePoolsToMigrateLocalVolume(virtualMachineProfileMock,
dataCenterDeploymentMock, volumeVoMock);
@@ -571,33 +611,33 @@ public class VirtualMachineManagerImplTest {
virtualMachineManagerImpl.setStoragePoolAllocators(storagePoolAllocatorsMock);
-
Mockito.doReturn(Mockito.mock(DiskOfferingVO.class)).when(diskOfferingDaoMock).findById(Mockito.anyLong());
+
Mockito.doReturn(Mockito.mock(DiskOfferingVO.class)).when(diskOfferingDaoMock).findById(anyLong());
Mockito.doReturn(false).when(storagePoolVoMock).isLocal();
List<StoragePool> poolListMock = new ArrayList<>();
poolListMock.add(storagePoolVoMock);
-
Mockito.doReturn(poolListMock).when(storagePoolAllocatorMock).allocateToPool(Mockito.any(DiskProfile.class),
Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
- Mockito.any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+
Mockito.doReturn(poolListMock).when(storagePoolAllocatorMock).allocateToPool(any(DiskProfile.class),
any(VirtualMachineProfile.class), any(DeploymentPlan.class),
+ any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
-
Mockito.doReturn(null).when(storagePoolAllocatorMock2).allocateToPool(Mockito.any(DiskProfile.class),
Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
- Mockito.any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+
Mockito.doReturn(null).when(storagePoolAllocatorMock2).allocateToPool(any(DiskProfile.class),
any(VirtualMachineProfile.class), any(DeploymentPlan.class),
+ any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
- Mockito.doReturn(new
ArrayList<>()).when(storagePoolAllocatorMock3).allocateToPool(Mockito.any(DiskProfile.class),
Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
- Mockito.any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+ Mockito.doReturn(new
ArrayList<>()).when(storagePoolAllocatorMock3).allocateToPool(any(DiskProfile.class),
any(VirtualMachineProfile.class), any(DeploymentPlan.class),
+ any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
Mockito.doReturn(false).when(virtualMachineManagerImpl).isStorageCrossClusterMigration(clusterMockId,
storagePoolVoMock);
List<StoragePool> poolList =
virtualMachineManagerImpl.getCandidateStoragePoolsToMigrateLocalVolume(virtualMachineProfileMock,
dataCenterDeploymentMock, volumeVoMock);
Assert.assertTrue(poolList.isEmpty());
-
Mockito.verify(storagePoolAllocatorMock).allocateToPool(Mockito.any(DiskProfile.class),
Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
- Mockito.any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
-
Mockito.verify(storagePoolAllocatorMock2).allocateToPool(Mockito.any(DiskProfile.class),
Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
- Mockito.any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
-
Mockito.verify(storagePoolAllocatorMock3).allocateToPool(Mockito.any(DiskProfile.class),
Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
- Mockito.any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+
Mockito.verify(storagePoolAllocatorMock).allocateToPool(any(DiskProfile.class),
any(VirtualMachineProfile.class), any(DeploymentPlan.class),
+ any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+
Mockito.verify(storagePoolAllocatorMock2).allocateToPool(any(DiskProfile.class),
any(VirtualMachineProfile.class), any(DeploymentPlan.class),
+ any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+
Mockito.verify(storagePoolAllocatorMock3).allocateToPool(any(DiskProfile.class),
any(VirtualMachineProfile.class), any(DeploymentPlan.class),
+ any(ExcludeList.class),
Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
}
@Test(expected = CloudRuntimeException.class)
@@ -686,8 +726,8 @@ public class VirtualMachineManagerImplTest {
HashMap<Volume, StoragePool> volumeToPoolObjectMap = new HashMap<>();
Mockito.doReturn(ScopeType.CLUSTER).when(storagePoolVoMock).getScope();
-
Mockito.doNothing().when(virtualMachineManagerImpl).executeManagedStorageChecksWhenTargetStoragePoolNotProvided(Mockito.any(),
Mockito.any(), Mockito.any());
-
Mockito.doReturn(false).when(virtualMachineManagerImpl).isStorageCrossClusterMigration(Mockito.anyLong(),
Mockito.any());
+
Mockito.doNothing().when(virtualMachineManagerImpl).executeManagedStorageChecksWhenTargetStoragePoolNotProvided(any(),
any(), any());
+
Mockito.doReturn(false).when(virtualMachineManagerImpl).isStorageCrossClusterMigration(anyLong(),
any());
virtualMachineManagerImpl.createStoragePoolMappingsForVolumes(virtualMachineProfileMock,
dataCenterDeploymentMock, volumeToPoolObjectMap, allVolumes);
@@ -710,7 +750,7 @@ public class VirtualMachineManagerImplTest {
Mockito.doReturn(volumesNotMapped).when(virtualMachineManagerImpl).findVolumesThatWereNotMappedByTheUser(virtualMachineProfileMock,
volumeToPoolObjectMap);
Mockito.doNothing().when(virtualMachineManagerImpl).createStoragePoolMappingsForVolumes(Mockito.eq(virtualMachineProfileMock),
- Mockito.any(DataCenterDeployment.class),
Mockito.eq(volumeToPoolObjectMap), Mockito.eq(volumesNotMapped));
+ any(DataCenterDeployment.class),
Mockito.eq(volumeToPoolObjectMap), Mockito.eq(volumesNotMapped));
Map<Volume, StoragePool> mappingVolumeAndStoragePool =
virtualMachineManagerImpl.createMappingVolumeAndStoragePool(virtualMachineProfileMock,
hostMock, new HashMap<>());
@@ -720,7 +760,7 @@ public class VirtualMachineManagerImplTest {
inOrder.verify(virtualMachineManagerImpl).buildMapUsingUserInformation(Mockito.eq(virtualMachineProfileMock),
Mockito.eq(hostMock), Mockito.anyMapOf(Long.class, Long.class));
inOrder.verify(virtualMachineManagerImpl).findVolumesThatWereNotMappedByTheUser(virtualMachineProfileMock,
volumeToPoolObjectMap);
inOrder.verify(virtualMachineManagerImpl).createStoragePoolMappingsForVolumes(Mockito.eq(virtualMachineProfileMock),
- Mockito.any(DataCenterDeployment.class),
Mockito.eq(volumeToPoolObjectMap), Mockito.eq(volumesNotMapped));
+ any(DataCenterDeployment.class),
Mockito.eq(volumeToPoolObjectMap), Mockito.eq(volumesNotMapped));
}
@Test
@@ -774,11 +814,11 @@ public class VirtualMachineManagerImplTest {
private void prepareAndTestIsRootVolumeOnLocalStorage(ScopeType scope,
boolean expected) {
StoragePoolVO storagePoolVoMock = Mockito.mock(StoragePoolVO.class);
-
Mockito.doReturn(storagePoolVoMock).when(storagePoolDaoMock).findById(Mockito.anyLong());
+
Mockito.doReturn(storagePoolVoMock).when(storagePoolDaoMock).findById(anyLong());
Mockito.doReturn(scope).when(storagePoolVoMock).getScope();
List<VolumeVO> mockedVolumes = new ArrayList<>();
mockedVolumes.add(volumeVoMock);
-
Mockito.doReturn(mockedVolumes).when(volumeDaoMock).findByInstanceAndType(Mockito.anyLong(),
Mockito.any());
+
Mockito.doReturn(mockedVolumes).when(volumeDaoMock).findByInstanceAndType(anyLong(),
any());
boolean result =
virtualMachineManagerImpl.isRootVolumeOnLocalStorage(0l);
@@ -806,7 +846,7 @@ public class VirtualMachineManagerImplTest {
}
private void
prepareAndRunCheckIfNewOfferingStorageScopeMatchesStoragePool(boolean
isRootOnLocal, boolean isOfferingUsingLocal) {
-
Mockito.doReturn(isRootOnLocal).when(virtualMachineManagerImpl).isRootVolumeOnLocalStorage(Mockito.anyLong());
+
Mockito.doReturn(isRootOnLocal).when(virtualMachineManagerImpl).isRootVolumeOnLocalStorage(anyLong());
Mockito.doReturn("vmInstanceMockedToString").when(vmInstanceMock).toString();
Mockito.doReturn(isOfferingUsingLocal).when(diskOfferingMock).isUseLocalStorage();
virtualMachineManagerImpl.checkIfNewOfferingStorageScopeMatchesStoragePool(vmInstanceMock,
diskOfferingMock);
@@ -895,4 +935,188 @@ public class VirtualMachineManagerImplTest {
map.put(Mockito.mock(Volume.class), pool2);
virtualMachineManagerImpl.checkAndAttemptMigrateVmAcrossCluster(vm,
destinationClusterId, map);
}
+
+ @Test
+ public void testOrchestrateStartNonNullPodId() throws Exception {
+ VMInstanceVO vmInstance = new VMInstanceVO();
+ ReflectionTestUtils.setField(vmInstance, "id", 1L);
+ ReflectionTestUtils.setField(vmInstance, "uuid", "vm-uuid");
+ ReflectionTestUtils.setField(vmInstance, "serviceOfferingId", 2L);
+ ReflectionTestUtils.setField(vmInstance, "instanceName", "myVm");
+ ReflectionTestUtils.setField(vmInstance, "hostId", 2L);
+ ReflectionTestUtils.setField(vmInstance, "type",
VirtualMachine.Type.User);
+ ReflectionTestUtils.setField(vmInstance, "dataCenterId", 1L);
+ ReflectionTestUtils.setField(vmInstance, "hypervisorType",
HypervisorType.KVM);
+
+ VirtualMachineGuru vmGuru = mock(VirtualMachineGuru.class);
+
+ User user = mock(User.class);
+
+ Account account = mock(Account.class);
+
+ ReservationContext ctx = mock(ReservationContext.class);
+
+ ItWorkVO work = mock(ItWorkVO.class);
+
+ ServiceOfferingVO serviceOffering = mock(ServiceOfferingVO.class);
+
+ VirtualMachineTemplate template = mock(VirtualMachineTemplate.class);
+ when(template.isDeployAsIs()).thenReturn(false);
+
+ DataCenterDeployment plan = mock(DataCenterDeployment.class);
+ when(plan.getDataCenterId()).thenReturn(1L);
+ when(plan.getPodId()).thenReturn(1L);
+
+ Map<VirtualMachineProfile.Param, Object> params = new HashMap<>();
+
+ DeploymentPlanner planner = mock(DeploymentPlanner.class);
+
+ when(vmInstanceDaoMock.findByUuid("vm-uuid")).thenReturn(vmInstance);
+
+ doReturn(vmGuru).when(virtualMachineManagerImpl).getVmGuru(vmInstance);
+
+ Ternary<VMInstanceVO, ReservationContext, ItWorkVO> start = new
Ternary<>(vmInstance, ctx, work);
+
Mockito.doReturn(start).when(virtualMachineManagerImpl).changeToStartState(vmGuru,
vmInstance, user, account);
+
+ when(ctx.getJournal()).thenReturn(Mockito.mock(Journal.class));
+
+ when(serviceOfferingDaoMock.findById(vmInstance.getId(),
vmInstance.getServiceOfferingId())).thenReturn(serviceOffering);
+
+ when(_entityMgr.findByIdIncludingRemoved(VirtualMachineTemplate.class,
vmInstance.getTemplateId())).thenReturn(template);
+
+ Host destHost = mock(Host.class);
+ Pod destPod = mock(Pod.class);
+ DeployDestination dest = mock(DeployDestination.class);
+ when(dest.getHost()).thenReturn(destHost);
+ when(dest.getPod()).thenReturn(destPod);
+ when(dest.getCluster()).thenReturn(mock(Cluster.class));
+ when(destHost.getId()).thenReturn(1L);
+ when(destPod.getId()).thenReturn(2L);
+ when(_dpMgr.planDeployment(any(VirtualMachineProfileImpl.class),
any(DataCenterDeployment.class), any(ExcludeList.class),
any(DeploymentPlanner.class))).thenReturn(dest);
+
+
doNothing().when(virtualMachineManagerImpl).checkIfTemplateNeededForCreatingVmVolumes(vmInstance);
+
+ when(_workDao.updateStep(any(), any())).thenReturn(true);
+ when(_stateMachine.transitTo(vmInstance,
VirtualMachine.Event.OperationRetry, new Pair(vmInstance.getHostId(), 1L),
vmInstanceDaoMock)).thenThrow(new CloudRuntimeException("Error while
transitioning"));
+ when(_stateMachine.transitTo(vmInstance,
VirtualMachine.Event.OperationFailed, new Pair(vmInstance.getHostId(), null),
vmInstanceDaoMock)).thenReturn(true);
+
+
+ Cluster cluster = mock(Cluster.class);
+ when(dest.getCluster()).thenReturn(cluster);
+ ClusterDetailsVO cluster_detail_cpu = mock(ClusterDetailsVO.class);
+ ClusterDetailsVO cluster_detail_ram = mock(ClusterDetailsVO.class);
+ when(cluster.getId()).thenReturn(1L);
+ when(_clusterDetailsDao.findDetail(1L,
VmDetailConstants.CPU_OVER_COMMIT_RATIO)).thenReturn(cluster_detail_cpu);
+ when(_clusterDetailsDao.findDetail(1L,
VmDetailConstants.MEMORY_OVER_COMMIT_RATIO)).thenReturn(cluster_detail_ram);
+ when(userVmDetailsDao.findDetail(anyLong(),
Mockito.anyString())).thenReturn(null);
+ when(cluster_detail_cpu.getValue()).thenReturn("1.0");
+ when(cluster_detail_ram.getValue()).thenReturn("1.0");
+
doReturn(false).when(virtualMachineManagerImpl).areAllVolumesAllocated(Mockito.anyLong());
+
+ CallContext callContext = mock(CallContext.class);
+ Mockito.when(callContext.getCallingAccount()).thenReturn(account);
+ Mockito.when(callContext.getCallingUser()).thenReturn(user);
+ PowerMockito.mockStatic(CallContext.class);
+ PowerMockito.when(CallContext.current()).thenReturn(callContext);
+
+ try {
+ virtualMachineManagerImpl.orchestrateStart("vm-uuid", params,
plan, planner);
+ } catch (CloudRuntimeException e) {
+ assertEquals(e.getMessage(), "Error while transitioning");
+ }
+
+ assertEquals(vmInstance.getPodIdToDeployIn(), (Long) destPod.getId());
+ }
+
+ @Test
+ public void testOrchestrateStartNullPodId() throws Exception {
+ VMInstanceVO vmInstance = new VMInstanceVO();
+ ReflectionTestUtils.setField(vmInstance, "id", 1L);
+ ReflectionTestUtils.setField(vmInstance, "uuid", "vm-uuid");
+ ReflectionTestUtils.setField(vmInstance, "serviceOfferingId", 2L);
+ ReflectionTestUtils.setField(vmInstance, "instanceName", "myVm");
+ ReflectionTestUtils.setField(vmInstance, "hostId", 2L);
+ ReflectionTestUtils.setField(vmInstance, "type",
VirtualMachine.Type.User);
+ ReflectionTestUtils.setField(vmInstance, "dataCenterId", 1L);
+ ReflectionTestUtils.setField(vmInstance, "hypervisorType",
HypervisorType.KVM);
+
+ VirtualMachineGuru vmGuru = mock(VirtualMachineGuru.class);
+
+ User user = mock(User.class);
+
+ Account account = mock(Account.class);
+
+ ReservationContext ctx = mock(ReservationContext.class);
+
+ ItWorkVO work = mock(ItWorkVO.class);
+
+ ServiceOfferingVO serviceOffering = mock(ServiceOfferingVO.class);
+
+ VirtualMachineTemplate template = mock(VirtualMachineTemplate.class);
+ when(template.isDeployAsIs()).thenReturn(false);
+
+ DataCenterDeployment plan = mock(DataCenterDeployment.class);
+ when(plan.getDataCenterId()).thenReturn(1L);
+ when(plan.getPodId()).thenReturn(1L);
+
+ Map<VirtualMachineProfile.Param, Object> params = new HashMap<>();
+
+ DeploymentPlanner planner = mock(DeploymentPlanner.class);
+
+ when(vmInstanceDaoMock.findByUuid("vm-uuid")).thenReturn(vmInstance);
+
+ doReturn(vmGuru).when(virtualMachineManagerImpl).getVmGuru(vmInstance);
+
+ Ternary<VMInstanceVO, ReservationContext, ItWorkVO> start = new
Ternary<>(vmInstance, ctx, work);
+
Mockito.doReturn(start).when(virtualMachineManagerImpl).changeToStartState(vmGuru,
vmInstance, user, account);
+
+ when(ctx.getJournal()).thenReturn(Mockito.mock(Journal.class));
+
+ when(serviceOfferingDaoMock.findById(vmInstance.getId(),
vmInstance.getServiceOfferingId())).thenReturn(serviceOffering);
+
+ when(_entityMgr.findByIdIncludingRemoved(VirtualMachineTemplate.class,
vmInstance.getTemplateId())).thenReturn(template);
+
+ Host destHost = mock(Host.class);
+ Pod destPod = mock(Pod.class);
+ DeployDestination dest = mock(DeployDestination.class);
+ when(dest.getHost()).thenReturn(destHost);
+ when(dest.getPod()).thenReturn(destPod);
+ when(dest.getCluster()).thenReturn(mock(Cluster.class));
+ when(destHost.getId()).thenReturn(1L);
+ when(destPod.getId()).thenReturn(2L);
+ when(_dpMgr.planDeployment(any(VirtualMachineProfileImpl.class),
any(DataCenterDeployment.class), any(ExcludeList.class),
any(DeploymentPlanner.class))).thenReturn(dest);
+
+
doNothing().when(virtualMachineManagerImpl).checkIfTemplateNeededForCreatingVmVolumes(vmInstance);
+
+ when(_workDao.updateStep(any(), any())).thenReturn(true);
+ when(_stateMachine.transitTo(vmInstance,
VirtualMachine.Event.OperationRetry, new Pair(vmInstance.getHostId(), 1L),
vmInstanceDaoMock)).thenThrow(new CloudRuntimeException("Error while
transitioning"));
+ when(_stateMachine.transitTo(vmInstance,
VirtualMachine.Event.OperationFailed, new Pair(vmInstance.getHostId(), null),
vmInstanceDaoMock)).thenReturn(true);
+
+
+ Cluster cluster = mock(Cluster.class);
+ when(dest.getCluster()).thenReturn(cluster);
+ ClusterDetailsVO cluster_detail_cpu = mock(ClusterDetailsVO.class);
+ ClusterDetailsVO cluster_detail_ram = mock(ClusterDetailsVO.class);
+ when(cluster.getId()).thenReturn(1L);
+ when(_clusterDetailsDao.findDetail(1L,
VmDetailConstants.CPU_OVER_COMMIT_RATIO)).thenReturn(cluster_detail_cpu);
+ when(_clusterDetailsDao.findDetail(1L,
VmDetailConstants.MEMORY_OVER_COMMIT_RATIO)).thenReturn(cluster_detail_ram);
+ when(userVmDetailsDao.findDetail(anyLong(),
Mockito.anyString())).thenReturn(null);
+ when(cluster_detail_cpu.getValue()).thenReturn("1.0");
+ when(cluster_detail_ram.getValue()).thenReturn("1.0");
+
doReturn(true).when(virtualMachineManagerImpl).areAllVolumesAllocated(Mockito.anyLong());
+
+ CallContext callContext = mock(CallContext.class);
+ Mockito.when(callContext.getCallingAccount()).thenReturn(account);
+ Mockito.when(callContext.getCallingUser()).thenReturn(user);
+ PowerMockito.mockStatic(CallContext.class);
+ PowerMockito.when(CallContext.current()).thenReturn(callContext);
+
+ try {
+ virtualMachineManagerImpl.orchestrateStart("vm-uuid", params,
plan, planner);
+ } catch (CloudRuntimeException e) {
+ assertEquals(e.getMessage(), "Error while transitioning");
+ }
+
+ assertNull(vmInstance.getPodIdToDeployIn());
+ }
}