From ac581d1546750a6ffc49ebab180e1b80bec4319e Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Thu, 30 Jan 2020 10:36:50 +0100 Subject: [PATCH] New feature: Resource count (CPU/RAM) take only running vms into calculation (#3760) * marvin: check resource count of more types * New feature: add flag resource.count.running.vms.only to count resource consumption of only running vms Stopped VMs do not use CPU/RAM actually. A new global configuration resource.count.running.vms.only is added to determine whether resource (cpu/memory) of only running vms (including Starting/Stopping) will be taken into calculation of resource consumption. * Add integration test for resource count of only running vms --- .../main/java/com/cloud/vm/UserVmService.java | 2 +- .../api/command/user/vm/DeployVMCmd.java | 3 + .../api/command/user/vm/StartVMCmd.java | 8 +- .../com/cloud/vm/VirtualMachineManager.java | 3 + .../cloud/vm/VirtualMachineManagerImpl.java | 39 +- .../main/java/com/cloud/vm/dao/UserVmDao.java | 2 +- .../java/com/cloud/vm/dao/UserVmDaoImpl.java | 7 +- .../network/as/AutoScaleManagerImpl.java | 3 + .../ResourceLimitManagerImpl.java | 52 +- .../main/java/com/cloud/vm/UserVmManager.java | 5 +- .../java/com/cloud/vm/UserVmManagerImpl.java | 123 ++- .../test_resource_count_running_vms.py | 927 ++++++++++++++++++ tools/marvin/marvin/codes.py | 8 + tools/marvin/marvin/lib/common.py | 48 +- 14 files changed, 1168 insertions(+), 62 deletions(-) create mode 100644 test/integration/component/test_resource_count_running_vms.py diff --git a/api/src/main/java/com/cloud/vm/UserVmService.java b/api/src/main/java/com/cloud/vm/UserVmService.java index 99eb827c122..67020448dc7 100644 --- a/api/src/main/java/com/cloud/vm/UserVmService.java +++ b/api/src/main/java/com/cloud/vm/UserVmService.java @@ -396,7 +396,7 @@ public interface UserVmService { * @throws ResourceUnavailableException * if the resources required the deploy the VM is not currently available. */ - UserVm startVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException; + UserVm startVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException; /** * Creates a vm group. diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java index c161897032e..60b9f312a8e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java @@ -588,6 +588,9 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG } catch (ResourceUnavailableException ex) { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); + } catch (ResourceAllocationException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage()); } catch (ConcurrentOperationException ex) { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java index 365d406b22b..2a7f6d0316d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java @@ -154,7 +154,7 @@ public class StartVMCmd extends BaseAsyncCmd implements UserCmd { } @Override - public void execute() throws ResourceUnavailableException, ResourceAllocationException { + public void execute() { try { CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); @@ -177,6 +177,12 @@ public class StartVMCmd extends BaseAsyncCmd implements UserCmd { } catch (ExecutionException ex) { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage()); + } catch (ResourceUnavailableException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); + } catch (ResourceAllocationException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage()); } catch (InsufficientCapacityException ex) { StringBuilder message = new StringBuilder(ex.getMessage()); if (ex instanceof InsufficientServerCapacityException) { diff --git a/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java index 6041146b9de..491adfd71a4 100644 --- a/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java +++ b/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java @@ -58,6 +58,9 @@ public interface VirtualMachineManager extends Manager { ConfigKey VmConfigDriveOnPrimaryPool = new ConfigKey<>("Advanced", Boolean.class, "vm.configdrive.primarypool.enabled", "false", "If config drive need to be created and hosted on primary storage pool. Currently only supported for KVM.", true); + ConfigKey ResoureCountRunningVMsonly = new ConfigKey("Advanced", Boolean.class, "resource.count.running.vms.only", "false", + "Count the resources of only running VMs in resource limitation.", true); + interface Topics { String VM_POWER_STATE = "vm.powerstate"; } diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index 58eed4ee679..fedd3a38b5d 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -122,6 +122,7 @@ import com.cloud.agent.manager.Commands; import com.cloud.agent.manager.allocator.HostAllocator; import com.cloud.alert.AlertManager; import com.cloud.capacity.CapacityManager; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.dc.ClusterDetailsDao; import com.cloud.dc.ClusterDetailsVO; import com.cloud.dc.DataCenter; @@ -191,6 +192,7 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; +import com.cloud.user.ResourceLimitService; import com.cloud.user.User; import com.cloud.utils.DateUtil; import com.cloud.utils.Journal; @@ -302,6 +304,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Inject private ResourceManager _resourceMgr; @Inject + private ResourceLimitService _resourceLimitMgr; + @Inject private VMSnapshotManager _vmSnapshotMgr; @Inject private ClusterDetailsDao _clusterDetailsDao; @@ -970,6 +974,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); + // check resource count if ResoureCountRunningVMsonly.value() = true + final Account owner = _entityMgr.findById(Account.class, vm.getAccountId()); + if (VirtualMachine.Type.User.equals(vm.type) && ResoureCountRunningVMsonly.value()) { + resourceCountIncrement(owner.getAccountId(),new Long(offering.getCpu()), new Long(offering.getRamSize())); + } + boolean canRetry = true; ExcludeList avoids = null; try { @@ -1045,7 +1055,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } } - final Account owner = _entityMgr.findById(Account.class, vm.getAccountId()); final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, owner, params); DeployDestination dest = null; try { @@ -1272,6 +1281,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } } finally { if (startedVm == null) { + if (VirtualMachine.Type.User.equals(vm.type) && ResoureCountRunningVMsonly.value()) { + resourceCountDecrement(owner.getAccountId(),new Long(offering.getCpu()), new Long(offering.getRamSize())); + } if (canRetry) { try { changeState(vm, Event.OperationFailed, null, work, Step.Done); @@ -1817,7 +1829,14 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _workDao.update(work.getId(), work); } - if (!stateTransitTo(vm, Event.OperationSucceeded, null)) { + boolean result = stateTransitTo(vm, Event.OperationSucceeded, null); + if (result) { + if (VirtualMachine.Type.User.equals(vm.type) && ResoureCountRunningVMsonly.value()) { + //update resource count if stop successfully + ServiceOfferingVO offering = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()); + resourceCountDecrement(vm.getAccountId(),new Long(offering.getCpu()), new Long(offering.getRamSize())); + } + } else { throw new CloudRuntimeException("unable to stop " + vm); } } catch (final NoTransitionException e) { @@ -4218,7 +4237,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac public ConfigKey[] getConfigKeys() { return new ConfigKey[] {ClusterDeltaSyncInterval, StartRetry, VmDestroyForcestop, VmOpCancelInterval, VmOpCleanupInterval, VmOpCleanupWait, VmOpLockStateRetry, - VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval, VmConfigDriveLabel, VmConfigDriveOnPrimaryPool, HaVmRestartHostUp}; + VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval, VmConfigDriveLabel, VmConfigDriveOnPrimaryPool, HaVmRestartHostUp, + ResoureCountRunningVMsonly }; } public List getStoragePoolAllocators() { @@ -5338,4 +5358,17 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac return workJob; } + + protected void resourceCountIncrement (long accountId, Long cpu, Long memory) { + _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm); + _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.cpu, cpu); + _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.memory, memory); + } + + protected void resourceCountDecrement (long accountId, Long cpu, Long memory) { + _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.user_vm); + _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.cpu, cpu); + _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.memory, memory); + } + } diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDao.java index dfcc7f7fc33..0b1f9368e10 100644 --- a/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDao.java +++ b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDao.java @@ -77,7 +77,7 @@ public interface UserVmDao extends GenericDao { List listPodIdsHavingVmsforAccount(long zoneId, long accountId); - public Long countAllocatedVMsForAccount(long accountId); + public Long countAllocatedVMsForAccount(long accountId, boolean runningVMsonly); Hashtable listVmDetails(Hashtable userVmData); diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java index 5e22eb50208..28940d7238e 100644 --- a/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java @@ -635,11 +635,14 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use } @Override - public Long countAllocatedVMsForAccount(long accountId) { + public Long countAllocatedVMsForAccount(long accountId, boolean runningVMsonly) { SearchCriteria sc = CountByAccount.create(); sc.setParameters("account", accountId); sc.setParameters("type", VirtualMachine.Type.User); - sc.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging}); + if (runningVMsonly) + sc.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging, State.Stopped}); + else + sc.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging}); sc.setParameters("displayVm", 1); return customSearch(sc, null).get(0); } diff --git a/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java index 1b936e10d82..c7105495161 100644 --- a/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java @@ -1376,6 +1376,9 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale } catch (final ResourceUnavailableException ex) { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); + } catch (ResourceAllocationException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage()); } catch (ConcurrentOperationException ex) { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage()); diff --git a/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 417ccfc6f64..fbc8a99f1b3 100644 --- a/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -44,6 +44,8 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.alert.AlertManager; +import com.cloud.api.query.dao.UserVmJoinDao; +import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.configuration.Config; import com.cloud.configuration.Resource; import com.cloud.configuration.Resource.ResourceOwnerType; @@ -100,6 +102,8 @@ import com.cloud.utils.db.TransactionCallbackNoReturn; import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.VirtualMachineManager; +import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; @@ -151,6 +155,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim private VlanDao _vlanDao; @Inject private SnapshotDataStoreDao _snapshotDataStoreDao; + @Inject + private UserVmJoinDao _userVmJoinDao; protected GenericSearchBuilder templateSizeSearch; protected GenericSearchBuilder snapshotSizeSearch; @@ -872,7 +878,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim protected long recalculateAccountResourceCount(final long accountId, final ResourceType type) { final Long newCount; if (type == Resource.ResourceType.user_vm) { - newCount = _userVmDao.countAllocatedVMsForAccount(accountId); + newCount = _userVmDao.countAllocatedVMsForAccount(accountId, VirtualMachineManager.ResoureCountRunningVMsonly.value()); } else if (type == Resource.ResourceType.volume) { long virtualRouterCount = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId).size(); newCount = _volumeDao.countAllocatedVolumesForAccount(accountId) - virtualRouterCount; // don't count the volumes of virtual router @@ -929,11 +935,51 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim } public long countCpusForAccount(long accountId) { - return _resourceCountDao.countCpuNumberAllocatedToAccount(accountId); + long cputotal = 0; + // user vms + SearchBuilder userVmSearch = _userVmJoinDao.createSearchBuilder(); + userVmSearch.and("accountId", userVmSearch.entity().getAccountId(), Op.EQ); + userVmSearch.and("state", userVmSearch.entity().getState(), SearchCriteria.Op.NIN); + userVmSearch.and("displayVm", userVmSearch.entity().isDisplayVm(), Op.EQ); + userVmSearch.groupBy(userVmSearch.entity().getId()); // select distinct + userVmSearch.done(); + + SearchCriteria sc1 = userVmSearch.create(); + sc1.setParameters("accountId", accountId); + if (VirtualMachineManager.ResoureCountRunningVMsonly.value()) + sc1.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging, State.Stopped}); + else + sc1.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging}); + sc1.setParameters("displayVm", 1); + List userVms = _userVmJoinDao.search(sc1,null); + for (UserVmJoinVO vm : userVms) { + cputotal += Long.valueOf(vm.getCpu()); + } + return cputotal; } public long calculateMemoryForAccount(long accountId) { - return _resourceCountDao.countMemoryAllocatedToAccount(accountId); + long ramtotal = 0; + // user vms + SearchBuilder userVmSearch = _userVmJoinDao.createSearchBuilder(); + userVmSearch.and("accountId", userVmSearch.entity().getAccountId(), Op.EQ); + userVmSearch.and("state", userVmSearch.entity().getState(), SearchCriteria.Op.NIN); + userVmSearch.and("displayVm", userVmSearch.entity().isDisplayVm(), Op.EQ); + userVmSearch.groupBy(userVmSearch.entity().getId()); // select distinct + userVmSearch.done(); + + SearchCriteria sc1 = userVmSearch.create(); + sc1.setParameters("accountId", accountId); + if (VirtualMachineManager.ResoureCountRunningVMsonly.value()) + sc1.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging, State.Stopped}); + else + sc1.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging}); + sc1.setParameters("displayVm", 1); + List userVms = _userVmJoinDao.search(sc1,null); + for (UserVmJoinVO vm : userVms) { + ramtotal += Long.valueOf(vm.getRamSize()); + } + return ramtotal; } public long calculateSecondaryStorageForAccount(long accountId) { diff --git a/server/src/main/java/com/cloud/vm/UserVmManager.java b/server/src/main/java/com/cloud/vm/UserVmManager.java index 717ff5a0fd2..f37fcd8dd35 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManager.java +++ b/server/src/main/java/com/cloud/vm/UserVmManager.java @@ -30,6 +30,7 @@ import com.cloud.agent.api.VolumeStatsEntry; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ManagementServerException; +import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.VirtualMachineMigrationException; import com.cloud.offering.ServiceOffering; @@ -99,10 +100,10 @@ public interface UserVmManager extends UserVmService { boolean expunge(UserVmVO vm, long callerUserId, Account caller); Pair> startVirtualMachine(long vmId, Long hostId, Map additionalParams, String deploymentPlannerToUse) - throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException; Pair> startVirtualMachine(long vmId, Long podId, Long clusterId, Long hostId, Map additionalParams, String deploymentPlannerToUse) - throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException; boolean upgradeVirtualMachine(Long id, Long serviceOfferingId, Map customParameters) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 52339662cb6..a155d8e977c 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -572,16 +572,20 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir _resourceLimitMgr.checkResourceLimit(owner, ResourceType.memory, displayVm, memory); } - private void resourceCountIncrement(long accountId, Boolean displayVm, Long cpu, Long memory) { - _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm, displayVm); - _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu); - _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.memory, displayVm, memory); + protected void resourceCountIncrement(long accountId, Boolean displayVm, Long cpu, Long memory) { + if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) { + _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm, displayVm); + _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu); + _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.memory, displayVm, memory); + } } - private void resourceCountDecrement(long accountId, Boolean displayVm, Long cpu, Long memory) { - _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.user_vm, displayVm); - _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu); - _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.memory, displayVm, memory); + protected void resourceCountDecrement(long accountId, Boolean displayVm, Long cpu, Long memory) { + if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) { + _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.user_vm, displayVm); + _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu); + _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.memory, displayVm, memory); + } } public class VmAndCountDetails { @@ -1016,11 +1020,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir int currentMemory = currentServiceOffering.getRamSize(); Account owner = _accountMgr.getActiveAccountById(vmInstance.getAccountId()); - if (newCpu > currentCpu) { - _resourceLimitMgr.checkResourceLimit(owner, ResourceType.cpu, newCpu - currentCpu); - } - if (newMemory > currentMemory) { - _resourceLimitMgr.checkResourceLimit(owner, ResourceType.memory, newMemory - currentMemory); + if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) { + if (newCpu > currentCpu) { + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.cpu, newCpu - currentCpu); + } + if (newMemory > currentMemory) { + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.memory, newMemory - currentMemory); + } } // Check that the specified service offering ID is valid @@ -1036,15 +1042,17 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } // Increment or decrement CPU and Memory count accordingly. - if (newCpu > currentCpu) { - _resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu)); - } else if (currentCpu > newCpu) { - _resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.cpu, new Long(currentCpu - newCpu)); - } - if (newMemory > currentMemory) { - _resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.memory, new Long(newMemory - currentMemory)); - } else if (currentMemory > newMemory) { - _resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.memory, new Long(currentMemory - newMemory)); + if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) { + if (newCpu > currentCpu) { + _resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu)); + } else if (currentCpu > newCpu) { + _resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.cpu, new Long(currentCpu - newCpu)); + } + if (newMemory > currentMemory) { + _resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.memory, new Long(newMemory - currentMemory)); + } else if (currentMemory > newMemory) { + _resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.memory, new Long(currentMemory - newMemory)); + } } // Generate usage event for VM upgrade @@ -1123,11 +1131,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir int currentMemory = currentServiceOffering.getRamSize(); Account owner = _accountMgr.getActiveAccountById(vmInstance.getAccountId()); - if (newCpu > currentCpu) { - _resourceLimitMgr.checkResourceLimit(owner, ResourceType.cpu, newCpu - currentCpu); - } - if (newMemory > currentMemory) { - _resourceLimitMgr.checkResourceLimit(owner, ResourceType.memory, newMemory - currentMemory); + if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) { + if (newCpu > currentCpu) { + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.cpu, newCpu - currentCpu); + } + if (newMemory > currentMemory) { + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.memory, newMemory - currentMemory); + } } // Check that the specified service offering ID is valid @@ -1161,15 +1171,17 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } // Increment or decrement CPU and Memory count accordingly. - if (newCpu > currentCpu) { - _resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu)); - } else if (currentCpu > newCpu) { - _resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.cpu, new Long(currentCpu - newCpu)); - } - if (newMemory > currentMemory) { - _resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.memory, new Long(newMemory - currentMemory)); - } else if (currentMemory > newMemory) { - _resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.memory, new Long(currentMemory - newMemory)); + if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) { + if (newCpu > currentCpu) { + _resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu)); + } else if (currentCpu > newCpu) { + _resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.cpu, new Long(currentCpu - newCpu)); + } + if (newMemory > currentMemory) { + _resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.memory, new Long(newMemory - currentMemory)); + } else if (currentMemory > newMemory) { + _resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.memory, new Long(currentMemory - newMemory)); + } } return _vmDao.findById(vmInstance.getId()); @@ -2057,7 +2069,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir // First check that the maximum number of UserVMs, CPU and Memory limit for the given // accountId will not be exceeded - resourceLimitCheck(account, vm.isDisplayVm(), new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize())); + if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) { + resourceLimitCheck(account, vm.isDisplayVm(), new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize())); + } _haMgr.cancelDestroy(vm, vm.getHostId()); @@ -2549,9 +2563,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir // Resource limit changes ServiceOffering offering = _serviceOfferingDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId()); - _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.user_vm, isDisplayVm); - _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.cpu, isDisplayVm, new Long(offering.getCpu())); - _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.memory, isDisplayVm, new Long(offering.getRamSize())); + if (isDisplayVm) { + resourceCountIncrement(vmInstance.getAccountId(), true, new Long(offering.getCpu()), new Long(offering.getRamSize())); + } else { + resourceCountDecrement(vmInstance.getAccountId(), true, new Long(offering.getCpu()), new Long(offering.getRamSize())); + } // Usage saveUsageEvent(vmInstance); @@ -2823,7 +2839,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir @Override @ActionEvent(eventType = EventTypes.EVENT_VM_START, eventDescription = "starting Vm", async = true) - public UserVm startVirtualMachine(StartVMCmd cmd) throws ExecutionException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + public UserVm startVirtualMachine(StartVMCmd cmd) throws ExecutionException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException { return startVirtualMachine(cmd.getId(), cmd.getPodId(), cmd.getClusterId(), cmd.getHostId(), null, cmd.getDeploymentPlanner()).first(); } @@ -3522,7 +3538,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } size += _diskOfferingDao.findById(diskOfferingId).getDiskSize(); } - resourceLimitCheck(owner, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize())); + if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) { + resourceLimitCheck(owner, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize())); + } _resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, (isIso || diskOfferingId == null ? 1 : 2)); _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, size); @@ -4237,7 +4255,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir @Override @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "starting Vm", async = true) - public UserVm startVirtualMachine(DeployVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException { + public UserVm startVirtualMachine(DeployVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException { long vmId = cmd.getEntityId(); Long podId = null; Long clusterId = null; @@ -4253,7 +4271,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir private UserVm startVirtualMachine(long vmId, Long podId, Long clusterId, Long hostId, Map diskOfferingMap, Map additonalParams, String deploymentPlannerToUse) throws ResourceUnavailableException, - InsufficientCapacityException, ConcurrentOperationException { + InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException { UserVmVO vm = _vmDao.findById(vmId); Pair> vmParamPair = null; @@ -4581,13 +4599,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir @Override public Pair> startVirtualMachine(long vmId, Long hostId, Map additionalParams, String deploymentPlannerToUse) - throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException { return startVirtualMachine(vmId, null, null, hostId, additionalParams, deploymentPlannerToUse); } @Override public Pair> startVirtualMachine(long vmId, Long podId, Long clusterId, Long hostId, Map additionalParams, String deploymentPlannerToUse) - throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException { // Input validation final Account callerAccount = CallContext.current().getCallingAccount(); UserVO callerUser = _userDao.findById(CallContext.current().getCallingUserId()); @@ -4613,6 +4631,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if (owner.getState() == Account.State.disabled) { throw new PermissionDeniedException("The owner of " + vm + " is disabled: " + vm.getAccountId()); } + if (VirtualMachineManager.ResoureCountRunningVMsonly.value()) { + // check if account/domain is with in resource limits to start a new vm + ServiceOfferingVO offering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId()); + resourceLimitCheck(owner, vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize())); + } // check if vm is security group enabled if (_securityGroupMgr.isVmSecurityGroupEnabled(vmId) && _securityGroupMgr.getSecurityGroupsForVm(vmId).isEmpty() @@ -6123,7 +6146,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir removeInstanceFromInstanceGroup(cmd.getVmId()); // VV 2: check if account/domain is with in resource limits to create a new vm - resourceLimitCheck(newAccount, vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize())); + if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) { + resourceLimitCheck(newAccount, vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize())); + } // VV 3: check if volumes and primary storage space are with in resource limits _resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.volume, _volsDao.findByInstance(cmd.getVmId()).size()); @@ -6176,7 +6201,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } //update resource count of new account - resourceCountIncrement(newAccount.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize())); + if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) { + resourceCountIncrement(newAccount.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize())); + } //generate usage events to account for this change UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), diff --git a/test/integration/component/test_resource_count_running_vms.py b/test/integration/component/test_resource_count_running_vms.py new file mode 100644 index 00000000000..2c6e972c102 --- /dev/null +++ b/test/integration/component/test_resource_count_running_vms.py @@ -0,0 +1,927 @@ +# 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. +""" tests for Resource count of only running vms in cloudstack 4.14.0.0 + +""" +# Import Local Modules +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.utils import (validateList, + cleanup_resources) +from marvin.lib.base import (Account, + Domain, + Configurations, + Network, + NetworkOffering, + VirtualMachine, + Resources, + ServiceOffering, + Zone) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + matchResourceCount, + isAccountResourceCountEqualToExpectedCount) +from marvin.codes import (PASS, FAILED, RESOURCE_CPU, RESOURCE_MEMORY) +import logging +import random +import time + +class TestResourceCountRunningVMs(cloudstackTestCase): + @classmethod + def setUpClass(cls): + cls.testClient = super( + TestResourceCountRunningVMs, + cls).getClsTestClient() + cls.apiclient = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() + zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests()) + cls.zone = Zone(zone.__dict__) + cls._cleanup = [] + + cls.logger = logging.getLogger("TestResourceCountRunningVMs") + cls.stream_handler = logging.StreamHandler() + cls.logger.setLevel(logging.DEBUG) + cls.logger.addHandler(cls.stream_handler) + + # Get Domain and templates + cls.domain = get_domain(cls.apiclient) + + cls.template = get_template(cls.apiclient, cls.zone.id, hypervisor="KVM") + if cls.template == FAILED: + sys.exit(1) + cls.templatesize = (cls.template.size / (1024 ** 3)) + + cls.services['mode'] = cls.zone.networktype + # Create Account + cls.account = Account.create( + cls.apiclient, + cls.services["account"], + admin=True, + domainid=cls.domain.id + ) + accounts = Account.list(cls.apiclient, id=cls.account.id) + cls.expectedCpu = int(accounts[0].cputotal) + cls.expectedMemory = int(accounts[0].memorytotal) + + if cls.zone.securitygroupsenabled: + cls.services["shared_network_offering"]["specifyVlan"] = 'True' + cls.services["shared_network_offering"]["specifyIpRanges"] = 'True' + + cls.network_offering = NetworkOffering.create( + cls.apiclient, + cls.services["shared_network_offering"] + ) + cls.network_offering.update(cls.apiclient, state='Enabled') + + cls.account_network = Network.create( + cls.apiclient, + cls.services["network2"], + networkofferingid=cls.network_offering.id, + zoneid=cls.zone.id, + accountid=cls.account.name, + domainid=cls.account.domainid + ) + else: + cls.network_offering = NetworkOffering.create( + cls.apiclient, + cls.services["isolated_network_offering"], + ) + # Enable Network offering + cls.network_offering.update(cls.apiclient, state='Enabled') + + # Create account network + cls.services["network"]["zoneid"] = cls.zone.id + cls.services["network"]["networkoffering"] = cls.network_offering.id + cls.account_network = Network.create( + cls.apiclient, + cls.services["network"], + cls.account.name, + cls.account.domainid + ) + + cls._cleanup.append(cls.account); + cls._cleanup.append(cls.network_offering) + + @classmethod + def tearDownClass(self): + try: + cleanup_resources(self.apiclient, self._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.cleanup = [] + return + + def tearDown(self): + try: + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def verify_resource_count_cpu_memory(self, expectedCpu, expectedMemory, account=None): + if account is None: + account = self.account + response = matchResourceCount( + self.apiclient, expectedCpu, + RESOURCE_CPU, + accountid=account.id) + self.assertEqual(response[0], PASS, response[1]) + + response = matchResourceCount( + self.apiclient, expectedMemory, + RESOURCE_MEMORY, + accountid=account.id) + self.assertEqual(response[0], PASS, response[1]) + + result = isAccountResourceCountEqualToExpectedCount( + self.apiclient, account.domainid, account.name, + expectedCpu, RESOURCE_CPU) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count of cpu does not match") + + result = isAccountResourceCountEqualToExpectedCount( + self.apiclient, account.domainid, account.name, + expectedMemory, RESOURCE_MEMORY) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count of memory does not match") + + def update_account_resource_limitation(self, maxCpu, maxMemory): + Resources.updateLimit(self.apiclient, + resourcetype=RESOURCE_CPU, + max=maxCpu, + domainid=self.account.domainid, + account=self.account.name) + + Resources.updateLimit(self.apiclient, + resourcetype=RESOURCE_MEMORY, + max=maxMemory, + domainid=self.account.domainid, + account=self.account.name) + + @attr(tags=["advanced", "advancedsg"], required_hardware="false") + def test_01_resource_count_vm_with_normal_offering_in_all_states(self): + """Create VM with normal offering. Take resources of vm in all states into calculation of resource count. + + Steps: + # 1. update resource.count.running.vms.only to false + # 2. create normal service offering + # 3. deploy vm, resource count of cpu/ram increases + # 4. stop vm, resource count of cpu/ram is not changed + # 5. update vm with displayvm=false, resource count decreases + # 6. update vm with displayvm=true, resource count increases + # 7. start vm, resource count of cpu/ram is not changed + # 8. reboot vm, resource count of cpu/ram is not changed + # 9. destroy vm, resource count of cpu/ram decreases + # 10. expunge vm, resource count of cpu/ram is not changed + """ + + Configurations.update(self.apiclient, + name="resource.count.running.vms.only", + value="false" ) + + # Create small service offering + self.service_offering = ServiceOffering.create( + self.apiclient, + self.services["service_offerings"]["small"] + ) + self.cleanup.append(self.service_offering) + + # deploy vm + try: + virtual_machine_1 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + zoneid=self.zone.id, + mode=self.zone.networktype + ) + except Exception as e: + self.fail("Exception while deploying virtual machine: %s" % e) + + self.expectedCpu = self.expectedCpu + virtual_machine_1.cpunumber + self.expectedMemory = self.expectedMemory + virtual_machine_1.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # stop vm + virtual_machine_1.stop(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # update vm with displayvm=false + virtual_machine_1.update(self.apiclient, displayvm=False) + self.expectedCpu = self.expectedCpu - virtual_machine_1.cpunumber + self.expectedMemory = self.expectedMemory - virtual_machine_1.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # update vm with displayvm=false + virtual_machine_1.update(self.apiclient, displayvm=True) + self.expectedCpu = self.expectedCpu + virtual_machine_1.cpunumber + self.expectedMemory = self.expectedMemory + virtual_machine_1.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # start vm + virtual_machine_1.start(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # reboot vm + virtual_machine_1.reboot(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # destroy vm + virtual_machine_1.delete(self.apiclient, expunge=False) + self.expectedCpu = self.expectedCpu - virtual_machine_1.cpunumber + self.expectedMemory = self.expectedMemory - virtual_machine_1.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # expunge vm + virtual_machine_1.expunge(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + @attr(tags=["advanced", "advancedsg"], required_hardware="false") + def test_02_resource_count_vm_with_dynamic_offering_in_all_states(self): + """Create VM with dynamic service offering. Take resources of vm in all states into calculation of resource count. + + Steps: + # 1. update resource.count.running.vms.only to false + # 2. create dynamic service offering + # 3. deploy vm, resource count of cpu/ram increases + # 4. stop vm, resource count of cpu/ram is not changed + # 5. update vm with displayvm=false, resource count decreases + # 6. update vm with displayvm=true, resource count increases + # 7. start vm, resource count of cpu/ram is not changed + # 8. reboot vm, resource count of cpu/ram is not changed + # 9. destroy vm, resource count of cpu/ram decreases + # 10. expunge vm, resource count of cpu/ram is not changed + """ + Configurations.update(self.apiclient, + name="resource.count.running.vms.only", + value="false" ) + + # Create dynamic service offering + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + self.service_offering = ServiceOffering.create( + self.apiclient, + self.services["service_offering"]) + self.cleanup.append(self.service_offering) + + # deploy vm + try: + virtual_machine_2 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + customcpunumber=1, + customcpuspeed=100, + custommemory=256, + templateid=self.template.id, + zoneid=self.zone.id, + mode=self.zone.networktype + ) + except Exception as e: + self.fail("Exception while deploying virtual machine: %s" % e) + + self.expectedCpu = self.expectedCpu + virtual_machine_2.cpunumber + self.expectedMemory = self.expectedMemory + virtual_machine_2.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # stop vm + virtual_machine_2.stop(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # update vm with displayvm=false + virtual_machine_2.update(self.apiclient, displayvm=False) + self.expectedCpu = self.expectedCpu - virtual_machine_2.cpunumber + self.expectedMemory = self.expectedMemory - virtual_machine_2.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # update vm with displayvm=false + virtual_machine_2.update(self.apiclient, displayvm=True) + self.expectedCpu = self.expectedCpu + virtual_machine_2.cpunumber + self.expectedMemory = self.expectedMemory + virtual_machine_2.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # start vm + virtual_machine_2.start(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # reboot vm + virtual_machine_2.reboot(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # destroy vm + virtual_machine_2.delete(self.apiclient, expunge=False) + self.expectedCpu = self.expectedCpu - virtual_machine_2.cpunumber + self.expectedMemory = self.expectedMemory - virtual_machine_2.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # expunge vm + virtual_machine_2.expunge(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + @attr(tags=["advanced", "advancedsg"], required_hardware="false") + def test_03_resource_count_vm_with_normal_offering_in_running_state(self): + """Create VM with normal service offering. Take resources of vm in running state into calculation of resource count. + + Steps: + # 1. update resource.count.running.vms.only to true + # 2. create normal service offering + # 3. deploy vm, resource count of cpu/ram increases + # 4. stop vm, resource count of cpu/ram decreases + # 5. start vm, resource count of cpu/ram increases + # 6. reboot vm, resource count of cpu/ram is not changed + # 7. destroy vm, resource count of cpu/ram decreases + # 8. recover vm, resource count of cpu/ram is not changed + # 9. update vm with displayvm=false, resource count of cpu/ram is not changed + # 10. destroy vm with expunge = true, resource count of cpu/ram is not changed + """ + Configurations.update(self.apiclient, + name="resource.count.running.vms.only", + value="true" ) + + # Create service offering + self.service_offering = ServiceOffering.create( + self.apiclient, + self.services["service_offerings"]["small"] + ) + self.cleanup.append(self.service_offering) + + # deploy vm + try: + virtual_machine_3 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + zoneid=self.zone.id, + mode=self.zone.networktype + ) + except Exception as e: + self.fail("Exception while deploying virtual machine: %s" % e) + + self.expectedCpu = self.expectedCpu + virtual_machine_3.cpunumber + self.expectedMemory = self.expectedMemory + virtual_machine_3.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # stop vm + virtual_machine_3.stop(self.apiclient) + self.expectedCpu = self.expectedCpu - virtual_machine_3.cpunumber + self.expectedMemory = self.expectedMemory - virtual_machine_3.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # start vm + virtual_machine_3.start(self.apiclient) + self.expectedCpu = self.expectedCpu + virtual_machine_3.cpunumber + self.expectedMemory = self.expectedMemory + virtual_machine_3.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # reboot vm + virtual_machine_3.reboot(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # destroy vm + virtual_machine_3.delete(self.apiclient, expunge=False) + self.expectedCpu = self.expectedCpu - virtual_machine_3.cpunumber + self.expectedMemory = self.expectedMemory - virtual_machine_3.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # recover vm + virtual_machine_3.recover(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # update vm with displayvm=false + virtual_machine_3.update(self.apiclient, displayvm=False) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # expunge vm + virtual_machine_3.delete(self.apiclient, expunge=True) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + @attr(tags=["advanced", "advancedsg"], required_hardware="false") + def test_04_resource_count_vm_with_dynamic_offering_in_running_state(self): + """Create VM with dynamic service offering. Take resources of vm in running state into calculation of resource count. + + Steps: + # 1. update resource.count.running.vms.only to true + # 2. create dynamic service offering + # 3. deploy vm, resource count of cpu/ram increases + # 4. stop vm, resource count of cpu/ram decreases + # 5. start vm, resource count of cpu/ram increases + # 6. reboot vm, resource count of cpu/ram is not changed + # 7. destroy vm, resource count of cpu/ram decreases + # 8. recover vm, resource count of cpu/ram is not changed + # 9. update vm with displayvm=false, resource count of cpu/ram is not changed + # 10. destroy vm with expunge = true, resource count of cpu/ram is not changed + """ + Configurations.update(self.apiclient, + name="resource.count.running.vms.only", + value="true" ) + + # Create dynamic service offering + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + self.service_offering = ServiceOffering.create( + self.apiclient, + self.services["service_offering"]) + self.cleanup.append(self.service_offering) + + # deploy vm + try: + virtual_machine_4 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + customcpunumber=1, + customcpuspeed=100, + custommemory=256, + templateid=self.template.id, + zoneid=self.zone.id, + mode=self.zone.networktype + ) + except Exception as e: + self.fail("Exception while deploying virtual machine: %s" % e) + + self.expectedCpu = self.expectedCpu + virtual_machine_4.cpunumber + self.expectedMemory = self.expectedMemory + virtual_machine_4.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # stop vm + virtual_machine_4.stop(self.apiclient) + self.expectedCpu = self.expectedCpu - virtual_machine_4.cpunumber + self.expectedMemory = self.expectedMemory - virtual_machine_4.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # start vm + virtual_machine_4.start(self.apiclient) + self.expectedCpu = self.expectedCpu + virtual_machine_4.cpunumber + self.expectedMemory = self.expectedMemory + virtual_machine_4.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # reboot vm + virtual_machine_4.reboot(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # destroy vm + virtual_machine_4.delete(self.apiclient, expunge=False) + self.expectedCpu = self.expectedCpu - virtual_machine_4.cpunumber + self.expectedMemory = self.expectedMemory - virtual_machine_4.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # recover vm + virtual_machine_4.recover(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # update vm with displayvm=false + virtual_machine_4.update(self.apiclient, displayvm=False) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # expunge vm + virtual_machine_4.delete(self.apiclient, expunge=True) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + @attr(tags=["advanced", "advancedsg"], required_hardware="false") + def test_05_resource_count_vm_with_dynamic_offering_in_running_state_failed_cases(self): + """Create VM with dynamic service offering. Take resources of vm in running state into calculation of resource count. Test failed cases + + Steps: + # 1. update resource.count.running.vms.only to true + # 2. create dynamic service offering + # 3. update account cpu/ram limitation to current value + # 4. deploy vm (startvm=false), resource count of cpu/ram is not changed + # 5. start vm, it should fail + # 6. increase cpu limitation, start vm, it should fail + # 7. increase memory limitation, start vm, it should succeed. resource count of cpu/ram increases + # 8. restore vm, it should succeed. resource count of cpu/ram is not changed + # 9. destroy vm, resource count of cpu/ram decreases + # 10. expunge vm, resource count of cpu/ram is not changed + """ + Configurations.update(self.apiclient, + name="resource.count.running.vms.only", + value="true" ) + + # Create dynamic service offering + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + self.service_offering = ServiceOffering.create( + self.apiclient, + self.services["service_offering"]) + self.cleanup.append(self.service_offering) + + # update resource limitation + self.update_account_resource_limitation(self.expectedCpu, self.expectedMemory) + + # deploy vm (startvm=false) + try: + virtual_machine_5 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + customcpunumber=1, + customcpuspeed=100, + custommemory=256, + templateid=self.template.id, + zoneid=self.zone.id, + startvm=False, + mode=self.zone.networktype + ) + except Exception as e: + self.fail("Exception while deploying virtual machine: %s" % e) + + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # start vm + try: + virtual_machine_5.start(self.apiclient) + self.fail("Start VM should fail as there is not enough cpu") + except Exception: + self.debug("Start VM failed as expected") + + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # increase cpu limitation, and start vm + self.update_account_resource_limitation(self.expectedCpu + virtual_machine_5.cpunumber, self.expectedMemory) + try: + virtual_machine_5.start(self.apiclient) + self.fail("Start VM should fail as there is not enough memory") + except Exception: + self.debug("Start VM failed as expected") + + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # increase memory limitation, and start vm + self.update_account_resource_limitation(self.expectedCpu + virtual_machine_5.cpunumber, self.expectedMemory + virtual_machine_5.memory) + try: + virtual_machine_5.start(self.apiclient) + self.debug("Start VM succeed as expected") + except Exception: + self.fail("Start VM should succeed as there is enough cpu and memory") + + self.expectedCpu = self.expectedCpu + virtual_machine_5.cpunumber + self.expectedMemory = self.expectedMemory + virtual_machine_5.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # restore running vm + virtual_machine_5.restore(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # expunge vm + virtual_machine_5.delete(self.apiclient, expunge=True) + self.expectedCpu = self.expectedCpu - virtual_machine_5.cpunumber + self.expectedMemory = self.expectedMemory - virtual_machine_5.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + @attr(tags=["advanced", "advancedsg"], required_hardware="false") + def test_06_resource_count_vm_with_dynamic_offering_in_all_states_failed_cases(self): + """Create VM with dynamic service offering. Take resources of vm in all states into calculation of resource count. Test failed cases + + Steps: + # 1. update resource.count.running.vms.only to false + # 2. create dynamic service offering + # 3. update account cpu/ram limitation to current value + # 4. deploy vm (startvm=false), it should fail + # 5. increase cpu limitation, deploy vm, it should fail + # 6. increase memory limitation, deploy vm, it should succeed. resource count of cpu/ram increases + # 7. start vm, resource count of cpu/ram is not changed + # 8. restore vm, it should succeed. resource count of cpu/ram is not changed + # 9. destroy vm, resource count of cpu/ram decreases + # 10. expunge vm, resource count of cpu/ram is not changed + """ + Configurations.update(self.apiclient, + name="resource.count.running.vms.only", + value="false" ) + + # Create dynamic service offering + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + self.service_offering = ServiceOffering.create( + self.apiclient, + self.services["service_offering"]) + self.cleanup.append(self.service_offering) + + # update resource limitation + self.update_account_resource_limitation(self.expectedCpu, self.expectedMemory) + + # deploy vm (startvm=false) + try: + virtual_machine_6 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + customcpunumber=1, + customcpuspeed=100, + custommemory=256, + templateid=self.template.id, + zoneid=self.zone.id, + startvm=False, + mode=self.zone.networktype + ) + self.fail("Deploy VM should fail as there is not enough cpu") + except Exception as e: + self.debug("Deploy VM failed as expected") + + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # increase cpu limitation, and deploy vm + self.update_account_resource_limitation(self.expectedCpu + 1, self.expectedMemory) + try: + virtual_machine_6 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + customcpunumber=1, + customcpuspeed=100, + custommemory=256, + templateid=self.template.id, + zoneid=self.zone.id, + startvm=False, + mode=self.zone.networktype + ) + self.fail("Deploy VM should fail as there is not enough memory") + except Exception as e: + self.debug("Deploy VM failed as expected") + + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # increase memory limitation, and deploy vm + self.update_account_resource_limitation(self.expectedCpu + 1, self.expectedMemory + 256) + try: + virtual_machine_6 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + customcpunumber=1, + customcpuspeed=100, + custommemory=256, + templateid=self.template.id, + zoneid=self.zone.id, + startvm=False, + mode=self.zone.networktype + ) + self.debug("Deploy VM succeed as expected") + except Exception: + self.fail("Deploy VM should succeed as there is enough cpu and memory") + + self.expectedCpu = self.expectedCpu + virtual_machine_6.cpunumber + self.expectedMemory = self.expectedMemory + virtual_machine_6.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # start vm + virtual_machine_6.start(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # restore running vm + virtual_machine_6.restore(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # expunge vm + virtual_machine_6.delete(self.apiclient, expunge=True) + self.expectedCpu = self.expectedCpu - virtual_machine_6.cpunumber + self.expectedMemory = self.expectedMemory - virtual_machine_6.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + @attr(tags=["advanced", "advancedsg"], required_hardware="false") + def test_07_resource_count_vm_in_running_state_and_move_and_upgrade(self): + """Create VM with dynamic service offering. Take resources of vm in running state into calculation. Move vm to another account and upgrade it. + + Steps: + # 1. update resource.count.running.vms.only to true + # 2. create dynamic service offering + # 3. deploy vm, resource count of cpu/ram increases + # 4. stop vm, resource count of cpu/ram decreases + # 5. create another account + # 6. move vm to new account. resource count of cpu/ram of current account is not changed. resource count of cpu/ram of new account is not changed. + # 7. create another service offering. + # 8. upgrade vm. resource count of cpu/ram of new account is not changed. + # 9. start vm, resource count of cpu/ram of new account increases with cpu/ram of new service offering. + # 10. destroy vm, resource count of cpu/ram decreases + # 11. expunge vm, resource count of cpu/ram is not changed + """ + Configurations.update(self.apiclient, + name="resource.count.running.vms.only", + value="true" ) + + # Create dynamic service offering + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + self.service_offering = ServiceOffering.create( + self.apiclient, + self.services["service_offering"]) + self.cleanup.append(self.service_offering) + + # deploy vm + try: + virtual_machine_7 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + customcpunumber=1, + customcpuspeed=100, + custommemory=256, + templateid=self.template.id, + zoneid=self.zone.id + ) + except Exception as e: + self.fail("Exception while deploying virtual machine: %s" % e) + + self.expectedCpu = self.expectedCpu + virtual_machine_7.cpunumber + self.expectedMemory = self.expectedMemory + virtual_machine_7.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # stop vm + virtual_machine_7.stop(self.apiclient) + self.expectedCpu = self.expectedCpu - virtual_machine_7.cpunumber + self.expectedMemory = self.expectedMemory - virtual_machine_7.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # create another account + self.account2 = Account.create( + self.apiclient, + self.services["account2"], + admin=True, + domainid=self.domain.id + ) + accounts = Account.list(self.apiclient, id=self.account2.id) + self.account2Cpu = int(accounts[0].cputotal) + self.account2Memory = int(accounts[0].memorytotal) + + # move vm to new account. resource count of cpu/ram of current account is not changed. resource count of cpu/ram of new account is not changed. + oldcpunumber = virtual_machine_7.cpunumber + oldmemory = virtual_machine_7.memory + virtual_machine_7.assign_virtual_machine(self.apiclient, self.account2.name, self.account2.domainid) + + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2); + + # create another service offering + self.service_offering_big = ServiceOffering.create( + self.apiclient, + self.services["service_offerings"]["big"] + ) + self.cleanup.append(self.service_offering_big) + + # upgrade vm + virtual_machine_7.change_service_offering(self.apiclient, self.service_offering_big.id) + self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2); + + # start vm, resource count of cpu/ram of new account increases with cpu/ram of new service offering. + virtual_machine_7.start(self.apiclient) + self.account2Cpu = self.account2Cpu + self.service_offering_big.cpunumber + self.account2Memory = self.account2Memory + self.service_offering_big.memory + self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2); + + # expunge vm + virtual_machine_7.delete(self.apiclient, expunge=True) + self.account2Cpu = self.account2Cpu - self.service_offering_big.cpunumber + self.account2Memory = self.account2Memory - self.service_offering_big.memory + self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2); + + @attr(tags=["advanced", "advancedsg"], required_hardware="false") + def test_08_resource_count_vm_in_all_states_and_move_and_upgrade(self): + """Create VM with dynamic service offering. Take resources of vm in all states into calculation. Move vm to another account and upgrade it. + + Steps: + # 1. update resource.count.running.vms.only to true + # 2. create dynamic service offering + # 3. deploy vm, resource count of cpu/ram increases + # 4. stop vm, resource count of cpu/ram is not changed + # 5. create another account + # 6. move vm to new account. resource count of cpu/ram of current account decreases. resource count of cpu/ram of new account increases. + # 7. create another service offering. + # 8. upgrade vm. resource count of cpu/ram of new account is changed. + # 9. start vm, resource count of cpu/ram is not changed + # 10. destroy vm, resource count of cpu/ram decreases + # 11. expunge vm, resource count of cpu/ram is not changed + """ + Configurations.update(self.apiclient, + name="resource.count.running.vms.only", + value="false" ) + + # Create dynamic service offering + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + self.service_offering = ServiceOffering.create( + self.apiclient, + self.services["service_offering"]) + self.cleanup.append(self.service_offering) + + # deploy vm + try: + virtual_machine_8 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + customcpunumber=1, + customcpuspeed=100, + custommemory=256, + templateid=self.template.id, + zoneid=self.zone.id + ) + except Exception as e: + self.fail("Exception while deploying virtual machine: %s" % e) + + self.expectedCpu = self.expectedCpu + virtual_machine_8.cpunumber + self.expectedMemory = self.expectedMemory + virtual_machine_8.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # stop vm + virtual_machine_8.stop(self.apiclient) + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + # create another account + self.account2 = Account.create( + self.apiclient, + self.services["account2"], + admin=True, + domainid=self.domain.id + ) + self.cleanup.append(self.account2) + accounts = Account.list(self.apiclient, id=self.account2.id) + self.account2Cpu = int(accounts[0].cputotal) + self.account2Memory = int(accounts[0].memorytotal) + + # move vm to new account. resource count of cpu/ram of current account decreases. resource count of cpu/ram of new account increases. + oldcpunumber = virtual_machine_8.cpunumber + oldmemory = virtual_machine_8.memory + virtual_machine_8.assign_virtual_machine(self.apiclient, self.account2.name, self.account2.domainid) + + self.expectedCpu = self.expectedCpu - virtual_machine_8.cpunumber + self.expectedMemory = self.expectedMemory - virtual_machine_8.memory + self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory); + + self.account2Cpu = self.account2Cpu + virtual_machine_8.cpunumber + self.account2Memory = self.account2Memory + virtual_machine_8.memory + self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2); + + # create another service offering + self.service_offering_big = ServiceOffering.create( + self.apiclient, + self.services["service_offerings"]["big"] + ) + self.cleanup.append(self.service_offering_big) + + # upgrade vm + virtual_machine_8.change_service_offering(self.apiclient, self.service_offering_big.id) + self.account2Cpu = self.account2Cpu + self.service_offering_big.cpunumber - oldcpunumber + self.account2Memory = self.account2Memory + self.service_offering_big.memory - oldmemory + self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2); + + # start vm + virtual_machine_8.start(self.apiclient) + self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2); + + # expunge vm + virtual_machine_8.delete(self.apiclient, expunge=True) + self.account2Cpu = self.account2Cpu - self.service_offering_big.cpunumber + self.account2Memory = self.account2Memory - self.service_offering_big.memory + self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2); diff --git a/tools/marvin/marvin/codes.py b/tools/marvin/marvin/codes.py index 317cfd077bd..1e8a83a0682 100644 --- a/tools/marvin/marvin/codes.py +++ b/tools/marvin/marvin/codes.py @@ -102,6 +102,14 @@ USER = 0 XEN_SERVER = "XenServer" ADMIN_ACCOUNT = 'ADMIN_ACCOUNT' USER_ACCOUNT = 'USER_ACCOUNT' +RESOURCE_USER_VM = 0 +RESOURCE_PUBLIC_IP = 1 +RESOURCE_VOLUME = 2 +RESOURCE_SNAPSHOT = 3 +RESOURCE_TEMPLATE = 4 +RESOURCE_PROJECT = 5 +RESOURCE_NETWORK = 6 +RESOURCE_VPC = 7 RESOURCE_CPU = 8 RESOURCE_MEMORY = 9 RESOURCE_PRIMARY_STORAGE = 10 diff --git a/tools/marvin/marvin/lib/common.py b/tools/marvin/marvin/lib/common.py index 03e5fba526b..c3a2f1cfaf8 100644 --- a/tools/marvin/marvin/lib/common.py +++ b/tools/marvin/marvin/lib/common.py @@ -63,6 +63,9 @@ from marvin.sshClient import SshClient from marvin.codes import (PASS, FAILED, ISOLATED_NETWORK, VPC_NETWORK, BASIC_ZONE, FAIL, NAT_RULE, STATIC_NAT_RULE, RESOURCE_PRIMARY_STORAGE, RESOURCE_SECONDARY_STORAGE, + RESOURCE_USER_VM, RESOURCE_PUBLIC_IP, RESOURCE_VOLUME, + RESOURCE_SNAPSHOT, RESOURCE_TEMPLATE, RESOURCE_PROJECT, + RESOURCE_NETWORK, RESOURCE_VPC, RESOURCE_CPU, RESOURCE_MEMORY, PUBLIC_TRAFFIC, GUEST_TRAFFIC, MANAGEMENT_TRAFFIC, STORAGE_TRAFFIC, VMWAREDVS) @@ -1392,6 +1395,20 @@ def matchResourceCount(apiclient, expectedCount, resourceType, resourceCount = resourceholderlist[0].cputotal elif resourceType == RESOURCE_MEMORY: resourceCount = resourceholderlist[0].memorytotal + elif resourceType == RESOURCE_USER_VM: + resourceCount = resourceholderlist[0].vmtotal + elif resourceType == RESOURCE_PUBLIC_IP: + resourceCount = resourceholderlist[0].iptotal + elif resourceType == RESOURCE_VOLUME: + resourceCount = resourceholderlist[0].volumetotal + elif resourceType == RESOURCE_SNAPSHOT: + resourceCount = resourceholderlist[0].snapshottotal + elif resourceType == RESOURCE_TEMPLATE: + resourceCount = resourceholderlist[0].templatetotal + elif resourceType == RESOURCE_NETWORK: + resourceCount = resourceholderlist[0].networktotal + elif resourceType == RESOURCE_VPC: + resourceCount = resourceholderlist[0].vpctotal assert str(resourceCount) == str(expectedCount),\ "Resource count %s should match with the expected resource count %s" %\ (resourceCount, expectedCount) @@ -1452,7 +1469,36 @@ def isDomainResourceCountEqualToExpectedCount(apiclient, domainid, expectedcount isExceptionOccured = True return [isExceptionOccured, reasonForException, isResourceCountEqual] - resourcecount = (response[0].resourcecount / (1024**3)) + if resourcetype == RESOURCE_PRIMARY_STORAGE or resourcetype == RESOURCE_SECONDARY_STORAGE: + resourcecount = (response[0].resourcecount / (1024**3)) + else: + resourcecount = response[0].resourcecount + + if resourcecount == expectedcount: + isResourceCountEqual = True + return [isExceptionOccured, reasonForException, isResourceCountEqual] + +def isAccountResourceCountEqualToExpectedCount(apiclient, domainid, account, expectedcount, + resourcetype): + """Get the resource count of specific account and match + it with the expected count + Return list [isExceptionOccured, reasonForException, isResourceCountEqual]""" + isResourceCountEqual = False + isExceptionOccured = False + reasonForException = None + try: + response = Resources.updateCount(apiclient, domainid=domainid, account=account, + resourcetype=resourcetype) + except Exception as e: + reasonForException = "Failed while updating resource count: %s" % e + isExceptionOccured = True + return [isExceptionOccured, reasonForException, isResourceCountEqual] + + if resourcetype == RESOURCE_PRIMARY_STORAGE or resourcetype == RESOURCE_SECONDARY_STORAGE: + resourcecount = (response[0].resourcecount / (1024**3)) + else: + resourcecount = response[0].resourcecount + if resourcecount == expectedcount: isResourceCountEqual = True return [isExceptionOccured, reasonForException, isResourceCountEqual]