Skip to content

Commit e8ac477

Browse files
authored
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]>
1 parent 08ad1c7 commit e8ac477

File tree

2 files changed

+112
-5
lines changed

2 files changed

+112
-5
lines changed

engine/orchestration/src/main/java/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,19 @@ public void processHostVmStatePingReport(long hostId, Map<String, HostVmStateRep
7777
processReport(hostId, translatedInfo, force);
7878
}
7979

80-
private void updateAndPublishVmPowerStates(long hostId, Map<Long, VirtualMachine.PowerState> instancePowerStates,
81-
Date updateTime) {
80+
protected void updateAndPublishVmPowerStates(long hostId, Map<Long, VirtualMachine.PowerState> instancePowerStates,
81+
Date updateTime) {
8282
if (instancePowerStates.isEmpty()) {
8383
return;
8484
}
8585
Set<Long> vmIds = instancePowerStates.keySet();
86-
Map<Long, VirtualMachine.PowerState> notUpdated = _instanceDao.updatePowerState(instancePowerStates, hostId,
87-
updateTime);
86+
Map<Long, VirtualMachine.PowerState> notUpdated =
87+
_instanceDao.updatePowerState(instancePowerStates, hostId, updateTime);
8888
if (notUpdated.size() > vmIds.size()) {
8989
return;
9090
}
9191
for (Long vmId : vmIds) {
92-
if (!notUpdated.isEmpty() && !notUpdated.containsKey(vmId)) {
92+
if (!notUpdated.containsKey(vmId)) {
9393
logger.debug("VM state report is updated. {}, {}, power state: {}",
9494
() -> hostCache.get(hostId), () -> vmCache.get(vmId), () -> instancePowerStates.get(vmId));
9595
_messageBus.publish(null, VirtualMachineManager.Topics.VM_POWER_STATE,
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package com.cloud.vm;
18+
19+
import java.util.Date;
20+
import java.util.HashMap;
21+
import java.util.Map;
22+
23+
import org.apache.cloudstack.framework.messagebus.MessageBus;
24+
import org.apache.cloudstack.framework.messagebus.PublishScope;
25+
import org.junit.Before;
26+
import org.junit.Test;
27+
import org.junit.runner.RunWith;
28+
import org.mockito.InjectMocks;
29+
import org.mockito.Mock;
30+
import org.mockito.Mockito;
31+
import org.mockito.junit.MockitoJUnitRunner;
32+
33+
import com.cloud.host.HostVO;
34+
import com.cloud.host.dao.HostDao;
35+
import com.cloud.vm.dao.VMInstanceDao;
36+
37+
@RunWith(MockitoJUnitRunner.class)
38+
public class VirtualMachinePowerStateSyncImplTest {
39+
@Mock
40+
MessageBus messageBus;
41+
@Mock
42+
VMInstanceDao instanceDao;
43+
@Mock
44+
HostDao hostDao;
45+
46+
@InjectMocks
47+
VirtualMachinePowerStateSyncImpl virtualMachinePowerStateSync = new VirtualMachinePowerStateSyncImpl();
48+
49+
@Before
50+
public void setup() {
51+
Mockito.lenient().when(instanceDao.findById(Mockito.anyLong())).thenReturn(Mockito.mock(VMInstanceVO.class));
52+
Mockito.lenient().when(hostDao.findById(Mockito.anyLong())).thenReturn(Mockito.mock(HostVO.class));
53+
}
54+
55+
@Test
56+
public void test_updateAndPublishVmPowerStates_emptyStates() {
57+
virtualMachinePowerStateSync.updateAndPublishVmPowerStates(1L, new HashMap<>(), new Date());
58+
Mockito.verify(instanceDao, Mockito.never()).updatePowerState(Mockito.anyMap(), Mockito.anyLong(),
59+
Mockito.any(Date.class));
60+
}
61+
62+
@Test
63+
public void test_updateAndPublishVmPowerStates_moreNotUpdated() {
64+
Map<Long, VirtualMachine.PowerState> powerStates = new HashMap<>();
65+
powerStates.put(1L, VirtualMachine.PowerState.PowerOff);
66+
Map<Long, VirtualMachine.PowerState> notUpdated = new HashMap<>(powerStates);
67+
notUpdated.put(2L, VirtualMachine.PowerState.PowerOn);
68+
Mockito.when(instanceDao.updatePowerState(Mockito.anyMap(), Mockito.anyLong(),
69+
Mockito.any(Date.class))).thenReturn(notUpdated);
70+
virtualMachinePowerStateSync.updateAndPublishVmPowerStates(1L, powerStates, new Date());
71+
Mockito.verify(messageBus, Mockito.never()).publish(Mockito.nullable(String.class), Mockito.anyString(),
72+
Mockito.any(PublishScope.class), Mockito.anyLong());
73+
}
74+
75+
@Test
76+
public void test_updateAndPublishVmPowerStates_allUpdated() {
77+
Map<Long, VirtualMachine.PowerState> powerStates = new HashMap<>();
78+
powerStates.put(1L, VirtualMachine.PowerState.PowerOff);
79+
Mockito.when(instanceDao.updatePowerState(Mockito.anyMap(), Mockito.anyLong(),
80+
Mockito.any(Date.class))).thenReturn(new HashMap<>());
81+
virtualMachinePowerStateSync.updateAndPublishVmPowerStates(1L, powerStates, new Date());
82+
Mockito.verify(messageBus, Mockito.times(1)).publish(null,
83+
VirtualMachineManager.Topics.VM_POWER_STATE,
84+
PublishScope.GLOBAL,
85+
1L);
86+
}
87+
88+
@Test
89+
public void test_updateAndPublishVmPowerStates_partialUpdated() {
90+
Map<Long, VirtualMachine.PowerState> powerStates = new HashMap<>();
91+
powerStates.put(1L, VirtualMachine.PowerState.PowerOn);
92+
powerStates.put(2L, VirtualMachine.PowerState.PowerOff);
93+
Map<Long, VirtualMachine.PowerState> notUpdated = new HashMap<>();
94+
notUpdated.put(2L, VirtualMachine.PowerState.PowerOff);
95+
Mockito.when(instanceDao.updatePowerState(Mockito.anyMap(), Mockito.anyLong(),
96+
Mockito.any(Date.class))).thenReturn(notUpdated);
97+
virtualMachinePowerStateSync.updateAndPublishVmPowerStates(1L, powerStates, new Date());
98+
Mockito.verify(messageBus, Mockito.times(1)).publish(null,
99+
VirtualMachineManager.Topics.VM_POWER_STATE,
100+
PublishScope.GLOBAL,
101+
1L);
102+
Mockito.verify(messageBus, Mockito.never()).publish(null,
103+
VirtualMachineManager.Topics.VM_POWER_STATE,
104+
PublishScope.GLOBAL,
105+
2L);
106+
}
107+
}

0 commit comments

Comments
 (0)