|
29 | 29 | import com.cloud.exception.InvalidParameterValueException; |
30 | 30 | import com.cloud.host.Host; |
31 | 31 | import com.cloud.host.HostVO; |
| 32 | +import com.cloud.deploy.DeploymentPlanner.ExcludeList; |
32 | 33 | import com.cloud.host.dao.HostDao; |
33 | 34 | import com.cloud.offering.ServiceOffering; |
34 | 35 | import com.cloud.org.Cluster; |
35 | 36 | import com.cloud.org.Grouping; |
36 | 37 | import com.cloud.server.ManagementServer; |
37 | 38 | import com.cloud.service.ServiceOfferingVO; |
| 39 | +import org.apache.cloudstack.affinity.AffinityGroupVMMapVO; |
38 | 40 | import com.cloud.service.dao.ServiceOfferingDao; |
39 | 41 | import com.cloud.utils.Pair; |
40 | 42 | import com.cloud.utils.Ternary; |
|
70 | 72 | import java.lang.reflect.Field; |
71 | 73 | import java.util.ArrayList; |
72 | 74 | import java.util.Collections; |
| 75 | +import org.apache.cloudstack.jobs.JobInfo; |
73 | 76 | import java.util.Date; |
74 | 77 | import java.util.HashMap; |
75 | 78 | import java.util.List; |
76 | 79 | import java.util.Map; |
77 | 80 |
|
78 | 81 | import static org.junit.Assert.assertEquals; |
79 | 82 | import static org.junit.Assert.assertFalse; |
| 83 | +import static org.junit.Assert.assertTrue; |
80 | 84 | import static org.junit.Assert.assertNull; |
81 | 85 |
|
82 | 86 | @RunWith(MockitoJUnitRunner.class) |
@@ -951,4 +955,86 @@ public void testProcessPlans() { |
951 | 955 |
|
952 | 956 | Mockito.verify(clusterDrsService, Mockito.times(2)).executeDrsPlan(Mockito.any(ClusterDrsPlanVO.class)); |
953 | 957 | } |
| 958 | + |
| 959 | + @Test |
| 960 | + public void testDestinationViolatesAffinityWhenVmHasNoAffinityGroups() { |
| 961 | + VMInstanceVO vm = Mockito.mock(VMInstanceVO.class); |
| 962 | + Mockito.when(vm.getId()).thenReturn(1L); |
| 963 | + Mockito.when(affinityGroupVMMapDao.listByInstanceId(1L)).thenReturn(Collections.emptyList()); |
| 964 | + |
| 965 | + HostVO destHost = Mockito.mock(HostVO.class); |
| 966 | + |
| 967 | + assertFalse(clusterDrsService.destinationViolatesAffinity(vm, destHost, Collections.emptyList())); |
| 968 | + Mockito.verify(managementServer, Mockito.never()) |
| 969 | + .applyAffinityConstraints(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); |
| 970 | + } |
| 971 | + |
| 972 | + @Test |
| 973 | + public void testDestinationViolatesAffinityWhenDestHostIsExcluded() { |
| 974 | + VMInstanceVO vm = Mockito.mock(VMInstanceVO.class); |
| 975 | + Mockito.when(vm.getId()).thenReturn(1L); |
| 976 | + Mockito.when(vm.getServiceOfferingId()).thenReturn(5L); |
| 977 | + Mockito.when(affinityGroupVMMapDao.listByInstanceId(1L)) |
| 978 | + .thenReturn(Collections.singletonList(Mockito.mock(AffinityGroupVMMapVO.class))); |
| 979 | + Mockito.when(serviceOfferingDao.findByIdIncludingRemoved(1L, 5L)) |
| 980 | + .thenReturn(Mockito.mock(ServiceOfferingVO.class)); |
| 981 | + |
| 982 | + HostVO destHost = Mockito.mock(HostVO.class); |
| 983 | + Mockito.when(destHost.getId()).thenReturn(20L); |
| 984 | + |
| 985 | + ExcludeList excludes = new ExcludeList(); |
| 986 | + excludes.addHost(20L); |
| 987 | + Mockito.when(managementServer.applyAffinityConstraints(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) |
| 988 | + .thenReturn(excludes); |
| 989 | + |
| 990 | + assertTrue(clusterDrsService.destinationViolatesAffinity(vm, destHost, Collections.emptyList())); |
| 991 | + } |
| 992 | + |
| 993 | + @Test |
| 994 | + public void testDestinationViolatesAffinityWhenDestHostIsAllowed() { |
| 995 | + VMInstanceVO vm = Mockito.mock(VMInstanceVO.class); |
| 996 | + Mockito.when(vm.getId()).thenReturn(1L); |
| 997 | + Mockito.when(vm.getServiceOfferingId()).thenReturn(5L); |
| 998 | + Mockito.when(affinityGroupVMMapDao.listByInstanceId(1L)) |
| 999 | + .thenReturn(Collections.singletonList(Mockito.mock(AffinityGroupVMMapVO.class))); |
| 1000 | + Mockito.when(serviceOfferingDao.findByIdIncludingRemoved(1L, 5L)) |
| 1001 | + .thenReturn(Mockito.mock(ServiceOfferingVO.class)); |
| 1002 | + |
| 1003 | + HostVO destHost = Mockito.mock(HostVO.class); |
| 1004 | + Mockito.when(destHost.getId()).thenReturn(20L); |
| 1005 | + |
| 1006 | + ExcludeList excludes = new ExcludeList(); |
| 1007 | + excludes.addHost(21L); |
| 1008 | + Mockito.when(managementServer.applyAffinityConstraints(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) |
| 1009 | + .thenReturn(excludes); |
| 1010 | + |
| 1011 | + assertFalse(clusterDrsService.destinationViolatesAffinity(vm, destHost, Collections.emptyList())); |
| 1012 | + } |
| 1013 | + |
| 1014 | + @Test |
| 1015 | + public void testExecuteDrsPlanSkipsMigrationThatViolatesAffinity() { |
| 1016 | + ClusterDrsPlanVO plan = Mockito.mock(ClusterDrsPlanVO.class); |
| 1017 | + Mockito.when(plan.getId()).thenReturn(1L); |
| 1018 | + |
| 1019 | + ClusterDrsPlanMigrationVO migration = Mockito.mock(ClusterDrsPlanMigrationVO.class); |
| 1020 | + Mockito.when(migration.getId()).thenReturn(7L); |
| 1021 | + Mockito.when(migration.getVmId()).thenReturn(1L); |
| 1022 | + Mockito.when(migration.getDestHostId()).thenReturn(20L); |
| 1023 | + Mockito.when(drsPlanMigrationDao.listPlanMigrationsToExecute(1L)) |
| 1024 | + .thenReturn(Collections.singletonList(migration)); |
| 1025 | + |
| 1026 | + VMInstanceVO vm = Mockito.mock(VMInstanceVO.class); |
| 1027 | + HostVO destHost = Mockito.mock(HostVO.class); |
| 1028 | + Mockito.when(vmInstanceDao.findById(1L)).thenReturn(vm); |
| 1029 | + Mockito.when(hostDao.findById(20L)).thenReturn(destHost); |
| 1030 | + |
| 1031 | + Mockito.doReturn(true).when(clusterDrsService) |
| 1032 | + .destinationViolatesAffinity(Mockito.any(), Mockito.any(), Mockito.any()); |
| 1033 | + |
| 1034 | + clusterDrsService.executeDrsPlan(plan); |
| 1035 | + |
| 1036 | + Mockito.verify(migration).setStatus(JobInfo.Status.FAILED); |
| 1037 | + Mockito.verify(clusterDrsService, Mockito.never()) |
| 1038 | + .createMigrateVMAsyncJob(Mockito.any(), Mockito.any(), Mockito.anyLong()); |
| 1039 | + } |
954 | 1040 | } |
0 commit comments