This is an automated email from the ASF dual-hosted git repository.
weizhouapache pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/main by this push:
new 5893ba5a8c0 server: Fix NPE when on findHostsForMigration when no
suitable hosts are found (#13138)
5893ba5a8c0 is described below
commit 5893ba5a8c00aa445be252e2dd0bc557b0cec3fc
Author: Fabricio Duarte <[email protected]>
AuthorDate: Tue May 12 04:07:20 2026 -0300
server: Fix NPE when on findHostsForMigration when no suitable hosts are
found (#13138)
---
.../com/cloud/server/ManagementServerImpl.java | 13 ++++----
.../com/cloud/server/ManagementServerImplTest.java | 39 +++++++++++++++++++---
2 files changed, 41 insertions(+), 11 deletions(-)
diff --git a/server/src/main/java/com/cloud/server/ManagementServerImpl.java
b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
index 70a434e4a96..e5066b6da5c 100644
--- a/server/src/main/java/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
@@ -1707,16 +1707,15 @@ public class ManagementServerImpl extends
MutualExclusiveIdsManagerBase implemen
if (CollectionUtils.isEmpty(suitableHosts)) {
logger.warn("No suitable hosts found.");
- } else {
- logger.debug("Hosts having capacity and are suitable for
migration: {}", suitableHosts);
+ return suitableHosts;
}
+ logger.debug("Hosts having capacity and are suitable for migration:
{}", suitableHosts);
+
// Only list hosts of the same architecture as the source Host in a
multi-arch zone
- if (!suitableHosts.isEmpty()) {
- List<CPU.CPUArch> clusterArchs =
ApiDBUtils.listZoneClustersArchs(vm.getDataCenterId());
- if (CollectionUtils.isNotEmpty(clusterArchs) &&
clusterArchs.size() > 1) {
- suitableHosts = suitableHosts.stream().filter(h -> h.getArch()
== srcHost.getArch()).collect(Collectors.toList());
- }
+ List<CPU.CPUArch> clusterArchs =
ApiDBUtils.listZoneClustersArchs(vm.getDataCenterId());
+ if (CollectionUtils.isNotEmpty(clusterArchs) && clusterArchs.size() >
1) {
+ suitableHosts = suitableHosts.stream().filter(h -> h.getArch() ==
srcHost.getArch()).collect(Collectors.toList());
}
return suitableHosts;
diff --git
a/server/src/test/java/com/cloud/server/ManagementServerImplTest.java
b/server/src/test/java/com/cloud/server/ManagementServerImplTest.java
index b569368f248..924bf1135a6 100644
--- a/server/src/test/java/com/cloud/server/ManagementServerImplTest.java
+++ b/server/src/test/java/com/cloud/server/ManagementServerImplTest.java
@@ -23,6 +23,10 @@ import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeploymentPlanner;
+import com.cloud.deploy.DeploymentPlanningManager;
+import com.cloud.vm.VirtualMachineProfile;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -181,6 +185,24 @@ public class ManagementServerImplTest {
@Mock
HostAllocator hostAllocator;
+ @Mock
+ VirtualMachine virtualMachineMock;
+
+ @Mock
+ VirtualMachineProfile virtualMachineProfileMock;
+
+ @Mock
+ DataCenterDeployment dataCenterDeploymentMock;
+
+ @Mock
+ DeploymentPlanner.ExcludeList excludeListMock;
+
+ @Mock
+ Host hostMock;
+
+ @Mock
+ DeploymentPlanningManager deploymentPlanningManagerMock;
+
private AutoCloseable closeable;
private MockedStatic<ApiDBUtils> apiDBUtilsMock;
@@ -1053,10 +1075,19 @@ public class ManagementServerImplTest {
@Test
public void testGetExternalVmConsole() {
- VirtualMachine virtualMachine = Mockito.mock(VirtualMachine.class);
Host host = Mockito.mock(Host.class);
- Mockito.when(extensionManager.getInstanceConsole(virtualMachine,
host)).thenReturn(Mockito.mock(com.cloud.agent.api.Answer.class));
- Assert.assertNotNull(spy.getExternalVmConsole(virtualMachine, host));
- Mockito.verify(extensionManager).getInstanceConsole(virtualMachine,
host);
+ Mockito.when(extensionManager.getInstanceConsole(virtualMachineMock,
host)).thenReturn(Mockito.mock(com.cloud.agent.api.Answer.class));
+ Assert.assertNotNull(spy.getExternalVmConsole(virtualMachineMock,
host));
+
Mockito.verify(extensionManager).getInstanceConsole(virtualMachineMock, host);
+ }
+
+ @Test
+ public void
getCapableSuitableHostsTestHostArchIsNotFilteredWhenNoSuitableHostsAreFound() {
+ List<Host> compatibleHosts = List.of(hostMock);
+ Mockito.doReturn(null).when(hostAllocator).allocateTo(Mockito.any(),
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyList(),
Mockito.anyInt(), Mockito.anyBoolean());
+
+ spy.getCapableSuitableHosts(virtualMachineMock,
virtualMachineProfileMock, dataCenterDeploymentMock, compatibleHosts,
excludeListMock, hostMock);
+
+ apiDBUtilsMock.verify(() ->
ApiDBUtils.listZoneClustersArchs(Mockito.anyLong()), Mockito.never());
}
}