| // 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.deploy; |
| |
| |
| import com.cloud.agent.AgentManager; |
| import com.cloud.capacity.CapacityManager; |
| import com.cloud.capacity.dao.CapacityDao; |
| import com.cloud.configuration.ConfigurationManagerImpl; |
| import com.cloud.dc.ClusterDetailsDao; |
| import com.cloud.dc.ClusterDetailsVO; |
| import com.cloud.dc.ClusterVO; |
| import com.cloud.dc.DataCenter; |
| 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.DedicatedResourceDao; |
| import com.cloud.dc.dao.HostPodDao; |
| import com.cloud.deploy.DeploymentPlanner.ExcludeList; |
| import com.cloud.deploy.DeploymentPlanner.PlannerResourceUsage; |
| import com.cloud.deploy.dao.PlannerHostReservationDao; |
| import com.cloud.exception.AffinityConflictException; |
| import com.cloud.exception.InsufficientServerCapacityException; |
| import com.cloud.gpu.GPU; |
| import com.cloud.gpu.dao.HostGpuGroupsDao; |
| import com.cloud.host.Host; |
| import com.cloud.host.HostVO; |
| import com.cloud.host.Status; |
| import com.cloud.host.dao.HostDao; |
| import com.cloud.host.dao.HostDetailsDao; |
| import com.cloud.host.dao.HostTagsDao; |
| import com.cloud.hypervisor.Hypervisor.HypervisorType; |
| import com.cloud.org.Grouping.AllocationState; |
| import com.cloud.resource.ResourceManager; |
| import com.cloud.service.ServiceOfferingVO; |
| import com.cloud.service.dao.ServiceOfferingDetailsDao; |
| import com.cloud.storage.DiskOfferingVO; |
| import com.cloud.storage.ScopeType; |
| import com.cloud.storage.Storage; |
| import com.cloud.storage.StorageManager; |
| import com.cloud.storage.StoragePool; |
| import com.cloud.storage.StoragePoolStatus; |
| import com.cloud.storage.VMTemplateVO; |
| import com.cloud.storage.Volume; |
| import com.cloud.storage.VolumeVO; |
| import com.cloud.storage.dao.DiskOfferingDao; |
| import com.cloud.storage.dao.GuestOSCategoryDao; |
| import com.cloud.storage.dao.GuestOSDao; |
| import com.cloud.storage.dao.StoragePoolHostDao; |
| import com.cloud.storage.dao.VMTemplateDao; |
| import com.cloud.storage.dao.VolumeDao; |
| import com.cloud.template.VirtualMachineTemplate; |
| import com.cloud.user.Account; |
| import com.cloud.user.AccountManager; |
| import com.cloud.user.AccountVO; |
| import com.cloud.user.dao.AccountDao; |
| import com.cloud.utils.Pair; |
| import com.cloud.utils.component.ComponentContext; |
| import com.cloud.vm.DiskProfile; |
| import com.cloud.vm.VMInstanceVO; |
| import com.cloud.vm.VirtualMachine; |
| import com.cloud.vm.VirtualMachine.Type; |
| import com.cloud.vm.VirtualMachineProfile; |
| import com.cloud.vm.VirtualMachineProfileImpl; |
| import com.cloud.vm.dao.UserVmDao; |
| import com.cloud.vm.dao.UserVmDetailsDao; |
| import com.cloud.vm.dao.VMInstanceDao; |
| import org.apache.cloudstack.affinity.AffinityGroupProcessor; |
| import org.apache.cloudstack.affinity.AffinityGroupService; |
| import org.apache.cloudstack.affinity.dao.AffinityGroupDao; |
| import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDao; |
| import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; |
| import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMReservationDao; |
| 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; |
| import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; |
| import org.apache.cloudstack.framework.config.ConfigKey; |
| import org.apache.cloudstack.framework.config.dao.ConfigurationDao; |
| import org.apache.cloudstack.framework.messagebus.MessageBus; |
| import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; |
| import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; |
| import org.apache.cloudstack.test.utils.SpringUtils; |
| import org.apache.commons.collections.CollectionUtils; |
| import org.junit.After; |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.mockito.ArgumentMatchers; |
| import org.mockito.InjectMocks; |
| import org.mockito.Mock; |
| import org.mockito.Mockito; |
| import org.mockito.MockitoAnnotations; |
| import org.mockito.Spy; |
| import org.springframework.context.annotation.Bean; |
| import org.springframework.context.annotation.ComponentScan; |
| import org.springframework.context.annotation.ComponentScan.Filter; |
| import org.springframework.context.annotation.Configuration; |
| import org.springframework.context.annotation.FilterType; |
| import org.springframework.core.type.classreading.MetadataReader; |
| import org.springframework.core.type.classreading.MetadataReaderFactory; |
| import org.springframework.core.type.filter.TypeFilter; |
| import org.springframework.test.context.ContextConfiguration; |
| import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; |
| import org.springframework.test.context.support.AnnotationConfigContextLoader; |
| |
| import javax.inject.Inject; |
| import javax.naming.ConfigurationException; |
| import java.io.IOException; |
| import java.lang.reflect.Field; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.mockito.Mockito.times; |
| import static org.mockito.Mockito.verify; |
| |
| @RunWith(SpringJUnit4ClassRunner.class) |
| @ContextConfiguration(loader = AnnotationConfigContextLoader.class) |
| public class DeploymentPlanningManagerImplTest { |
| |
| @Spy |
| @InjectMocks |
| DeploymentPlanningManagerImpl _dpm; |
| |
| @Inject |
| PlannerHostReservationDao _plannerHostReserveDao; |
| |
| @Inject |
| VirtualMachineProfileImpl vmProfile; |
| |
| @Inject |
| private AccountDao accountDao; |
| |
| @Inject |
| private VMInstanceDao vmInstanceDao; |
| |
| @Inject |
| AffinityGroupVMMapDao _affinityGroupVMMapDao; |
| |
| @Inject |
| ExcludeList avoids; |
| |
| @Inject |
| DataCenterVO dc; |
| |
| @Inject |
| DataCenterDao _dcDao; |
| |
| @Mock |
| FirstFitPlanner _planner; |
| |
| @Inject |
| ClusterDao _clusterDao; |
| |
| @Inject |
| DedicatedResourceDao _dedicatedDao; |
| |
| @Inject |
| UserVmDetailsDao vmDetailsDao; |
| |
| @Inject |
| VMTemplateDao templateDao; |
| |
| @Inject |
| HostPodDao hostPodDao; |
| |
| @Inject |
| VolumeDao volDao; |
| |
| @Inject |
| HostDao hostDao; |
| |
| @Inject |
| CapacityManager capacityMgr; |
| |
| @Inject |
| ServiceOfferingDetailsDao serviceOfferingDetailsDao; |
| |
| @Inject |
| ClusterDetailsDao clusterDetailsDao; |
| |
| @Inject |
| PrimaryDataStoreDao primaryDataStoreDao; |
| |
| @Mock |
| Host host; |
| |
| @Mock |
| ConfigurationDao configDao; |
| |
| @Mock |
| AccountManager _accountMgr; |
| |
| @Inject |
| DiskOfferingDao _diskOfferingDao; |
| |
| @Mock |
| DataStoreManager _dataStoreManager; |
| |
| @Inject |
| HostPodDao _podDao; |
| |
| private static final long dataCenterId = 1L; |
| private static final long instanceId = 123L; |
| private static final long hostId = 0L; |
| private static final long podId = 2L; |
| private static final long clusterId = 3L; |
| private static final long ADMIN_ACCOUNT_ROLE_ID = 1L; |
| private AutoCloseable closeable; |
| |
| @BeforeClass |
| public static void setUp() throws ConfigurationException { |
| } |
| |
| @Before |
| public void testSetUp() { |
| closeable = MockitoAnnotations.openMocks(this); |
| |
| ComponentContext.initComponentsLifeCycle(); |
| |
| PlannerHostReservationVO reservationVO = new PlannerHostReservationVO(hostId, dataCenterId, podId, clusterId, PlannerResourceUsage.Shared); |
| Mockito.when(_plannerHostReserveDao.persist(ArgumentMatchers.any(PlannerHostReservationVO.class))).thenReturn(reservationVO); |
| Mockito.when(_plannerHostReserveDao.findById(ArgumentMatchers.anyLong())).thenReturn(reservationVO); |
| Mockito.when(_affinityGroupVMMapDao.countAffinityGroupsForVm(ArgumentMatchers.anyLong())).thenReturn(0L); |
| |
| VMTemplateVO template = Mockito.mock(VMTemplateVO.class); |
| Mockito.when(template.isDeployAsIs()).thenReturn(false); |
| Mockito.when(templateDao.findById(Mockito.anyLong())).thenReturn(template); |
| |
| VMInstanceVO vm = Mockito.mock(VMInstanceVO.class); |
| Mockito.when(vm.getType()).thenReturn(Type.Instance); |
| Mockito.when(vm.getLastHostId()).thenReturn(null); |
| Mockito.when(vmProfile.getVirtualMachine()).thenReturn(vm); |
| Mockito.when(vmProfile.getId()).thenReturn(instanceId); |
| |
| Mockito.when(vmDetailsDao.listDetailsKeyPairs(ArgumentMatchers.anyLong())).thenReturn(null); |
| |
| Mockito.when(volDao.findByInstance(ArgumentMatchers.anyLong())).thenReturn(new ArrayList<>()); |
| |
| Mockito.when(_dcDao.findById(ArgumentMatchers.anyLong())).thenReturn(dc); |
| Mockito.when(dc.getId()).thenReturn(dataCenterId); |
| |
| ClusterVO clusterVO = new ClusterVO(); |
| clusterVO.setHypervisorType(HypervisorType.XenServer.toString()); |
| Mockito.when(_clusterDao.findById(ArgumentMatchers.anyLong())).thenReturn(clusterVO); |
| |
| Mockito.when(_planner.getName()).thenReturn("FirstFitPlanner"); |
| List<DeploymentPlanner> planners = new ArrayList<DeploymentPlanner>(); |
| planners.add(_planner); |
| _dpm.setPlanners(planners); |
| StoragePoolAllocator allocator = Mockito.mock(StoragePoolAllocator.class); |
| _dpm.setStoragePoolAllocators(Arrays.asList(allocator)); |
| |
| Mockito.when(host.getId()).thenReturn(hostId); |
| Mockito.doNothing().when(_dpm).avoidDisabledResources(vmProfile, dc, avoids); |
| } |
| |
| @After |
| public void tearDown() throws Exception { |
| closeable.close(); |
| } |
| |
| @Test |
| public void dataCenterAvoidTest() throws InsufficientServerCapacityException, AffinityConflictException { |
| ServiceOfferingVO svcOffering = |
| new ServiceOfferingVO("testOffering", 1, 512, 500, 1, 1, false, false, false, "test dpm", |
| false, VirtualMachine.Type.User, null, "FirstFitPlanner", true, false); |
| Mockito.when(vmProfile.getServiceOffering()).thenReturn(svcOffering); |
| |
| DataCenterDeployment plan = new DataCenterDeployment(dataCenterId); |
| |
| Mockito.when(avoids.shouldAvoid((DataCenterVO) ArgumentMatchers.any())).thenReturn(true); |
| DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids, null); |
| assertNull("DataCenter is in avoid set, destination should be null! ", dest); |
| } |
| |
| @Test |
| public void plannerCannotHandleTest() throws InsufficientServerCapacityException, AffinityConflictException { |
| ServiceOfferingVO svcOffering = |
| new ServiceOfferingVO("testOffering", 1, 512, 500, 1, 1, false, false, false, "test dpm", |
| false, VirtualMachine.Type.User, null, "UserDispersingPlanner", true, false); |
| Mockito.when(vmProfile.getServiceOffering()).thenReturn(svcOffering); |
| |
| DataCenterDeployment plan = new DataCenterDeployment(dataCenterId); |
| Mockito.when(avoids.shouldAvoid((DataCenterVO) ArgumentMatchers.any())).thenReturn(false); |
| |
| Mockito.when(_planner.canHandle(vmProfile, plan, avoids)).thenReturn(false); |
| DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids, null); |
| assertNull("Planner cannot handle, destination should be null! ", dest); |
| } |
| |
| @Test |
| public void emptyClusterListTest() throws InsufficientServerCapacityException, AffinityConflictException { |
| ServiceOfferingVO svcOffering = |
| new ServiceOfferingVO("testOffering", 1, 512, 500, 1, 1, false, false, false, "test dpm", |
| false, VirtualMachine.Type.User, null, "FirstFitPlanner", true, false); |
| Mockito.when(vmProfile.getServiceOffering()).thenReturn(svcOffering); |
| |
| DataCenterDeployment plan = new DataCenterDeployment(dataCenterId); |
| Mockito.when(avoids.shouldAvoid((DataCenterVO) ArgumentMatchers.any())).thenReturn(false); |
| Mockito.when(_planner.canHandle(vmProfile, plan, avoids)).thenReturn(true); |
| |
| Mockito.when(((DeploymentClusterPlanner) _planner).orderClusters(vmProfile, plan, avoids)).thenReturn(null); |
| DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids, null); |
| assertNull("Planner cannot handle, destination should be null! ", dest); |
| } |
| |
| @Test |
| public void testCheckAffinityEmptyPreferredHosts() { |
| assertTrue(_dpm.checkAffinity(host, new ArrayList<>())); |
| } |
| |
| @Test |
| public void testCheckAffinityNullPreferredHosts() { |
| assertTrue(_dpm.checkAffinity(host, null)); |
| } |
| |
| @Test |
| public void testCheckAffinityNotEmptyPreferredHostsContainingHost() { |
| assertTrue(_dpm.checkAffinity(host, Arrays.asList(3l, 4l, hostId, 2l))); |
| } |
| |
| @Test |
| public void testCheckAffinityNotEmptyPreferredHostsNotContainingHost() { |
| assertFalse(_dpm.checkAffinity(host, Arrays.asList(3l, 4l, 2l))); |
| } |
| |
| @Test |
| public void routerInDisabledResourceAssertFalse() { |
| Assert.assertFalse(DeploymentPlanningManager.allowRouterOnDisabledResource.value()); |
| } |
| |
| @Test |
| public void adminVmInDisabledResourceAssertFalse() { |
| Assert.assertFalse(DeploymentPlanningManager.allowAdminVmOnDisabledResource.value()); |
| } |
| |
| @Test |
| public void avoidDisabledResourcesTestAdminAccount() { |
| Type[] vmTypes = VirtualMachine.Type.values(); |
| for (int i = 0; i < vmTypes.length - 1; ++i) { |
| Mockito.when(vmProfile.getType()).thenReturn(vmTypes[i]); |
| if (vmTypes[i].isUsedBySystem()) { |
| prepareAndVerifyAvoidDisabledResourcesTest(1, 0, 0, ADMIN_ACCOUNT_ROLE_ID, vmTypes[i], true, false); |
| } else { |
| prepareAndVerifyAvoidDisabledResourcesTest(0, 1, 1, ADMIN_ACCOUNT_ROLE_ID, vmTypes[i], true, false); |
| } |
| } |
| } |
| |
| @Test |
| public void avoidDisabledResourcesTestUserAccounAdminCannotDeployOnDisabled() { |
| Type[] vmTypes = VirtualMachine.Type.values(); |
| for (int i = 0; i < vmTypes.length - 1; ++i) { |
| Mockito.when(vmProfile.getType()).thenReturn(vmTypes[i]); |
| long userAccountId = ADMIN_ACCOUNT_ROLE_ID + 1; |
| if (vmTypes[i].isUsedBySystem()) { |
| prepareAndVerifyAvoidDisabledResourcesTest(1, 0, 0, userAccountId, vmTypes[i], true, false); |
| } else { |
| prepareAndVerifyAvoidDisabledResourcesTest(0, 0, 1, userAccountId, vmTypes[i], true, false); |
| } |
| } |
| } |
| |
| @Test |
| public void avoidDisabledResourcesTestUserAccounAdminCanDeployOnDisabled() { |
| Type[] vmTypes = VirtualMachine.Type.values(); |
| for (int i = 0; i < vmTypes.length - 1; ++i) { |
| Mockito.when(vmProfile.getType()).thenReturn(vmTypes[i]); |
| long userAccountId = ADMIN_ACCOUNT_ROLE_ID + 1; |
| if (vmTypes[i].isUsedBySystem()) { |
| prepareAndVerifyAvoidDisabledResourcesTest(1, 0, 0, userAccountId, vmTypes[i], true, true); |
| } else { |
| prepareAndVerifyAvoidDisabledResourcesTest(0, 0, 1, userAccountId, vmTypes[i], true, true); |
| } |
| } |
| } |
| |
| private void prepareAndVerifyAvoidDisabledResourcesTest(int timesRouter, int timesAdminVm, |
| int timesDisabledResource, long roleId, Type vmType, boolean isSystemDepolyable, |
| boolean isAdminVmDeployable) { |
| Mockito.doReturn(isSystemDepolyable).when(_dpm).isRouterDeployableInDisabledResources(); |
| Mockito.doReturn(isAdminVmDeployable).when(_dpm).isAdminVmDeployableInDisabledResources(); |
| |
| VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class); |
| DataCenter dc = Mockito.mock(DataCenter.class); |
| ExcludeList avoids = Mockito.mock(ExcludeList.class); |
| |
| Mockito.when(vmProfile.getType()).thenReturn(vmType); |
| Mockito.when(vmProfile.getId()).thenReturn(1l); |
| |
| Mockito.doNothing().when(_dpm).avoidDisabledDataCenters(dc, avoids); |
| Mockito.doNothing().when(_dpm).avoidDisabledPods(dc, avoids); |
| Mockito.doNothing().when(_dpm).avoidDisabledClusters(dc, avoids); |
| Mockito.doNothing().when(_dpm).avoidDisabledHosts(dc, avoids); |
| |
| VMInstanceVO vmInstanceVO = Mockito.mock(VMInstanceVO.class); |
| Mockito.when(vmInstanceDao.findById(Mockito.anyLong())).thenReturn(vmInstanceVO); |
| AccountVO owner = Mockito.mock(AccountVO.class); |
| Mockito.when(owner.getRoleId()).thenReturn(roleId); |
| Mockito.when(accountDao.findById(Mockito.anyLong())).thenReturn(owner); |
| |
| _dpm.avoidDisabledResources(vmProfile, dc, avoids); |
| |
| Mockito.verify(_dpm, Mockito.times(timesRouter)).isRouterDeployableInDisabledResources(); |
| Mockito.verify(_dpm, Mockito.times(timesAdminVm)).isAdminVmDeployableInDisabledResources(); |
| Mockito.verify(_dpm, Mockito.times(timesDisabledResource)).avoidDisabledDataCenters(dc, avoids); |
| Mockito.verify(_dpm, Mockito.times(timesDisabledResource)).avoidDisabledPods(dc, avoids); |
| Mockito.verify(_dpm, Mockito.times(timesDisabledResource)).avoidDisabledClusters(dc, avoids); |
| Mockito.verify(_dpm, Mockito.times(timesDisabledResource)).avoidDisabledHosts(dc, avoids); |
| Mockito.reset(_dpm); |
| } |
| |
| @Test |
| public void avoidDisabledDataCentersTest() { |
| DataCenter dc = Mockito.mock(DataCenter.class); |
| Mockito.when(dc.getId()).thenReturn(123l); |
| |
| ExcludeList avoids = new ExcludeList(); |
| AllocationState[] allocationStates = AllocationState.values(); |
| for (int i = 0; i < allocationStates.length - 1; ++i) { |
| Mockito.when(dc.getAllocationState()).thenReturn(allocationStates[i]); |
| |
| _dpm.avoidDisabledDataCenters(dc, avoids); |
| |
| if (allocationStates[i] == AllocationState.Disabled) { |
| assertAvoidIsEmpty(avoids, false, true, true, true); |
| Assert.assertTrue(avoids.getDataCentersToAvoid().size() == 1); |
| Assert.assertTrue(avoids.getDataCentersToAvoid().contains(dc.getId())); |
| } else { |
| assertAvoidIsEmpty(avoids, true, true, true, true); |
| } |
| } |
| } |
| |
| @Test |
| public void avoidDisabledPodsTestNoDisabledPod() { |
| DataCenter dc = Mockito.mock(DataCenter.class); |
| List<Long> podIds = new ArrayList<>(); |
| long expectedPodId = 123l; |
| podIds.add(expectedPodId); |
| Mockito.doReturn(new ArrayList<>()).when(hostPodDao).listDisabledPods(Mockito.anyLong()); |
| ExcludeList avoids = new ExcludeList(); |
| |
| _dpm.avoidDisabledPods(dc, avoids); |
| assertAvoidIsEmpty(avoids, true, true, true, true); |
| } |
| |
| @Test |
| public void avoidDisabledPodsTestHasDisabledPod() { |
| DataCenter dc = Mockito.mock(DataCenter.class); |
| List<Long> podIds = new ArrayList<>(); |
| long expectedPodId = 123l; |
| podIds.add(expectedPodId); |
| Mockito.doReturn(podIds).when(hostPodDao).listDisabledPods(Mockito.anyLong()); |
| |
| ExcludeList avoids = new ExcludeList(); |
| |
| _dpm.avoidDisabledPods(dc, avoids); |
| assertAvoidIsEmpty(avoids, true, false, true, true); |
| Assert.assertTrue(avoids.getPodsToAvoid().size() == 1); |
| Assert.assertTrue(avoids.getPodsToAvoid().contains(expectedPodId)); |
| } |
| |
| @Test |
| public void avoidDisabledClustersTestNoDisabledCluster() { |
| DataCenter dc = prepareAvoidDisabledTests(); |
| Mockito.doReturn(new ArrayList<>()).when(_clusterDao).listDisabledClusters(Mockito.anyLong(), Mockito.anyLong()); |
| ExcludeList avoids = new ExcludeList(); |
| |
| _dpm.avoidDisabledClusters(dc, avoids); |
| assertAvoidIsEmpty(avoids, true, true, true, true); |
| } |
| |
| @Test |
| public void avoidDisabledClustersTestHasDisabledCluster() { |
| DataCenter dc = prepareAvoidDisabledTests(); |
| long expectedClusterId = 123l; |
| List<Long> disabledClusters = new ArrayList<>(); |
| disabledClusters.add(expectedClusterId); |
| Mockito.doReturn(disabledClusters).when(_clusterDao).listDisabledClusters(Mockito.anyLong(), Mockito.anyLong()); |
| ExcludeList avoids = new ExcludeList(); |
| |
| _dpm.avoidDisabledClusters(dc, avoids); |
| |
| assertAvoidIsEmpty(avoids, true, true, false, true); |
| Assert.assertTrue(avoids.getClustersToAvoid().size() == 1); |
| Assert.assertTrue(avoids.getClustersToAvoid().contains(expectedClusterId)); |
| } |
| |
| @Test |
| public void volumesRequireEncryptionTest() { |
| VolumeVO vol1 = new VolumeVO("vol1", dataCenterId, podId, 1L, 1L, instanceId, "folder", "path", Storage.ProvisioningType.THIN, (long) 10 << 30, Volume.Type.ROOT); |
| VolumeVO vol2 = new VolumeVO("vol2", dataCenterId, podId, 1L, 1L, instanceId, "folder", "path", Storage.ProvisioningType.THIN, (long) 10 << 30, Volume.Type.DATADISK); |
| VolumeVO vol3 = new VolumeVO("vol3", dataCenterId, podId, 1L, 1L, instanceId, "folder", "path", Storage.ProvisioningType.THIN, (long) 10 << 30, Volume.Type.DATADISK); |
| vol2.setPassphraseId(1L); |
| |
| List<VolumeVO> volumes = List.of(vol1, vol2, vol3); |
| Assert.assertTrue("Volumes require encryption, but not reporting", _dpm.anyVolumeRequiresEncryption(volumes)); |
| } |
| |
| @Test |
| public void volumesDoNotRequireEncryptionTest() { |
| VolumeVO vol1 = new VolumeVO("vol1", dataCenterId, podId, 1L, 1L, instanceId, "folder", "path", Storage.ProvisioningType.THIN, (long) 10 << 30, Volume.Type.ROOT); |
| VolumeVO vol2 = new VolumeVO("vol2", dataCenterId, podId, 1L, 1L, instanceId, "folder", "path", Storage.ProvisioningType.THIN, (long) 10 << 30, Volume.Type.DATADISK); |
| VolumeVO vol3 = new VolumeVO("vol3", dataCenterId, podId, 1L, 1L, instanceId, "folder", "path", Storage.ProvisioningType.THIN, (long) 10 << 30, Volume.Type.DATADISK); |
| |
| List<VolumeVO> volumes = List.of(vol1, vol2, vol3); |
| Assert.assertFalse("Volumes do not require encryption, but reporting they do", _dpm.anyVolumeRequiresEncryption(volumes)); |
| } |
| |
| /** |
| * Root requires encryption, chosen host supports it |
| */ |
| @Test |
| public void passEncRootProvidedHostSupportingEncryptionTest() { |
| HostVO host = new HostVO("host"); |
| Map<String, String> hostDetails = new HashMap<>() {{ |
| put(Host.HOST_VOLUME_ENCRYPTION, "true"); |
| }}; |
| host.setDetails(hostDetails); |
| |
| VolumeVO vol1 = new VolumeVO("vol1", dataCenterId, podId, 1L, 1L, instanceId, "folder", "path", Storage.ProvisioningType.THIN, (long) 10 << 30, Volume.Type.ROOT); |
| vol1.setPassphraseId(1L); |
| |
| setupMocksForPlanDeploymentHostTests(host, vol1); |
| |
| DataCenterDeployment plan = new DataCenterDeployment(dataCenterId, podId, clusterId, hostId, null, null); |
| try { |
| DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids, null); |
| Assert.assertEquals(dest.getHost(), host); |
| } catch (Exception ex) { |
| ex.printStackTrace(); |
| } |
| } |
| |
| /** |
| * Root requires encryption, chosen host does not support it |
| */ |
| @Test |
| public void failEncRootProvidedHostNotSupportingEncryptionTest() { |
| HostVO host = new HostVO("host"); |
| Map<String, String> hostDetails = new HashMap<>() {{ |
| put(Host.HOST_VOLUME_ENCRYPTION, "false"); |
| }}; |
| host.setDetails(hostDetails); |
| |
| VolumeVO vol1 = new VolumeVO("vol1", dataCenterId, podId, 1L, 1L, instanceId, "folder", "path", Storage.ProvisioningType.THIN, (long) 10 << 30, Volume.Type.ROOT); |
| vol1.setPassphraseId(1L); |
| |
| setupMocksForPlanDeploymentHostTests(host, vol1); |
| |
| DataCenterDeployment plan = new DataCenterDeployment(dataCenterId, podId, clusterId, hostId, null, null); |
| try { |
| DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids, null); |
| Assert.assertNull("Destination should be null since host doesn't support encryption and root requires it", dest); |
| } catch (Exception ex) { |
| ex.printStackTrace(); |
| } |
| } |
| |
| /** |
| * Root does not require encryption, chosen host does not support it |
| */ |
| @Test |
| public void passNoEncRootProvidedHostNotSupportingEncryptionTest() { |
| HostVO host = new HostVO("host"); |
| Map<String, String> hostDetails = new HashMap<>() {{ |
| put(Host.HOST_VOLUME_ENCRYPTION, "false"); |
| }}; |
| host.setDetails(hostDetails); |
| |
| VolumeVO vol1 = new VolumeVO("vol1", dataCenterId, podId, 1L, 1L, instanceId, "folder", "path", Storage.ProvisioningType.THIN, (long) 10 << 30, Volume.Type.ROOT); |
| |
| setupMocksForPlanDeploymentHostTests(host, vol1); |
| |
| DataCenterDeployment plan = new DataCenterDeployment(dataCenterId, podId, clusterId, hostId, null, null); |
| try { |
| DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids, null); |
| Assert.assertEquals(dest.getHost(), host); |
| } catch (Exception ex) { |
| ex.printStackTrace(); |
| } |
| } |
| |
| /** |
| * Root does not require encryption, chosen host does support it |
| */ |
| @Test |
| public void passNoEncRootProvidedHostSupportingEncryptionTest() { |
| HostVO host = new HostVO("host"); |
| Map<String, String> hostDetails = new HashMap<>() {{ |
| put(Host.HOST_VOLUME_ENCRYPTION, "true"); |
| }}; |
| host.setDetails(hostDetails); |
| |
| VolumeVO vol1 = new VolumeVO("vol1", dataCenterId, podId, 1L, 1L, instanceId, "folder", "path", Storage.ProvisioningType.THIN, (long) 10 << 30, Volume.Type.ROOT); |
| |
| setupMocksForPlanDeploymentHostTests(host, vol1); |
| |
| DataCenterDeployment plan = new DataCenterDeployment(dataCenterId, podId, clusterId, hostId, null, null); |
| try { |
| DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids, null); |
| Assert.assertEquals(dest.getHost(), host); |
| } catch (Exception ex) { |
| ex.printStackTrace(); |
| } |
| } |
| |
| /** |
| * Root requires encryption, last host supports it |
| */ |
| @Test |
| public void passEncRootLastHostSupportingEncryptionTest() { |
| HostVO host = Mockito.spy(new HostVO("host")); |
| Map<String, String> hostDetails = new HashMap<>() {{ |
| put(Host.HOST_VOLUME_ENCRYPTION, "true"); |
| }}; |
| host.setDetails(hostDetails); |
| Mockito.when(host.getStatus()).thenReturn(Status.Up); |
| |
| VolumeVO vol1 = new VolumeVO("vol1", dataCenterId, podId, 1L, 1L, instanceId, "folder", "path", Storage.ProvisioningType.THIN, (long) 10 << 30, Volume.Type.ROOT); |
| vol1.setPassphraseId(1L); |
| |
| setupMocksForPlanDeploymentHostTests(host, vol1); |
| |
| VMInstanceVO vm = (VMInstanceVO) vmProfile.getVirtualMachine(); |
| vm.setLastHostId(hostId); |
| |
| // host id is null here so we pick up last host id |
| DataCenterDeployment plan = new DataCenterDeployment(dataCenterId, podId, clusterId, null, null, null); |
| try { |
| DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids, null); |
| Assert.assertEquals(dest.getHost(), host); |
| } catch (Exception ex) { |
| ex.printStackTrace(); |
| } |
| } |
| |
| /** |
| * Root requires encryption, last host does not support it |
| */ |
| @Test |
| public void failEncRootLastHostNotSupportingEncryptionTest() { |
| HostVO host = Mockito.spy(new HostVO("host")); |
| Map<String, String> hostDetails = new HashMap<>() {{ |
| put(Host.HOST_VOLUME_ENCRYPTION, "false"); |
| }}; |
| host.setDetails(hostDetails); |
| Mockito.when(host.getStatus()).thenReturn(Status.Up); |
| |
| VolumeVO vol1 = new VolumeVO("vol1", dataCenterId, podId, 1L, 1L, instanceId, "folder", "path", Storage.ProvisioningType.THIN, (long) 10 << 30, Volume.Type.ROOT); |
| vol1.setPassphraseId(1L); |
| |
| setupMocksForPlanDeploymentHostTests(host, vol1); |
| |
| VMInstanceVO vm = (VMInstanceVO) vmProfile.getVirtualMachine(); |
| vm.setLastHostId(hostId); |
| // host id is null here so we pick up last host id |
| DataCenterDeployment plan = new DataCenterDeployment(dataCenterId, podId, clusterId, null, null, null); |
| try { |
| DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids, null); |
| Assert.assertNull("Destination should be null since last host doesn't support encryption and root requires it", dest); |
| } catch (Exception ex) { |
| ex.printStackTrace(); |
| } |
| } |
| |
| @Test |
| public void passEncRootPlannerHostSupportingEncryptionTest() { |
| HostVO host = Mockito.spy(new HostVO("host")); |
| Map<String, String> hostDetails = new HashMap<>() {{ |
| put(Host.HOST_VOLUME_ENCRYPTION, "true"); |
| }}; |
| host.setDetails(hostDetails); |
| Mockito.when(host.getStatus()).thenReturn(Status.Up); |
| |
| VolumeVO vol1 = new VolumeVO("vol1", dataCenterId, podId, 1L, 1L, instanceId, "folder", "path", Storage.ProvisioningType.THIN, (long) 10 << 30, Volume.Type.ROOT); |
| vol1.setPassphraseId(1L); |
| |
| DeploymentClusterPlanner planner = setupMocksForPlanDeploymentHostTests(host, vol1); |
| |
| // host id is null here so we pick up last host id |
| DataCenterDeployment plan = new DataCenterDeployment(dataCenterId, podId, clusterId, null, null, null); |
| |
| try { |
| DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids, planner); |
| Assert.assertEquals(host, dest.getHost()); |
| } catch (Exception ex) { |
| ex.printStackTrace(); |
| } |
| } |
| |
| @Test |
| public void failEncRootPlannerHostSupportingEncryptionTest() { |
| HostVO host = Mockito.spy(new HostVO("host")); |
| Map<String, String> hostDetails = new HashMap<>() {{ |
| put(Host.HOST_VOLUME_ENCRYPTION, "false"); |
| }}; |
| host.setDetails(hostDetails); |
| Mockito.when(host.getStatus()).thenReturn(Status.Up); |
| |
| VolumeVO vol1 = new VolumeVO("vol1", dataCenterId, podId, 1L, 1L, instanceId, "folder", "path", Storage.ProvisioningType.THIN, (long) 10 << 30, Volume.Type.ROOT); |
| vol1.setPassphraseId(1L); |
| |
| DeploymentClusterPlanner planner = setupMocksForPlanDeploymentHostTests(host, vol1); |
| |
| // host id is null here so we pick up last host id |
| DataCenterDeployment plan = new DataCenterDeployment(dataCenterId, podId, clusterId, null, null, null); |
| |
| try { |
| DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids, planner); |
| Assert.assertNull("Destination should be null since last host doesn't support encryption and root requires it", dest); |
| } catch (Exception ex) { |
| ex.printStackTrace(); |
| } |
| } |
| |
| @Test |
| public void findSuitablePoolsForVolumesTest() throws Exception { |
| Long diskOfferingId = 1L; |
| HostVO host = Mockito.spy(new HostVO("host")); |
| Map<String, String> hostDetails = new HashMap<>() { |
| { |
| put(Host.HOST_VOLUME_ENCRYPTION, "true"); |
| } |
| }; |
| host.setDetails(hostDetails); |
| Mockito.when(host.getStatus()).thenReturn(Status.Up); |
| |
| VolumeVO vol1 = Mockito.spy(new VolumeVO("vol1", dataCenterId, podId, 1L, 1L, instanceId, "folder", "path", |
| Storage.ProvisioningType.THIN, (long) 10 << 30, Volume.Type.ROOT)); |
| Mockito.when(vol1.getId()).thenReturn(1L); |
| vol1.setState(Volume.State.Allocated); |
| vol1.setPassphraseId(1L); |
| vol1.setPoolId(1L); |
| vol1.setDiskOfferingId(diskOfferingId); |
| |
| StoragePoolVO storagePool = new StoragePoolVO(); |
| storagePool.setStatus(StoragePoolStatus.Maintenance); |
| storagePool.setId(vol1.getPoolId()); |
| storagePool.setDataCenterId(dataCenterId); |
| storagePool.setPodId(podId); |
| storagePool.setClusterId(clusterId); |
| |
| DiskProfile diskProfile = Mockito.mock(DiskProfile.class); |
| |
| StoragePoolAllocator allocator = Mockito.mock(StoragePoolAllocator.class); |
| |
| DataCenterDeployment plan = new DataCenterDeployment(dataCenterId, podId, clusterId, null, null, null); |
| |
| Account account = Mockito.mock(Account.class); |
| Mockito.when(account.getId()).thenReturn(1L); |
| Mockito.when(vmProfile.getOwner()).thenReturn(account); |
| Mockito.when(_accountMgr.isRootAdmin(account.getId())).thenReturn(Boolean.FALSE); |
| |
| Mockito.when(_dcDao.findById(dataCenterId)).thenReturn(dc); |
| Mockito.when(dc.getAllocationState()).thenReturn(AllocationState.Enabled); |
| |
| HostPodVO podVo = Mockito.mock(HostPodVO.class); |
| Mockito.when(podVo.getAllocationState()).thenReturn(AllocationState.Enabled); |
| Mockito.doReturn(podVo).when(_podDao).findById(podId); |
| |
| ClusterVO cluster = Mockito.mock(ClusterVO.class); |
| Mockito.when(cluster.getAllocationState()).thenReturn(AllocationState.Enabled); |
| Mockito.when(_clusterDao.findById(clusterId)).thenReturn(cluster); |
| |
| DiskOfferingVO diskOffering = Mockito.mock(DiskOfferingVO.class); |
| |
| Mockito.when(_diskOfferingDao.findById(vol1.getDiskOfferingId())).thenReturn(diskOffering); |
| VirtualMachineTemplate vmt = Mockito.mock(VirtualMachineTemplate.class); |
| |
| ServiceOfferingVO serviceOffering = Mockito.mock(ServiceOfferingVO.class); |
| Mockito.when(vmProfile.getServiceOffering()).thenReturn(serviceOffering); |
| |
| PrimaryDataStore primaryDataStore = Mockito.mock(PrimaryDataStore.class); |
| |
| Mockito.when(vmt.getFormat()).thenReturn(Storage.ImageFormat.ISO); |
| Mockito.when(vmProfile.getTemplate()).thenReturn(vmt); |
| |
| Mockito.when(vmProfile.getId()).thenReturn(1L); |
| Mockito.when(vmProfile.getType()).thenReturn(VirtualMachine.Type.User); |
| Mockito.when(volDao.findUsableVolumesForInstance(1L)).thenReturn(Arrays.asList(vol1)); |
| Mockito.when(volDao.findByInstanceAndType(1L, Volume.Type.ROOT)).thenReturn(Arrays.asList(vol1)); |
| Mockito.when(_dataStoreManager.getPrimaryDataStore(vol1.getPoolId())).thenReturn((DataStore) primaryDataStore); |
| Mockito.when(avoids.shouldAvoid(storagePool)).thenReturn(Boolean.FALSE); |
| |
| Mockito.doReturn(Arrays.asList(storagePool)).when(allocator).allocateToPool(diskProfile, vmProfile, plan, |
| avoids, 10); |
| Mockito.when(volDao.update(vol1.getId(), vol1)).thenReturn(true); |
| _dpm.findSuitablePoolsForVolumes(vmProfile, plan, avoids, 10); |
| verify(vol1, times(1)).setPoolId(null); |
| assertTrue(vol1.getPoolId() == null); |
| |
| } |
| |
| // This is so ugly but everything is so intertwined... |
| private DeploymentClusterPlanner setupMocksForPlanDeploymentHostTests(HostVO host, VolumeVO vol1) { |
| long diskOfferingId = 345L; |
| List<VolumeVO> volumeVOs = new ArrayList<>(); |
| List<Volume> volumes = new ArrayList<>(); |
| vol1.setDiskOfferingId(diskOfferingId); |
| volumes.add(vol1); |
| volumeVOs.add(vol1); |
| |
| DiskOfferingVO diskOffering = new DiskOfferingVO(); |
| diskOffering.setEncrypt(true); |
| |
| VMTemplateVO template = new VMTemplateVO(); |
| template.setFormat(Storage.ImageFormat.QCOW2); |
| |
| host.setClusterId(clusterId); |
| |
| StoragePool pool = new StoragePoolVO(); |
| |
| Map<Volume, List<StoragePool>> suitableVolumeStoragePools = new HashMap<>() {{ |
| put(vol1, List.of(pool)); |
| }}; |
| |
| Pair<Map<Volume, List<StoragePool>>, List<Volume>> suitable = new Pair<>(suitableVolumeStoragePools, volumes); |
| |
| ServiceOfferingVO svcOffering = new ServiceOfferingVO("test", 1, 256, 1, 1, 1, false, "vm", false, Type.User, false); |
| Mockito.when(vmProfile.getServiceOffering()).thenReturn(svcOffering); |
| Mockito.when(vmProfile.getHypervisorType()).thenReturn(HypervisorType.KVM); |
| Mockito.when(hostDao.findById(hostId)).thenReturn(host); |
| Mockito.doNothing().when(hostDao).loadDetails(host); |
| Mockito.doReturn(volumeVOs).when(volDao).findByInstance(ArgumentMatchers.anyLong()); |
| Mockito.doReturn(suitable).when(_dpm).findSuitablePoolsForVolumes( |
| ArgumentMatchers.any(VirtualMachineProfile.class), |
| ArgumentMatchers.any(DataCenterDeployment.class), |
| ArgumentMatchers.any(ExcludeList.class), |
| ArgumentMatchers.anyInt() |
| ); |
| |
| ClusterVO clusterVO = new ClusterVO(); |
| clusterVO.setHypervisorType(HypervisorType.KVM.toString()); |
| Mockito.when(_clusterDao.findById(ArgumentMatchers.anyLong())).thenReturn(clusterVO); |
| |
| Mockito.doReturn(List.of(host)).when(_dpm).findSuitableHosts( |
| ArgumentMatchers.any(VirtualMachineProfile.class), |
| ArgumentMatchers.any(DeploymentPlan.class), |
| ArgumentMatchers.any(ExcludeList.class), |
| ArgumentMatchers.anyInt() |
| ); |
| |
| Map<Volume, StoragePool> suitableVolumeStoragePoolMap = new HashMap<>() {{ |
| put(vol1, pool); |
| }}; |
| Mockito.doReturn(true).when(_dpm).hostCanAccessSPool(ArgumentMatchers.any(Host.class), ArgumentMatchers.any(StoragePool.class)); |
| |
| Pair<Host, Map<Volume, StoragePool>> potentialResources = new Pair<>(host, suitableVolumeStoragePoolMap); |
| |
| Mockito.when(capacityMgr.checkIfHostReachMaxGuestLimit(host)).thenReturn(false); |
| Mockito.when(capacityMgr.checkIfHostHasCpuCapability(ArgumentMatchers.anyLong(), ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt())).thenReturn(true); |
| Mockito.when(capacityMgr.checkIfHostHasCapacity( |
| ArgumentMatchers.anyLong(), |
| ArgumentMatchers.anyInt(), |
| ArgumentMatchers.anyLong(), |
| ArgumentMatchers.anyBoolean(), |
| ArgumentMatchers.anyFloat(), |
| ArgumentMatchers.anyFloat(), |
| ArgumentMatchers.anyBoolean() |
| )).thenReturn(true); |
| Mockito.when(serviceOfferingDetailsDao.findDetail(vmProfile.getServiceOfferingId(), GPU.Keys.vgpuType.toString())).thenReturn(null); |
| |
| Mockito.doReturn(true).when(_dpm).checkVmProfileAndHost(vmProfile, host); |
| Mockito.doReturn(true).when(_dpm).checkIfHostFitsPlannerUsage(ArgumentMatchers.anyLong(), ArgumentMatchers.nullable(PlannerResourceUsage.class)); |
| Mockito.when(clusterDetailsDao.findDetail(ArgumentMatchers.anyLong(), ArgumentMatchers.anyString())).thenReturn(new ClusterDetailsVO(clusterId, "mock", "1")); |
| |
| DeploymentClusterPlanner planner = Mockito.spy(new FirstFitPlanner()); |
| try { |
| Mockito.doReturn(List.of(clusterId), List.of()).when(planner).orderClusters( |
| ArgumentMatchers.any(VirtualMachineProfile.class), |
| ArgumentMatchers.any(DeploymentPlan.class), |
| ArgumentMatchers.any(ExcludeList.class) |
| ); |
| } catch (Exception ex) { |
| ex.printStackTrace(); |
| } |
| |
| return planner; |
| } |
| |
| private DataCenter prepareAvoidDisabledTests() { |
| DataCenter dc = Mockito.mock(DataCenter.class); |
| Mockito.when(dc.getId()).thenReturn(123l); |
| List<Long> podIds = new ArrayList<>(); |
| podIds.add(1l); |
| Mockito.doReturn(podIds).when(hostPodDao).listAllPods(Mockito.anyLong()); |
| return dc; |
| } |
| |
| private void assertAvoidIsEmpty(ExcludeList avoids, boolean isDcEmpty, boolean isPodsEmpty, boolean isClustersEmpty, |
| boolean isHostsEmpty) { |
| Assert.assertEquals(isDcEmpty, CollectionUtils.isEmpty(avoids.getDataCentersToAvoid())); |
| Assert.assertEquals(isPodsEmpty, CollectionUtils.isEmpty(avoids.getPodsToAvoid())); |
| Assert.assertEquals(isClustersEmpty, CollectionUtils.isEmpty(avoids.getClustersToAvoid())); |
| Assert.assertEquals(isHostsEmpty, CollectionUtils.isEmpty(avoids.getHostsToAvoid())); |
| } |
| |
| @Configuration |
| @ComponentScan(basePackageClasses = {DeploymentPlanningManagerImpl.class}, |
| includeFilters = {@Filter(value = TestConfiguration.Library.class, |
| type = FilterType.CUSTOM)}, useDefaultFilters = false) |
| public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration { |
| |
| @Bean |
| public FirstFitPlanner firstFitPlanner() { |
| return Mockito.mock(FirstFitPlanner.class); |
| } |
| |
| @Bean |
| public DeploymentPlanner deploymentPlanner() { |
| return Mockito.mock(DeploymentPlanner.class); |
| } |
| |
| @Bean |
| public DataCenterVO dataCenter() { |
| return Mockito.mock(DataCenterVO.class); |
| } |
| |
| @Bean |
| public ExcludeList excludeList() { |
| return Mockito.mock(ExcludeList.class); |
| } |
| |
| @Bean |
| public VirtualMachineProfileImpl virtualMachineProfileImpl() { |
| return Mockito.mock(VirtualMachineProfileImpl.class); |
| } |
| |
| @Bean |
| public HostTagsDao hostTagsDao() { |
| return Mockito.mock(HostTagsDao.class); |
| } |
| |
| @Bean |
| public HostDetailsDao hostDetailsDao() { |
| return Mockito.mock(HostDetailsDao.class); |
| } |
| |
| |
| @Bean |
| public ClusterDetailsDao clusterDetailsDao() { |
| return Mockito.mock(ClusterDetailsDao.class); |
| } |
| |
| @Bean |
| public ResourceManager resourceManager() { |
| return Mockito.mock(ResourceManager.class); |
| } |
| |
| @Bean |
| public ServiceOfferingDetailsDao serviceOfferingDetailsDao() { |
| return Mockito.mock(ServiceOfferingDetailsDao.class); |
| } |
| |
| @Bean |
| public AffinityGroupDomainMapDao affinityGroupDomainMapDao() { |
| return Mockito.mock(AffinityGroupDomainMapDao.class); |
| } |
| |
| @Bean |
| public DataStoreManager cataStoreManager() { |
| return Mockito.mock(DataStoreManager.class); |
| } |
| |
| @Bean |
| public StorageManager storageManager() { |
| return Mockito.mock(StorageManager.class); |
| } |
| |
| @Bean |
| public HostDao hostDao() { |
| return Mockito.mock(HostDao.class); |
| } |
| |
| @Bean |
| public HostPodDao hostPodDao() { |
| return Mockito.mock(HostPodDao.class); |
| } |
| |
| @Bean |
| public ClusterDao clusterDao() { |
| return Mockito.mock(ClusterDao.class); |
| } |
| |
| @Bean |
| public DedicatedResourceDao dedicatedResourceDao() { |
| return Mockito.mock(DedicatedResourceDao.class); |
| } |
| |
| @Bean |
| public GuestOSDao guestOSDao() { |
| return Mockito.mock(GuestOSDao.class); |
| } |
| |
| @Bean |
| public GuestOSCategoryDao guestOSCategoryDao() { |
| return Mockito.mock(GuestOSCategoryDao.class); |
| } |
| |
| @Bean |
| public CapacityManager capacityManager() { |
| return Mockito.mock(CapacityManager.class); |
| } |
| |
| @Bean |
| public StoragePoolHostDao storagePoolHostDao() { |
| return Mockito.mock(StoragePoolHostDao.class); |
| } |
| |
| @Bean |
| public VolumeDao volumeDao() { |
| return Mockito.mock(VolumeDao.class); |
| } |
| |
| @Bean |
| public ConfigurationDao configurationDao() { |
| return Mockito.mock(ConfigurationDao.class); |
| } |
| |
| @Bean |
| public DiskOfferingDao diskOfferingDao() { |
| return Mockito.mock(DiskOfferingDao.class); |
| } |
| |
| @Bean |
| public PrimaryDataStoreDao primaryDataStoreDao() { |
| return Mockito.mock(PrimaryDataStoreDao.class); |
| } |
| |
| @Bean |
| public CapacityDao capacityDao() { |
| return Mockito.mock(CapacityDao.class); |
| } |
| |
| @Bean |
| public PlannerHostReservationDao plannerHostReservationDao() { |
| return Mockito.mock(PlannerHostReservationDao.class); |
| } |
| |
| @Bean |
| public AffinityGroupProcessor affinityGroupProcessor() { |
| return Mockito.mock(AffinityGroupProcessor.class); |
| } |
| |
| @Bean |
| public AffinityGroupDao affinityGroupDao() { |
| return Mockito.mock(AffinityGroupDao.class); |
| } |
| |
| @Bean |
| public AffinityGroupVMMapDao affinityGroupVMMapDao() { |
| return Mockito.mock(AffinityGroupVMMapDao.class); |
| } |
| |
| @Bean |
| public AccountManager accountManager() { |
| return Mockito.mock(AccountManager.class); |
| } |
| |
| @Bean |
| public AgentManager agentManager() { |
| return Mockito.mock(AgentManager.class); |
| } |
| |
| @Bean |
| public MessageBus messageBus() { |
| return Mockito.mock(MessageBus.class); |
| } |
| |
| @Bean |
| public UserVmDao userVMDao() { |
| return Mockito.mock(UserVmDao.class); |
| } |
| |
| @Bean |
| public UserVmDetailsDao userVmDetailsDao() { |
| return Mockito.mock(UserVmDetailsDao.class); |
| } |
| |
| @Bean |
| public VMInstanceDao vmInstanceDao() { |
| return Mockito.mock(VMInstanceDao.class); |
| } |
| |
| @Bean |
| public DataCenterDao dataCenterDao() { |
| return Mockito.mock(DataCenterDao.class); |
| } |
| |
| @Bean |
| public VMReservationDao reservationDao() { |
| return Mockito.mock(VMReservationDao.class); |
| } |
| |
| @Bean |
| public AffinityGroupService affinityGroupService() { |
| return Mockito.mock(AffinityGroupService.class); |
| } |
| |
| @Bean |
| public HostGpuGroupsDao hostGpuGroupsDao() { |
| return Mockito.mock(HostGpuGroupsDao.class); |
| } |
| |
| @Bean |
| public AccountDao accountDao() { |
| return Mockito.mock(AccountDao.class); |
| } |
| |
| @Bean |
| public VMTemplateDao vmTemplateDao() { |
| return Mockito.mock(VMTemplateDao.class); |
| } |
| |
| public static class Library implements TypeFilter { |
| |
| @Override |
| public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { |
| ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class); |
| return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); |
| } |
| } |
| } |
| |
| @Test |
| public void testReorderHostsByPriority() { |
| Map<Long, Integer> priorities = new LinkedHashMap<>(); |
| priorities.put(1L, 3); |
| priorities.put(2L, -6); |
| priorities.put(3L, 5); |
| priorities.put(5L, 8); |
| priorities.put(6L, -1); |
| priorities.put(8L, 5); |
| priorities.put(9L, DataCenterDeployment.PROHIBITED_HOST_PRIORITY); |
| |
| Host host1 = Mockito.mock(Host.class); |
| Mockito.when(host1.getId()).thenReturn(1L); |
| Host host2 = Mockito.mock(Host.class); |
| Mockito.when(host2.getId()).thenReturn(2L); |
| Host host3 = Mockito.mock(Host.class); |
| Mockito.when(host3.getId()).thenReturn(3L); |
| Host host4 = Mockito.mock(Host.class); |
| Mockito.when(host4.getId()).thenReturn(4L); |
| Host host5 = Mockito.mock(Host.class); |
| Mockito.when(host5.getId()).thenReturn(5L); |
| Host host6 = Mockito.mock(Host.class); |
| Mockito.when(host6.getId()).thenReturn(6L); |
| Host host7 = Mockito.mock(Host.class); |
| Mockito.when(host7.getId()).thenReturn(7L); |
| Host host8 = Mockito.mock(Host.class); |
| Mockito.when(host8.getId()).thenReturn(8L); |
| Host host9 = Mockito.mock(Host.class); |
| Mockito.when(host9.getId()).thenReturn(9L); |
| |
| List<Host> hosts = new ArrayList<>(Arrays.asList(host1, host2, host3, host4, host5, host6, host7, host8, host9)); |
| _dpm.reorderHostsByPriority(priorities, hosts); |
| |
| Assert.assertEquals(8, hosts.size()); |
| |
| Assert.assertEquals(5, hosts.get(0).getId()); |
| Assert.assertEquals(3, hosts.get(1).getId()); |
| Assert.assertEquals(8, hosts.get(2).getId()); |
| Assert.assertEquals(1, hosts.get(3).getId()); |
| Assert.assertEquals(4, hosts.get(4).getId()); |
| Assert.assertEquals(7, hosts.get(5).getId()); |
| Assert.assertEquals(6, hosts.get(6).getId()); |
| Assert.assertEquals(2, hosts.get(7).getId()); |
| } |
| |
| private List<Long> prepareMockForAvoidOtherClustersForDeploymentIfMigrationDisabled(boolean configValue, |
| boolean mockVolumes, boolean mockClusterStoreVolume) { |
| try { |
| Field f = ConfigKey.class.getDeclaredField("_defaultValue"); |
| f.setAccessible(true); |
| f.set(ConfigurationManagerImpl.MIGRATE_VM_ACROSS_CLUSTERS, String.valueOf(configValue)); |
| } catch (NoSuchFieldException | IllegalAccessException e) { |
| throw new RuntimeException(e); |
| } |
| List<Long> allClusters = List.of(101L, 102L, 103L, 104L); |
| Mockito.when(_clusterDao.listAllClusters(Mockito.anyLong())).thenReturn(allClusters); |
| if (mockVolumes) { |
| VolumeVO vol1 = Mockito.mock(VolumeVO.class); |
| Mockito.when(vol1.getPoolId()).thenReturn(1L); |
| VolumeVO vol2 = Mockito.mock(VolumeVO.class); |
| Mockito.when(vol2.getPoolId()).thenReturn(2L); |
| StoragePoolVO pool1 = Mockito.mock(StoragePoolVO.class); |
| Mockito.when(pool1.getScope()).thenReturn(ScopeType.ZONE); |
| Mockito.when(primaryDataStoreDao.findById(1L)).thenReturn(pool1); |
| StoragePoolVO pool2 = Mockito.mock(StoragePoolVO.class); |
| Mockito.when(pool2.getScope()).thenReturn(mockClusterStoreVolume ? ScopeType.CLUSTER : ScopeType.GLOBAL); |
| Mockito.when(primaryDataStoreDao.findById(2L)).thenReturn(pool2); |
| Mockito.when(volDao.findUsableVolumesForInstance(1L)).thenReturn(List.of(vol1, vol2)); |
| } else { |
| Mockito.when(volDao.findUsableVolumesForInstance(1L)).thenReturn(new ArrayList<>()); |
| } |
| return allClusters; |
| } |
| |
| @Test |
| public void avoidOtherClustersForDeploymentIfMigrationDisabledNonValidHost() { |
| prepareMockForAvoidOtherClustersForDeploymentIfMigrationDisabled(false, false, false); |
| VirtualMachine vm = Mockito.mock(VirtualMachine.class); |
| ExcludeList excludeList = new ExcludeList(); |
| _dpm.avoidOtherClustersForDeploymentIfMigrationDisabled(vm, null, excludeList); |
| Assert.assertTrue(CollectionUtils.isEmpty(excludeList.getClustersToAvoid())); |
| |
| Host lastHost = Mockito.mock(Host.class); |
| Mockito.when(lastHost.getClusterId()).thenReturn(null); |
| _dpm.avoidOtherClustersForDeploymentIfMigrationDisabled(vm, lastHost, excludeList); |
| Assert.assertTrue(CollectionUtils.isEmpty(excludeList.getClustersToAvoid())); |
| } |
| |
| private Set<Long> runAvoidOtherClustersForDeploymentIfMigrationDisabledTest() { |
| VirtualMachine vm = Mockito.mock(VirtualMachine.class); |
| Mockito.when(vm.getId()).thenReturn(1L); |
| ExcludeList excludeList = new ExcludeList(); |
| Host lastHost = Mockito.mock(Host.class); |
| Long sourceClusterId = 101L; |
| Mockito.when(lastHost.getClusterId()).thenReturn(sourceClusterId); |
| _dpm.avoidOtherClustersForDeploymentIfMigrationDisabled(vm, lastHost, excludeList); |
| return excludeList.getClustersToAvoid(); |
| } |
| |
| @Test |
| public void avoidOtherClustersForDeploymentIfMigrationDisabledConfigAllows() { |
| prepareMockForAvoidOtherClustersForDeploymentIfMigrationDisabled(true, false, false); |
| Assert.assertTrue(CollectionUtils.isEmpty(runAvoidOtherClustersForDeploymentIfMigrationDisabledTest())); |
| } |
| |
| @Test |
| public void avoidOtherClustersForDeploymentIfMigrationDisabledNoVmVolumes() { |
| prepareMockForAvoidOtherClustersForDeploymentIfMigrationDisabled(false, false, false); |
| Assert.assertTrue(CollectionUtils.isEmpty(runAvoidOtherClustersForDeploymentIfMigrationDisabledTest())); |
| } |
| |
| @Test |
| public void avoidOtherClustersForDeploymentIfMigrationDisabledVmVolumesNonValidScope() { |
| prepareMockForAvoidOtherClustersForDeploymentIfMigrationDisabled(false, true, false); |
| Assert.assertTrue(CollectionUtils.isEmpty(runAvoidOtherClustersForDeploymentIfMigrationDisabledTest())); |
| } |
| |
| @Test |
| public void avoidOtherClustersForDeploymentIfMigrationDisabledValid() { |
| List<Long> allClusters = prepareMockForAvoidOtherClustersForDeploymentIfMigrationDisabled(false, true, true); |
| Set<Long> avoidedClusters = runAvoidOtherClustersForDeploymentIfMigrationDisabledTest(); |
| Assert.assertTrue(CollectionUtils.isNotEmpty(avoidedClusters)); |
| Assert.assertEquals(allClusters.size() - 1, avoidedClusters.size()); |
| Assert.assertFalse(avoidedClusters.contains(allClusters.get(0))); |
| } |
| } |