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());
     }
 }

Reply via email to