This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch 4.20
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.20 by this push:
     new e8ac477e9f8 engine/orchestration: fix missing vm powerstate update vm 
state (#10407)
e8ac477e9f8 is described below

commit e8ac477e9f88389cbab754defd0add98dd192fc0
Author: Abhishek Kumar <[email protected]>
AuthorDate: Tue Feb 25 15:50:27 2025 +0530

    engine/orchestration: fix missing vm powerstate update vm state (#10407)
    
    * engine/orchestration: fix missing vm powerstate update vm state
    
    Fixes #10406
    VMs were not moving to Stopped state when PowerReportMissing is processed.
    
    Signed-off-by: Abhishek Kumar <[email protected]>
    
    * add unit tests
    
    Signed-off-by: Abhishek Kumar <[email protected]>
    
    * add license
    
    Signed-off-by: Abhishek Kumar <[email protected]>
    
    * add lenient
    
    Signed-off-by: Abhishek Kumar <[email protected]>
    
    ---------
    
    Signed-off-by: Abhishek Kumar <[email protected]>
---
 .../cloud/vm/VirtualMachinePowerStateSyncImpl.java |  10 +-
 .../vm/VirtualMachinePowerStateSyncImplTest.java   | 107 +++++++++++++++++++++
 2 files changed, 112 insertions(+), 5 deletions(-)

diff --git 
a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java
 
b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java
index 4b344ac4299..7a1a39ec0f0 100644
--- 
a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java
+++ 
b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java
@@ -77,19 +77,19 @@ public class VirtualMachinePowerStateSyncImpl implements 
VirtualMachinePowerStat
         processReport(hostId, translatedInfo, force);
     }
 
-    private void updateAndPublishVmPowerStates(long hostId, Map<Long, 
VirtualMachine.PowerState> instancePowerStates,
-           Date updateTime) {
+    protected void updateAndPublishVmPowerStates(long hostId, Map<Long, 
VirtualMachine.PowerState> instancePowerStates,
+               Date updateTime) {
         if (instancePowerStates.isEmpty()) {
             return;
         }
         Set<Long> vmIds = instancePowerStates.keySet();
-        Map<Long, VirtualMachine.PowerState> notUpdated = 
_instanceDao.updatePowerState(instancePowerStates, hostId,
-                updateTime);
+        Map<Long, VirtualMachine.PowerState> notUpdated =
+                _instanceDao.updatePowerState(instancePowerStates, hostId, 
updateTime);
         if (notUpdated.size() > vmIds.size()) {
             return;
         }
         for (Long vmId : vmIds) {
-            if (!notUpdated.isEmpty() && !notUpdated.containsKey(vmId)) {
+            if (!notUpdated.containsKey(vmId)) {
                 logger.debug("VM state report is updated. {}, {}, power state: 
{}",
                         () -> hostCache.get(hostId), () -> vmCache.get(vmId), 
() -> instancePowerStates.get(vmId));
                 _messageBus.publish(null, 
VirtualMachineManager.Topics.VM_POWER_STATE,
diff --git 
a/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachinePowerStateSyncImplTest.java
 
b/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachinePowerStateSyncImplTest.java
new file mode 100644
index 00000000000..4df14fe22f3
--- /dev/null
+++ 
b/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachinePowerStateSyncImplTest.java
@@ -0,0 +1,107 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.vm;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.PublishScope;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+@RunWith(MockitoJUnitRunner.class)
+public class VirtualMachinePowerStateSyncImplTest {
+    @Mock
+    MessageBus messageBus;
+    @Mock
+    VMInstanceDao instanceDao;
+    @Mock
+    HostDao hostDao;
+
+    @InjectMocks
+    VirtualMachinePowerStateSyncImpl virtualMachinePowerStateSync = new 
VirtualMachinePowerStateSyncImpl();
+
+    @Before
+    public void setup() {
+        
Mockito.lenient().when(instanceDao.findById(Mockito.anyLong())).thenReturn(Mockito.mock(VMInstanceVO.class));
+        
Mockito.lenient().when(hostDao.findById(Mockito.anyLong())).thenReturn(Mockito.mock(HostVO.class));
+    }
+
+    @Test
+    public void test_updateAndPublishVmPowerStates_emptyStates() {
+        virtualMachinePowerStateSync.updateAndPublishVmPowerStates(1L, new 
HashMap<>(), new Date());
+        Mockito.verify(instanceDao, 
Mockito.never()).updatePowerState(Mockito.anyMap(), Mockito.anyLong(),
+                Mockito.any(Date.class));
+    }
+
+    @Test
+    public void test_updateAndPublishVmPowerStates_moreNotUpdated() {
+        Map<Long, VirtualMachine.PowerState> powerStates = new HashMap<>();
+        powerStates.put(1L, VirtualMachine.PowerState.PowerOff);
+        Map<Long, VirtualMachine.PowerState> notUpdated = new 
HashMap<>(powerStates);
+        notUpdated.put(2L, VirtualMachine.PowerState.PowerOn);
+        Mockito.when(instanceDao.updatePowerState(Mockito.anyMap(), 
Mockito.anyLong(),
+                Mockito.any(Date.class))).thenReturn(notUpdated);
+        virtualMachinePowerStateSync.updateAndPublishVmPowerStates(1L, 
powerStates, new Date());
+        Mockito.verify(messageBus, 
Mockito.never()).publish(Mockito.nullable(String.class), Mockito.anyString(),
+                Mockito.any(PublishScope.class), Mockito.anyLong());
+    }
+
+    @Test
+    public void test_updateAndPublishVmPowerStates_allUpdated() {
+        Map<Long, VirtualMachine.PowerState> powerStates = new HashMap<>();
+        powerStates.put(1L, VirtualMachine.PowerState.PowerOff);
+        Mockito.when(instanceDao.updatePowerState(Mockito.anyMap(), 
Mockito.anyLong(),
+                Mockito.any(Date.class))).thenReturn(new HashMap<>());
+        virtualMachinePowerStateSync.updateAndPublishVmPowerStates(1L, 
powerStates, new Date());
+        Mockito.verify(messageBus, Mockito.times(1)).publish(null,
+                VirtualMachineManager.Topics.VM_POWER_STATE,
+                PublishScope.GLOBAL,
+                1L);
+    }
+
+    @Test
+    public void test_updateAndPublishVmPowerStates_partialUpdated() {
+        Map<Long, VirtualMachine.PowerState> powerStates = new HashMap<>();
+        powerStates.put(1L, VirtualMachine.PowerState.PowerOn);
+        powerStates.put(2L, VirtualMachine.PowerState.PowerOff);
+        Map<Long, VirtualMachine.PowerState> notUpdated = new HashMap<>();
+        notUpdated.put(2L, VirtualMachine.PowerState.PowerOff);
+        Mockito.when(instanceDao.updatePowerState(Mockito.anyMap(), 
Mockito.anyLong(),
+                Mockito.any(Date.class))).thenReturn(notUpdated);
+        virtualMachinePowerStateSync.updateAndPublishVmPowerStates(1L, 
powerStates, new Date());
+        Mockito.verify(messageBus, Mockito.times(1)).publish(null,
+                VirtualMachineManager.Topics.VM_POWER_STATE,
+                PublishScope.GLOBAL,
+                1L);
+        Mockito.verify(messageBus, Mockito.never()).publish(null,
+                VirtualMachineManager.Topics.VM_POWER_STATE,
+                PublishScope.GLOBAL,
+                2L);
+    }
+}

Reply via email to