Skip to content

Commit 5177783

Browse files
committed
server: add unit tests for rejectReAddOfDeletedHost
Cover the management-server guard that refuses an agent whose GUID belongs to a previously deleted host: - honours 'add.host.on.service.restart.kvm': when true the guard returns early and issues no database lookup at all - rejects a match on the full GUID and, separately, on the GUID prefix - the rejection message names both the GUID and the setting to flip - a full-GUID hit short-circuits the prefix lookup - a live host (removed = null) returned by the *IncludingRemoved lookups is never rejected, so an ordinary agent reconnect keeps working - blank/null GUID and prefix are not looked up, so a blank prefix cannot turn into a wildcard query matching an unrelated host The tests mutate the static ADD_HOST_ON_SERVICE_RESTART_KVM ConfigKey, so tearDown() restores its declared default to keep the change from leaking into other tests sharing the JVM fork.
1 parent d792015 commit 5177783

1 file changed

Lines changed: 123 additions & 0 deletions

File tree

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

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,11 @@
8181
import java.util.ArrayList;
8282
import java.util.Arrays;
8383
import java.util.Collections;
84+
import java.util.Date;
8485
import java.util.List;
8586
import java.util.UUID;
8687

88+
import static com.cloud.configuration.ConfigurationManagerImpl.ADD_HOST_ON_SERVICE_RESTART_KVM;
8789
import static com.cloud.resource.ResourceState.Event.ErrorsCorrected;
8890
import static com.cloud.resource.ResourceState.Event.InternalEnterMaintenance;
8991
import static com.cloud.resource.ResourceState.Event.UnableToMaintain;
@@ -240,6 +242,9 @@ public void setup() throws Exception {
240242

241243
@After
242244
public void tearDown() throws Exception {
245+
// rejectReAddOfDeletedHost tests mutate this static ConfigKey; restore its declared
246+
// default so the change cannot leak into other tests sharing this JVM fork.
247+
overrideDefaultConfigValue(ADD_HOST_ON_SERVICE_RESTART_KVM, "_defaultValue", "true");
243248
sshHelperMocked.close();
244249
actionEventUtilsMocked.close();
245250
getVncPortCommandMockedConstruction.close();
@@ -1393,4 +1398,122 @@ public void testCheckIfAllHostsInUseWithEmptyHostsInMultipleLevels() {
13931398
Mockito.verify(hostDao).findByClusterId(clusterId, Host.Type.Routing);
13941399
Mockito.verify(hostDao).findByPodId(podId, Host.Type.Routing);
13951400
}
1401+
1402+
private static final String DELETED_HOST_GUID = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee-LibvirtComputingResource";
1403+
private static final String DELETED_HOST_GUID_PREFIX = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee";
1404+
1405+
private HostVO mockDeletedHost() {
1406+
HostVO deletedHost = Mockito.mock(HostVO.class);
1407+
when(deletedHost.getRemoved()).thenReturn(new Date());
1408+
when(deletedHost.getId()).thenReturn(42L);
1409+
when(deletedHost.getUuid()).thenReturn("some-host-uuid");
1410+
when(deletedHost.getName()).thenReturn("kvm-host-1");
1411+
return deletedHost;
1412+
}
1413+
1414+
/**
1415+
* When 'add.host.on.service.restart.kvm' is true the operator has opted in to letting a deleted
1416+
* host come back, so the guard must not even query the database.
1417+
*/
1418+
@Test
1419+
public void testRejectReAddOfDeletedHostDoesNothingWhenSettingEnabled() throws Exception {
1420+
overrideDefaultConfigValue(ADD_HOST_ON_SERVICE_RESTART_KVM, "_defaultValue", "true");
1421+
1422+
resourceManager.rejectReAddOfDeletedHost(DELETED_HOST_GUID, DELETED_HOST_GUID_PREFIX);
1423+
1424+
verify(hostDao, never()).findByGuidIncludingRemoved(anyString());
1425+
verify(hostDao, never()).findByGuidPrefixIncludingRemoved(anyString());
1426+
}
1427+
1428+
@Test
1429+
public void testRejectReAddOfDeletedHostDoesNotThrowWhenGuidIsUnknown() throws Exception {
1430+
overrideDefaultConfigValue(ADD_HOST_ON_SERVICE_RESTART_KVM, "_defaultValue", "false");
1431+
when(hostDao.findByGuidIncludingRemoved(DELETED_HOST_GUID)).thenReturn(null);
1432+
when(hostDao.findByGuidPrefixIncludingRemoved(DELETED_HOST_GUID_PREFIX)).thenReturn(null);
1433+
1434+
resourceManager.rejectReAddOfDeletedHost(DELETED_HOST_GUID, DELETED_HOST_GUID_PREFIX);
1435+
}
1436+
1437+
@Test
1438+
public void testRejectReAddOfDeletedHostThrowsWhenFullGuidMatchesDeletedHost() throws Exception {
1439+
overrideDefaultConfigValue(ADD_HOST_ON_SERVICE_RESTART_KVM, "_defaultValue", "false");
1440+
HostVO deletedHost = mockDeletedHost();
1441+
when(hostDao.findByGuidIncludingRemoved(DELETED_HOST_GUID)).thenReturn(deletedHost);
1442+
1443+
try {
1444+
resourceManager.rejectReAddOfDeletedHost(DELETED_HOST_GUID, DELETED_HOST_GUID_PREFIX);
1445+
Assert.fail("Expected CloudRuntimeException for an agent whose GUID belongs to a deleted host");
1446+
} catch (CloudRuntimeException e) {
1447+
Assert.assertTrue(e.getMessage().contains(DELETED_HOST_GUID));
1448+
Assert.assertTrue(e.getMessage().contains(ADD_HOST_ON_SERVICE_RESTART_KVM.key()));
1449+
}
1450+
1451+
// A full-GUID hit short-circuits; the prefix lookup must not be issued.
1452+
verify(hostDao, never()).findByGuidPrefixIncludingRemoved(anyString());
1453+
}
1454+
1455+
@Test
1456+
public void testRejectReAddOfDeletedHostThrowsWhenGuidPrefixMatchesDeletedHost() throws Exception {
1457+
overrideDefaultConfigValue(ADD_HOST_ON_SERVICE_RESTART_KVM, "_defaultValue", "false");
1458+
when(hostDao.findByGuidIncludingRemoved(DELETED_HOST_GUID)).thenReturn(null);
1459+
HostVO deletedHost = mockDeletedHost();
1460+
when(hostDao.findByGuidPrefixIncludingRemoved(DELETED_HOST_GUID_PREFIX)).thenReturn(deletedHost);
1461+
1462+
try {
1463+
resourceManager.rejectReAddOfDeletedHost(DELETED_HOST_GUID, DELETED_HOST_GUID_PREFIX);
1464+
Assert.fail("Expected CloudRuntimeException when only the GUID prefix matches a deleted host");
1465+
} catch (CloudRuntimeException e) {
1466+
Assert.assertTrue(e.getMessage().contains(ADD_HOST_ON_SERVICE_RESTART_KVM.key()));
1467+
}
1468+
}
1469+
1470+
/**
1471+
* A row returned by the *IncludingRemoved lookups may still be a live host. Only soft-deleted
1472+
* rows (removed != null) may be refused, otherwise a normal agent reconnect would break.
1473+
*/
1474+
@Test
1475+
public void testRejectReAddOfDeletedHostAllowsLiveHostWithSameGuid() throws Exception {
1476+
overrideDefaultConfigValue(ADD_HOST_ON_SERVICE_RESTART_KVM, "_defaultValue", "false");
1477+
HostVO liveHost = Mockito.mock(HostVO.class);
1478+
when(liveHost.getRemoved()).thenReturn(null);
1479+
when(hostDao.findByGuidIncludingRemoved(DELETED_HOST_GUID)).thenReturn(liveHost);
1480+
when(hostDao.findByGuidPrefixIncludingRemoved(DELETED_HOST_GUID_PREFIX)).thenReturn(null);
1481+
1482+
resourceManager.rejectReAddOfDeletedHost(DELETED_HOST_GUID, DELETED_HOST_GUID_PREFIX);
1483+
}
1484+
1485+
@Test
1486+
public void testRejectReAddOfDeletedHostAllowsLiveHostMatchedByPrefix() throws Exception {
1487+
overrideDefaultConfigValue(ADD_HOST_ON_SERVICE_RESTART_KVM, "_defaultValue", "false");
1488+
HostVO liveHost = Mockito.mock(HostVO.class);
1489+
when(liveHost.getRemoved()).thenReturn(null);
1490+
when(hostDao.findByGuidIncludingRemoved(DELETED_HOST_GUID)).thenReturn(null);
1491+
when(hostDao.findByGuidPrefixIncludingRemoved(DELETED_HOST_GUID_PREFIX)).thenReturn(liveHost);
1492+
1493+
resourceManager.rejectReAddOfDeletedHost(DELETED_HOST_GUID, DELETED_HOST_GUID_PREFIX);
1494+
}
1495+
1496+
@Test
1497+
public void testRejectReAddOfDeletedHostSkipsLookupsForBlankGuidAndPrefix() throws Exception {
1498+
overrideDefaultConfigValue(ADD_HOST_ON_SERVICE_RESTART_KVM, "_defaultValue", "false");
1499+
1500+
resourceManager.rejectReAddOfDeletedHost(null, null);
1501+
resourceManager.rejectReAddOfDeletedHost("", " ");
1502+
1503+
verify(hostDao, never()).findByGuidIncludingRemoved(anyString());
1504+
verify(hostDao, never()).findByGuidPrefixIncludingRemoved(anyString());
1505+
}
1506+
1507+
/**
1508+
* A blank prefix must not be turned into a wildcard lookup that could match an unrelated host.
1509+
*/
1510+
@Test
1511+
public void testRejectReAddOfDeletedHostSkipsPrefixLookupWhenPrefixBlank() throws Exception {
1512+
overrideDefaultConfigValue(ADD_HOST_ON_SERVICE_RESTART_KVM, "_defaultValue", "false");
1513+
when(hostDao.findByGuidIncludingRemoved(DELETED_HOST_GUID)).thenReturn(null);
1514+
1515+
resourceManager.rejectReAddOfDeletedHost(DELETED_HOST_GUID, "");
1516+
1517+
verify(hostDao, never()).findByGuidPrefixIncludingRemoved(anyString());
1518+
}
13961519
}

0 commit comments

Comments
 (0)