Skip to content

Commit 507f6fc

Browse files
Added more unit tests
1 parent 3c56d34 commit 507f6fc

File tree

3 files changed

+396
-44
lines changed

3 files changed

+396
-44
lines changed

server/src/main/java/com/cloud/resource/ResourceManagerImpl.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2324,12 +2324,12 @@ protected void checkIfAllHostsInUse(List<String> sagsToDelete, Long clusterId, L
23242324
return;
23252325
}
23262326

2327-
List<Long> hostIdsUsingStorageTags = listOfHostIdsUsingTheStorageAccessGroups(sagsToDelete, clusterId, podId, zoneId);
2327+
List<Long> hostIdsUsingStorageAccessGroups = listOfHostIdsUsingTheStorageAccessGroups(sagsToDelete, clusterId, podId, zoneId);
23282328

23292329
// Check for zone level hosts
23302330
if (zoneId != null) {
23312331
List<HostVO> hostsInZone = _hostDao.findByDataCenterId(zoneId);
2332-
Set<Long> hostIdsInUseSet = hostIdsUsingStorageTags.stream().collect(Collectors.toSet());
2332+
Set<Long> hostIdsInUseSet = hostIdsUsingStorageAccessGroups.stream().collect(Collectors.toSet());
23332333

23342334
boolean allInUseZone = hostsInZone.stream()
23352335
.map(HostVO::getId)
@@ -2343,7 +2343,7 @@ protected void checkIfAllHostsInUse(List<String> sagsToDelete, Long clusterId, L
23432343
// Check for cluster level hosts
23442344
if (clusterId != null) {
23452345
List<HostVO> hostsInCluster = _hostDao.findByClusterId(clusterId, Type.Routing);
2346-
Set<Long> hostIdsInUseSet = hostIdsUsingStorageTags.stream().collect(Collectors.toSet());
2346+
Set<Long> hostIdsInUseSet = hostIdsUsingStorageAccessGroups.stream().collect(Collectors.toSet());
23472347

23482348
boolean allInUseCluster = hostsInCluster.stream()
23492349
.map(HostVO::getId)
@@ -2357,7 +2357,7 @@ protected void checkIfAllHostsInUse(List<String> sagsToDelete, Long clusterId, L
23572357
// Check for pod level hosts
23582358
if (podId != null) {
23592359
List<HostVO> hostsInPod = _hostDao.findByPodId(podId, Type.Routing);
2360-
Set<Long> hostIdsInUseSet = hostIdsUsingStorageTags.stream().collect(Collectors.toSet());
2360+
Set<Long> hostIdsInUseSet = hostIdsUsingStorageAccessGroups.stream().collect(Collectors.toSet());
23612361

23622362
boolean allInUsePod = hostsInPod.stream()
23632363
.map(HostVO::getId)
@@ -2464,11 +2464,13 @@ public void updateClusterStorageAccessGroups(Long clusterId, List<String> newSto
24642464
Map<HostVO, List<String>> hostsAndStorageAccessGroupsMap = new HashMap<>();
24652465
for (HostVO host : hostsInCluster) {
24662466
String[] existingSAGs = _storageMgr.getStorageAccessGroups(null, null, null, host.getId());
2467-
List<String> existingSAGsList = new ArrayList<>(Arrays.asList(existingSAGs));
2468-
existingSAGsList.removeAll(sagsToDelete);
2469-
List<String> combinedSAGs = new ArrayList<>(sagsToAdd);
2470-
combinedSAGs.addAll(existingSAGsList);
2471-
hostsAndStorageAccessGroupsMap.put(host, combinedSAGs);
2467+
Set<String> existingSAGsSet = new HashSet<>(Arrays.asList(existingSAGs));
2468+
existingSAGsSet.removeAll(sagsToDelete);
2469+
List<String> existingSAGsList = new ArrayList<>(existingSAGsSet);
2470+
Set<String> combinedSAGsSet = new HashSet<>(sagsToAdd);
2471+
combinedSAGsSet.addAll(existingSAGsList);
2472+
2473+
hostsAndStorageAccessGroupsMap.put(host, new ArrayList<>(combinedSAGsSet));
24722474
}
24732475

24742476
updateConnectionsBetweenHostsAndStoragePools(hostsAndStorageAccessGroupsMap);
@@ -2533,7 +2535,7 @@ protected void checkIfAnyVolumesInUse(List<String> sagsToAdd, List<String> sagsT
25332535
}
25342536
}
25352537

2536-
private void updateConnectionsBetweenHostsAndStoragePools(Map<HostVO, List<String>> hostsAndStorageAccessGroupsMap) {
2538+
protected void updateConnectionsBetweenHostsAndStoragePools(Map<HostVO, List<String>> hostsAndStorageAccessGroupsMap) {
25372539
List<HostVO> hostsList = new ArrayList<>(hostsAndStorageAccessGroupsMap.keySet());
25382540
Map<HostVO, List<StoragePoolVO>> hostStoragePoolsMapBefore = getHostStoragePoolsBefore(hostsList);
25392541

server/src/test/java/com/cloud/resource/ResourceManagerImplTest.java

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
import com.cloud.agent.api.GetVncPortAnswer;
2222
import com.cloud.agent.api.GetVncPortCommand;
2323
import com.cloud.capacity.dao.CapacityDao;
24+
import com.cloud.dc.ClusterVO;
25+
import com.cloud.dc.DataCenterVO;
26+
import com.cloud.dc.HostPodVO;
27+
import com.cloud.dc.dao.ClusterDao;
28+
import com.cloud.dc.dao.DataCenterDao;
29+
import com.cloud.dc.dao.HostPodDao;
2430
import com.cloud.event.ActionEventUtils;
2531
import com.cloud.exception.InvalidParameterValueException;
2632
import com.cloud.ha.HighAvailabilityManager;
@@ -34,6 +40,7 @@
3440
import com.cloud.storage.StoragePoolHostVO;
3541
import com.cloud.storage.Volume;
3642
import com.cloud.storage.VolumeVO;
43+
import com.cloud.storage.dao.StoragePoolAndAccessGroupMapDao;
3744
import com.cloud.storage.dao.StoragePoolHostDao;
3845
import com.cloud.storage.dao.VolumeDao;
3946
import com.cloud.utils.Ternary;
@@ -48,6 +55,8 @@
4855
import com.trilead.ssh2.Connection;
4956
import org.apache.cloudstack.api.command.admin.host.CancelHostAsDegradedCmd;
5057
import org.apache.cloudstack.api.command.admin.host.DeclareHostAsDegradedCmd;
58+
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
59+
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
5160
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
5261
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
5362
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
@@ -102,6 +111,12 @@ public class ResourceManagerImplTest {
102111
@Mock
103112
private HostDao hostDao;
104113
@Mock
114+
private ClusterDao clusterDao;
115+
@Mock
116+
private HostPodDao podDao;
117+
@Mock
118+
private DataCenterDao dcDao;
119+
@Mock
105120
private VMInstanceDao vmInstanceDao;
106121
@Mock
107122
private ConfigurationDao configurationDao;
@@ -137,6 +152,9 @@ public class ResourceManagerImplTest {
137152
@Mock
138153
private Connection sshConnection;
139154

155+
@Mock
156+
private StoragePoolAndAccessGroupMapDao storagePoolAccessGroupMapDao;
157+
140158
private static long hostId = 1L;
141159
private static final String hostUsername = "user";
142160
private static final String hostPassword = "password";
@@ -954,4 +972,206 @@ public void testUpdateStoragePoolConnectionsOnHosts_ConflictWithHostIdsAndVolume
954972
}
955973
}
956974

975+
@Test(expected = CloudRuntimeException.class)
976+
public void testNoUpHostsThrowsException() {
977+
PrimaryDataStoreInfo primaryStore = Mockito.mock(PrimaryDataStoreInfo.class);
978+
Mockito.when(primaryStore.getClusterId()).thenReturn(1L);
979+
Mockito.doReturn(Collections.emptyList()).when(resourceManager).listAllUpHosts(Mockito.any(), Mockito.anyLong(), Mockito.any(), Mockito.anyLong());
980+
resourceManager.getEligibleUpHostsInClusterForStorageConnection(primaryStore);
981+
}
982+
983+
@Test(expected = CloudRuntimeException.class)
984+
public void testNoUpAndEnabledHostsThrowsException() {
985+
PrimaryDataStoreInfo primaryStore = Mockito.mock(PrimaryDataStoreInfo.class);
986+
Mockito.when(primaryStore.getClusterId()).thenReturn(1L);
987+
Mockito.doReturn(Collections.emptyList()).when(resourceManager).listAllUpAndEnabledHosts(Mockito.any(), Mockito.anyLong(), Mockito.any(), Mockito.anyLong());
988+
resourceManager.getEligibleUpAndEnabledHostsInClusterForStorageConnection(primaryStore);
989+
}
990+
991+
@Test
992+
public void testEligibleHostsMatchingStorageAccessGroups() {
993+
PrimaryDataStoreInfo primaryStore = Mockito.mock(PrimaryDataStoreInfo.class);
994+
DataStore dataStore = Mockito.mock(DataStore.class);
995+
Mockito.when(primaryStore.getId()).thenReturn(1L);
996+
Mockito.when(dataStore.getId()).thenReturn(1L);
997+
Mockito.when(primaryStore.getClusterId()).thenReturn(1L);
998+
999+
HostVO host1 = Mockito.mock(HostVO.class);
1000+
HostVO host2 = Mockito.mock(HostVO.class);
1001+
List<HostVO> allHosts = Arrays.asList(host1, host2);
1002+
1003+
Mockito.when(host1.getId()).thenReturn(1L);
1004+
Mockito.when(host2.getId()).thenReturn(2L);
1005+
1006+
Mockito.doReturn(allHosts).when(resourceManager).listAllUpHosts(Mockito.any(), Mockito.anyLong(), Mockito.any(), Mockito.anyLong());
1007+
Mockito.doReturn(allHosts).when(resourceManager).listAllUpAndEnabledHosts(Mockito.any(), Mockito.anyLong(), Mockito.any(), Mockito.anyLong());
1008+
Mockito.doReturn(allHosts).when(resourceManager).listAllUpAndEnabledHostsInOneZoneByHypervisor(Mockito.any(), Mockito.anyLong());
1009+
Mockito.doReturn(Arrays.asList("group1", "group2")).when(storagePoolAccessGroupMapDao).getStorageAccessGroups(1L);
1010+
1011+
Mockito.doReturn(new String[]{"group1"})
1012+
.when(storageManager).getStorageAccessGroups(null, null, null, 1L);
1013+
Mockito.doReturn(new String[]{"group3"})
1014+
.when(storageManager).getStorageAccessGroups(null, null, null, 2L);
1015+
1016+
List<HostVO> hostsToConnect = resourceManager.getEligibleUpHostsInClusterForStorageConnection(primaryStore);
1017+
1018+
Assert.assertEquals("Only one host should match the storage access groups.", 1, hostsToConnect.size());
1019+
Assert.assertTrue("Host1 should be included as it matches the storage access group.", hostsToConnect.contains(host1));
1020+
Assert.assertFalse("Host2 should not be included as it does not match any storage access group.", hostsToConnect.contains(host2));
1021+
1022+
hostsToConnect = resourceManager.getEligibleUpAndEnabledHostsInClusterForStorageConnection(primaryStore);
1023+
1024+
Assert.assertEquals("Only one host should match the storage access groups.", 1, hostsToConnect.size());
1025+
Assert.assertTrue("Host1 should be included as it matches the storage access group.", hostsToConnect.contains(host1));
1026+
Assert.assertFalse("Host2 should not be included as it does not match any storage access group.", hostsToConnect.contains(host2));
1027+
1028+
hostsToConnect = resourceManager.getEligibleUpAndEnabledHostsInZoneForStorageConnection(dataStore, 1L, Hypervisor.HypervisorType.KVM);
1029+
1030+
Assert.assertEquals("Only one host should match the storage access groups.", 1, hostsToConnect.size());
1031+
Assert.assertTrue("Host1 should be included as it matches the storage access group.", hostsToConnect.contains(host1));
1032+
Assert.assertFalse("Host2 should not be included as it does not match any storage access group.", hostsToConnect.contains(host2));
1033+
}
1034+
1035+
@Test
1036+
public void testUpdateZoneStorageAccessGroups() {
1037+
long zoneId = 1L;
1038+
long podId = 2L;
1039+
long clusterId = 3L;
1040+
long host1Id = 1L;
1041+
long host2Id = 2L;
1042+
List<String> newStorageAccessGroups = Arrays.asList("group1", "group2");
1043+
1044+
DataCenterVO zoneVO = Mockito.mock(DataCenterVO.class);
1045+
Mockito.when(dcDao.findById(zoneId)).thenReturn(zoneVO);
1046+
Mockito.when(zoneVO.getId()).thenReturn(zoneId);
1047+
Mockito.when(zoneVO.getStorageAccessGroups()).thenReturn("group1,group3");
1048+
1049+
HostVO host1 = Mockito.mock(HostVO.class);
1050+
HostVO host2 = Mockito.mock(HostVO.class);
1051+
Mockito.when(host1.getId()).thenReturn(host1Id);
1052+
Mockito.when(host2.getId()).thenReturn(host2Id);
1053+
1054+
HostPodVO pod1 = Mockito.mock(HostPodVO.class);
1055+
ClusterVO cluster1 = Mockito.mock(ClusterVO.class);
1056+
Mockito.when(pod1.getId()).thenReturn(podId);
1057+
Mockito.when(cluster1.getId()).thenReturn(clusterId);
1058+
Mockito.when(podDao.findById(podId)).thenReturn(pod1);
1059+
Mockito.when(clusterDao.findById(clusterId)).thenReturn(cluster1);
1060+
Mockito.when(podDao.listByDataCenterId(zoneId)).thenReturn(Collections.singletonList(pod1));
1061+
Mockito.when(clusterDao.listByPodId(podId)).thenReturn(Collections.singletonList(cluster1));
1062+
Mockito.when(hostDao.findHypervisorHostInPod(podId)).thenReturn(Arrays.asList(host1, host2));
1063+
Mockito.when(hostDao.findByDataCenterId(zoneId)).thenReturn(Arrays.asList(host1, host2));
1064+
Mockito.when(hostDao.findByClusterId(clusterId)).thenReturn(Arrays.asList(host1, host2));
1065+
1066+
List<Long> hostIdsUsingStorageTags = Arrays.asList(host1Id);
1067+
Mockito.doReturn(hostIdsUsingStorageTags).when(resourceManager).listOfHostIdsUsingTheStorageAccessGroups(any(), any(), any(), any());
1068+
1069+
Mockito.doReturn(new String[]{"group1", "group3"}).when(storageManager).getStorageAccessGroups(null, null, null, host1Id);
1070+
Mockito.doReturn(new String[]{"group2", "group4"}).when(storageManager).getStorageAccessGroups(null, null, null, host2Id);
1071+
1072+
resourceManager.updateZoneStorageAccessGroups(zoneId, newStorageAccessGroups);
1073+
1074+
Mockito.verify(hostDao, Mockito.times(2)).update(host1Id, host1);
1075+
Mockito.verify(hostDao, Mockito.times(1)).update(host2Id, host2);
1076+
}
1077+
1078+
@Test
1079+
public void testUpdatePodStorageAccessGroups() {
1080+
long podId = 2L;
1081+
long clusterId = 3L;
1082+
long host1Id = 1L;
1083+
long host2Id = 2L;
1084+
List<String> newStorageAccessGroups = Arrays.asList("group1", "group2");
1085+
1086+
HostVO host1 = Mockito.mock(HostVO.class);
1087+
HostVO host2 = Mockito.mock(HostVO.class);
1088+
Mockito.when(host1.getId()).thenReturn(host1Id);
1089+
Mockito.when(host2.getId()).thenReturn(host2Id);
1090+
1091+
HostPodVO pod1 = Mockito.mock(HostPodVO.class);
1092+
ClusterVO cluster1 = Mockito.mock(ClusterVO.class);
1093+
Mockito.when(pod1.getStorageAccessGroups()).thenReturn("group1,group3");
1094+
Mockito.when(cluster1.getId()).thenReturn(clusterId);
1095+
Mockito.when(podDao.findById(podId)).thenReturn(pod1);
1096+
Mockito.when(clusterDao.findById(clusterId)).thenReturn(cluster1);
1097+
Mockito.when(clusterDao.listByPodId(podId)).thenReturn(Collections.singletonList(cluster1));
1098+
Mockito.when(hostDao.findHypervisorHostInPod(podId)).thenReturn(Arrays.asList(host1, host2));
1099+
Mockito.when(hostDao.findByPodId(podId, Host.Type.Routing)).thenReturn(Arrays.asList(host1, host2));
1100+
Mockito.when(hostDao.findByClusterId(clusterId)).thenReturn(Arrays.asList(host1, host2));
1101+
1102+
List<Long> hostIdsUsingStorageTags = Arrays.asList(host1Id);
1103+
Mockito.doReturn(hostIdsUsingStorageTags).when(resourceManager).listOfHostIdsUsingTheStorageAccessGroups(any(), any(), any(), any());
1104+
1105+
Mockito.doReturn(new String[]{"group1", "group3"}).when(storageManager).getStorageAccessGroups(null, null, null, host1Id);
1106+
Mockito.doReturn(new String[]{"group2", "group4"}).when(storageManager).getStorageAccessGroups(null, null, null, host2Id);
1107+
1108+
resourceManager.updatePodStorageAccessGroups(podId, newStorageAccessGroups);
1109+
1110+
Mockito.verify(hostDao, Mockito.times(2)).update(host1Id, host1);
1111+
Mockito.verify(hostDao, Mockito.times(1)).update(host2Id, host2);
1112+
}
1113+
1114+
@Test
1115+
public void testUpdateClusterStorageAccessGroups() {
1116+
long clusterId = 3L;
1117+
long host1Id = 1L;
1118+
long host2Id = 2L;
1119+
List<String> newStorageAccessGroups = Arrays.asList("group1", "group2");
1120+
1121+
HostVO host1 = Mockito.mock(HostVO.class);
1122+
HostVO host2 = Mockito.mock(HostVO.class);
1123+
Mockito.when(host1.getId()).thenReturn(host1Id);
1124+
Mockito.when(host2.getId()).thenReturn(host2Id);
1125+
1126+
ClusterVO cluster1 = Mockito.mock(ClusterVO.class);
1127+
Mockito.when(cluster1.getStorageAccessGroups()).thenReturn("group1,group3");
1128+
Mockito.when(cluster1.getId()).thenReturn(clusterId);
1129+
Mockito.when(clusterDao.findById(clusterId)).thenReturn(cluster1);
1130+
Mockito.when(hostDao.findHypervisorHostInCluster(clusterId)).thenReturn(Arrays.asList(host1, host2));
1131+
Mockito.when(hostDao.findByClusterId(clusterId)).thenReturn(Arrays.asList(host1, host2));
1132+
Mockito.when(hostDao.findByClusterId(clusterId, Host.Type.Routing)).thenReturn(Arrays.asList(host1, host2));
1133+
1134+
List<Long> hostIdsUsingStorageTags = Arrays.asList(host1Id);
1135+
Mockito.doReturn(hostIdsUsingStorageTags).when(resourceManager).listOfHostIdsUsingTheStorageAccessGroups(any(), any(), any(), any());
1136+
1137+
Mockito.doReturn(new String[]{"group1", "group3"}).when(storageManager).getStorageAccessGroups(null, null, null, host1Id);
1138+
Mockito.doReturn(new String[]{"group2", "group4"}).when(storageManager).getStorageAccessGroups(null, null, null, host2Id);
1139+
1140+
resourceManager.updateClusterStorageAccessGroups(clusterId, newStorageAccessGroups);
1141+
1142+
Mockito.verify(hostDao, Mockito.times(2)).update(host1Id, host1);
1143+
Mockito.verify(hostDao, Mockito.times(1)).update(host2Id, host2);
1144+
}
1145+
1146+
@Test
1147+
public void testUpdateHostStorageAccessGroups() {
1148+
long hostId = 1L;
1149+
long clusterId = 2L;
1150+
List<String> newStorageAccessGroups = Arrays.asList("group1", "group2");
1151+
1152+
HostVO host = Mockito.mock(HostVO.class);
1153+
Mockito.when(host.getId()).thenReturn(hostId);
1154+
Mockito.when(host.getClusterId()).thenReturn(clusterId);
1155+
Mockito.when(host.getStorageAccessGroups()).thenReturn("group1,group3");
1156+
1157+
Mockito.when(hostDao.findById(hostId)).thenReturn(host);
1158+
Mockito.when(storageManager.getStorageAccessGroups(null, null, clusterId, null))
1159+
.thenReturn(new String[]{"group3", "group4"});
1160+
1161+
Mockito.doNothing().when(resourceManager).checkIfAnyVolumesInUse(any(), any(), any());
1162+
Mockito.doNothing().when(resourceManager).updateConnectionsBetweenHostsAndStoragePools(any());
1163+
1164+
resourceManager.updateHostStorageAccessGroups(hostId, newStorageAccessGroups);
1165+
1166+
Mockito.verify(resourceManager).checkIfAnyVolumesInUse(eq(Arrays.asList("group1", "group2", "group3", "group4")),
1167+
eq(Arrays.asList("group3")),
1168+
eq(host));
1169+
1170+
Mockito.verify(resourceManager).updateConnectionsBetweenHostsAndStoragePools(
1171+
eq(Collections.singletonMap(host, Arrays.asList("group1", "group2", "group3", "group4")))
1172+
);
1173+
1174+
Mockito.verify(host).setStorageAccessGroups("group1,group2");
1175+
Mockito.verify(hostDao).update(hostId, host);
1176+
}
9571177
}

0 commit comments

Comments
 (0)