Skip to content

Commit be8423c

Browse files
Surya SrinivasanSurya Srinivasan
authored andcommitted
Add test to prevent duplicate RUNNING_VM usage records
1 parent 408e8c0 commit be8423c

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

usage/src/main/java/com/cloud/usage/UsageManagerImpl.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,26 @@ private void createVMHelperEvent(UsageEventVO event) {
11261126
Long templateId = event.getTemplateId();
11271127
String hypervisorType = event.getResourceType();
11281128

1129+
1130+
1131+
SearchCriteria<UsageVMInstanceVO> runningSc =
1132+
_usageInstanceDao.createSearchCriteria();
1133+
runningSc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, vmId);
1134+
runningSc.addAnd("usageType", SearchCriteria.Op.EQ, UsageTypes.RUNNING_VM);
1135+
runningSc.addAnd("endDate", SearchCriteria.Op.NULL);
1136+
1137+
List<UsageVMInstanceVO> existingRunning =
1138+
_usageInstanceDao.search(runningSc, null);
1139+
1140+
if (existingRunning != null && !existingRunning.isEmpty()) {
1141+
logger.warn(String.format(
1142+
"Duplicate VM.START event detected for VM [%d] at [%s], skipping helper record creation.",
1143+
vmId, event.getCreateDate()));
1144+
return;
1145+
}
1146+
1147+
1148+
11291149
// add this VM to the usage helper table
11301150
UsageVMInstanceVO usageInstanceNew =
11311151
new UsageVMInstanceVO(UsageTypes.RUNNING_VM, zoneId, event.getAccountId(), vmId, vmName, soId, templateId, hypervisorType, event.getCreateDate(),

usage/src/test/java/com/cloud/usage/UsageManagerImplTest.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@
3636
import com.cloud.user.dao.AccountDao;
3737
import org.mockito.junit.MockitoJUnitRunner;
3838

39+
40+
import java.util.Date;
41+
42+
import com.cloud.usage.dao.UsageVMInstanceDao;
43+
import com.cloud.utils.db.SearchCriteria;
44+
45+
import org.springframework.test.util.ReflectionTestUtils;
46+
47+
3948
@RunWith(MockitoJUnitRunner.class)
4049
public class UsageManagerImplTest {
4150

@@ -243,4 +252,41 @@ public void handleVMSnapshotEventTestEventIsNeitherAddNorRemove() {
243252
Mockito.verify(usageManagerImpl, Mockito.never()).createUsageVpnUser(usageEventVOMock,accountMock);
244253
Mockito.verify(usageManagerImpl, Mockito.never()).deleteUsageVpnUser(usageEventVOMock, accountMock);
245254
}
255+
256+
257+
@Test
258+
public void testDuplicateVmStartDoesNotCreateNewRunningUsage() {
259+
260+
UsageVMInstanceDao usageInstanceDao = Mockito.mock(UsageVMInstanceDao.class);
261+
ReflectionTestUtils.setField(usageManagerImpl, "_usageInstanceDao", usageInstanceDao);
262+
263+
Mockito.doNothing()
264+
.when(usageEventDetailsDao)
265+
.persist(Mockito.any());
266+
267+
long vmId = 100L;
268+
269+
UsageEventVO event = Mockito.mock(UsageEventVO.class);
270+
Mockito.when(event.getType()).thenReturn(EventTypes.EVENT_VM_START);
271+
Mockito.when(event.getResourceId()).thenReturn(vmId);
272+
Mockito.when(event.getZoneId()).thenReturn(1L);
273+
Mockito.when(event.getAccountId()).thenReturn(1L);
274+
Mockito.when(event.getCreateDate()).thenReturn(new Date());
275+
276+
UsageVMInstanceVO existing = Mockito.mock(UsageVMInstanceVO.class);
277+
List<UsageVMInstanceVO> existingList = List.of(existing);
278+
279+
SearchCriteria<UsageVMInstanceVO> sc = Mockito.mock(SearchCriteria.class);
280+
Mockito.when(usageInstanceDao.createSearchCriteria()).thenReturn(sc);
281+
Mockito.when(usageInstanceDao.search(Mockito.any(), Mockito.isNull()))
282+
.thenReturn(existingList);
283+
284+
usageManagerImpl.handleEvent(event);
285+
286+
Mockito.verify(usageInstanceDao, Mockito.never())
287+
.persist(Mockito.any(UsageVMInstanceVO.class));
288+
}
289+
290+
291+
246292
}

0 commit comments

Comments
 (0)