mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-1466: Automatiion - Primary Storage Limits test cases
This commit is contained in:
parent
942fc98848
commit
e7fe391be4
|
|
@ -0,0 +1,690 @@
|
|||
# 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.
|
||||
|
||||
""" P1 tests for primary storage domain limits
|
||||
|
||||
Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domain+or+accounts
|
||||
|
||||
Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-1466
|
||||
|
||||
Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domains+and+accounts
|
||||
"""
|
||||
# Import Local Modules
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase, unittest
|
||||
from marvin.lib.base import (Account,
|
||||
ServiceOffering,
|
||||
VirtualMachine,
|
||||
Resources,
|
||||
Domain,
|
||||
Volume,
|
||||
DiskOffering,
|
||||
Snapshot)
|
||||
from marvin.lib.common import (get_domain,
|
||||
get_zone,
|
||||
get_template,
|
||||
createSnapshotFromVirtualMachineVolume,
|
||||
isVmExpunged,
|
||||
isDomainResourceCountEqualToExpectedCount)
|
||||
from marvin.lib.utils import (cleanup_resources)
|
||||
from marvin.codes import (PASS,
|
||||
FAIL,
|
||||
FAILED,
|
||||
RESOURCE_PRIMARY_STORAGE)
|
||||
|
||||
class TestMultipleChildDomain(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cloudstackTestClient = super(TestMultipleChildDomain,
|
||||
cls).getClsTestClient()
|
||||
cls.api_client = cloudstackTestClient.getApiClient()
|
||||
# Fill services from the external config file
|
||||
cls.services = cloudstackTestClient.getParsedTestDataConfig()
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client)
|
||||
cls.zone = get_zone(cls.api_client, cloudstackTestClient.getZoneForTests())
|
||||
cls.services["mode"] = cls.zone.networktype
|
||||
|
||||
cls.template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostype"]
|
||||
)
|
||||
|
||||
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
cls.services["virtual_machine"]["template"] = cls.template.id
|
||||
cls.services["volume"]["zoneid"] = cls.zone.id
|
||||
|
||||
cls._cleanup = []
|
||||
try:
|
||||
cls.service_offering = ServiceOffering.create(cls.api_client,
|
||||
cls.services["service_offering"])
|
||||
cls._cleanup.append(cls.service_offering)
|
||||
except Exception as e:
|
||||
cls.tearDownClass()
|
||||
raise unittest.SkipTest("Exception in setUpClass: %s" % e)
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
# Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
self.services["disk_offering"]["disksize"] = 5
|
||||
try:
|
||||
self.disk_offering = DiskOffering.create(
|
||||
self.apiclient,
|
||||
self.services["disk_offering"]
|
||||
)
|
||||
self.assertNotEqual(self.disk_offering, None, \
|
||||
"Disk offering is None")
|
||||
self.cleanup.append(self.disk_offering)
|
||||
except Exception as e:
|
||||
self.tearDown()
|
||||
self.skipTest("Failure while creating disk offering: %s" % e)
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
# Clean up, terminate the created instance, volumes and snapshots
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
pass
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def updateDomainResourceLimits(self, parentdomainlimit, subdomainlimit):
|
||||
"""Update primary storage limits of the parent domain and its
|
||||
child domains"""
|
||||
|
||||
try:
|
||||
#Update resource limit for domain
|
||||
Resources.updateLimit(self.apiclient, resourcetype=10,
|
||||
max=parentdomainlimit,
|
||||
domainid=self.parent_domain.id)
|
||||
|
||||
# Update Resource limit for sub-domains
|
||||
Resources.updateLimit(self.apiclient, resourcetype=10,
|
||||
max=subdomainlimit,
|
||||
domainid=self.cadmin_1.domainid)
|
||||
|
||||
Resources.updateLimit(self.apiclient, resourcetype=10,
|
||||
max=subdomainlimit,
|
||||
domainid=self.cadmin_2.domainid)
|
||||
except Exception as e:
|
||||
return [FAIL, e]
|
||||
return [PASS, None]
|
||||
|
||||
def setupAccounts(self):
|
||||
try:
|
||||
self.parent_domain = Domain.create(self.apiclient,
|
||||
services=self.services["domain"],
|
||||
parentdomainid=self.domain.id)
|
||||
self.parentd_admin = Account.create(self.apiclient, self.services["account"],
|
||||
admin=True, domainid=self.parent_domain.id)
|
||||
|
||||
# Create sub-domains and their admin accounts
|
||||
self.cdomain_1 = Domain.create(self.apiclient,
|
||||
services=self.services["domain"],
|
||||
parentdomainid=self.parent_domain.id)
|
||||
self.cdomain_2 = Domain.create(self.apiclient,
|
||||
services=self.services["domain"],
|
||||
parentdomainid=self.parent_domain.id)
|
||||
|
||||
self.cadmin_1 = Account.create(self.apiclient, self.services["account"],
|
||||
admin=True, domainid=self.cdomain_1.id)
|
||||
|
||||
self.cadmin_2 = Account.create(self.apiclient, self.services["account"],
|
||||
admin=True, domainid=self.cdomain_2.id)
|
||||
|
||||
# Cleanup the resources created at end of test
|
||||
self.cleanup.append(self.cadmin_1)
|
||||
self.cleanup.append(self.cadmin_2)
|
||||
self.cleanup.append(self.cdomain_1)
|
||||
self.cleanup.append(self.cdomain_2)
|
||||
self.cleanup.append(self.parentd_admin)
|
||||
self.cleanup.append(self.parent_domain)
|
||||
|
||||
users = {
|
||||
self.cdomain_1: self.cadmin_1,
|
||||
self.cdomain_2: self.cadmin_2
|
||||
}
|
||||
except Exception as e:
|
||||
return [FAIL, e, None]
|
||||
return [PASS, None, users]
|
||||
|
||||
@attr(tags=["advanced","selfservice"])
|
||||
def test_01_multiple_domains_primary_storage_limits(self):
|
||||
"""Test primary storage limit of domain and its sub-domains
|
||||
|
||||
# Steps
|
||||
1. Create a parent domain and two sub-domains in it (also admin accounts
|
||||
of each domain)
|
||||
2. Update primary storage limits of the parent domain and child domains
|
||||
3. Deploy VM in child domain 1 so that total primary storage
|
||||
is less than the limit of child domain
|
||||
4. Repeat step 3 for child domain 2
|
||||
5. Try to deploy VM in parent domain now so that the total primary storage in
|
||||
parent domain (including that in sub-domains is more than the primary
|
||||
storage limit of the parent domain
|
||||
6. Delete the admin account of child domain 1 and check resource count
|
||||
of the parent domain
|
||||
7. Delete VM deployed in account 2 and check primary storage count
|
||||
of parent domain
|
||||
|
||||
# Validations:
|
||||
1. Step 3 and 4 should succeed
|
||||
2. Step 5 should fail as the resource limit exceeds in parent domain
|
||||
3. After step 6, resource count in parent domain should decrease by equivalent
|
||||
quantity
|
||||
4. After step 7, resource count in parent domain should be 0"""
|
||||
|
||||
# Setting up account and domain hierarchy
|
||||
result = self.setupAccounts()
|
||||
self.assertEqual(result[0], PASS,\
|
||||
"Failure while setting up accounts and domains: %s" % result[1])
|
||||
|
||||
templatesize = (self.template.size / (1024**3))
|
||||
disksize = 10
|
||||
subdomainlimit = (templatesize + disksize)
|
||||
|
||||
result = self.updateDomainResourceLimits(((subdomainlimit*3)- 1), subdomainlimit)
|
||||
self.assertEqual(result[0], PASS,\
|
||||
"Failure while updating resource limits: %s" % result[1])
|
||||
|
||||
try:
|
||||
self.services["disk_offering"]["disksize"] = disksize
|
||||
disk_offering_custom = DiskOffering.create(self.apiclient,
|
||||
services=self.services["disk_offering"])
|
||||
self.cleanup.append(disk_offering_custom)
|
||||
except Exception as e:
|
||||
self.fail("Failed to create disk offering")
|
||||
|
||||
# Get API clients of parent and child domain admin accounts
|
||||
api_client_admin = self.testClient.getUserApiClient(
|
||||
UserName=self.parentd_admin.name,
|
||||
DomainName=self.parentd_admin.domain)
|
||||
self.assertNotEqual(api_client_admin, FAILED,\
|
||||
"Failed to create api client for account: %s" % self.parentd_admin.name)
|
||||
|
||||
api_client_cadmin_1 = self.testClient.getUserApiClient(
|
||||
UserName=self.cadmin_1.name,
|
||||
DomainName=self.cadmin_1.domain)
|
||||
self.assertNotEqual(api_client_cadmin_1, FAILED,\
|
||||
"Failed to create api client for account: %s" % self.cadmin_1.name)
|
||||
|
||||
api_client_cadmin_2 = self.testClient.getUserApiClient(
|
||||
UserName=self.cadmin_2.name,
|
||||
DomainName=self.cadmin_2.domain)
|
||||
self.assertNotEqual(api_client_cadmin_2, FAILED,\
|
||||
"Failed to create api client for account: %s" % self.cadmin_2.name)
|
||||
|
||||
VirtualMachine.create(
|
||||
api_client_cadmin_1, self.services["virtual_machine"],
|
||||
accountid=self.cadmin_1.name, domainid=self.cadmin_1.domainid,
|
||||
diskofferingid=disk_offering_custom.id, serviceofferingid=self.service_offering.id
|
||||
)
|
||||
|
||||
self.initialResourceCount = (templatesize + disksize)
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.parent_domain.id,
|
||||
self.initialResourceCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
|
||||
# Create VM in second child domain
|
||||
vm_2 = VirtualMachine.create(
|
||||
api_client_cadmin_2, self.services["virtual_machine"],
|
||||
accountid=self.cadmin_2.name, domainid=self.cadmin_2.domainid,
|
||||
diskofferingid=disk_offering_custom.id, serviceofferingid=self.service_offering.id
|
||||
)
|
||||
|
||||
# Now the VMs in two child domains have exhausted the primary storage limit
|
||||
# of parent domain, hence VM creation in parent domain with custom disk offering
|
||||
# should fail
|
||||
with self.assertRaises(Exception):
|
||||
VirtualMachine.create(
|
||||
api_client_admin, self.services["virtual_machine"],
|
||||
accountid=self.parentd_admin.name, domainid=self.parentd_admin.domainid,
|
||||
diskofferingid=disk_offering_custom.id, serviceofferingid=self.service_offering.id
|
||||
)
|
||||
|
||||
# Deleting user account
|
||||
self.cadmin_1.delete(self.apiclient)
|
||||
self.cleanup.remove(self.cadmin_1)
|
||||
|
||||
expectedCount = self.initialResourceCount
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.parent_domain.id,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
|
||||
try:
|
||||
vm_2.delete(self.apiclient)
|
||||
except Exception as e:
|
||||
self.fail("Failed to delete instance: %s" % e)
|
||||
|
||||
self.assertTrue(isVmExpunged(self.apiclient, vm_2.id), "VM not expunged \
|
||||
in allotted time")
|
||||
|
||||
expectedCount = 0
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.parent_domain.id,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_02_multiple_domains_primary_storage_limits(self):
|
||||
"""Test primary storage counts in multiple child domains
|
||||
# Steps
|
||||
1. Create a parent domain and two sub-domains in it (also admin accounts
|
||||
of each domain)
|
||||
Repeat following steps for both the child domains
|
||||
2. Deploy VM in child domain
|
||||
3. Check if the resource count for domain is updated correctly
|
||||
4. Create a volume and attach it to the VM
|
||||
5. Check if the primary storage resource count is updated correctly
|
||||
|
||||
"""
|
||||
|
||||
# Setting up account and domain hierarchy
|
||||
result = self.setupAccounts()
|
||||
self.assertEqual(result[0], PASS,\
|
||||
"Failure while setting up accounts and domains: %s" % result[1])
|
||||
users = result[2]
|
||||
|
||||
templatesize = (self.template.size / (1024**3))
|
||||
|
||||
for domain, admin in users.items():
|
||||
self.account = admin
|
||||
self.domain = domain
|
||||
|
||||
apiclient = self.testClient.getUserApiClient(
|
||||
UserName=self.account.name,
|
||||
DomainName=self.account.domain)
|
||||
self.assertNotEqual(apiclient, FAILED,\
|
||||
"Failed to create api client for account: %s" % self.account.name)
|
||||
try:
|
||||
vm = VirtualMachine.create(
|
||||
apiclient, self.services["virtual_machine"],
|
||||
accountid=self.account.name, domainid=self.account.domainid,
|
||||
diskofferingid=self.disk_offering.id, serviceofferingid=self.service_offering.id
|
||||
)
|
||||
|
||||
expectedCount = templatesize + self.disk_offering.disksize
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.domain.id,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
|
||||
# Creating service offering with 10 GB volume
|
||||
self.services["disk_offering"]["disksize"] = 10
|
||||
disk_offering_10_GB = DiskOffering.create(self.apiclient,
|
||||
services=self.services["disk_offering"])
|
||||
|
||||
self.cleanup.append(disk_offering_10_GB)
|
||||
|
||||
volume = Volume.create(
|
||||
apiclient, self.services["volume"],
|
||||
zoneid=self.zone.id, account=self.account.name,
|
||||
domainid=self.account.domainid, diskofferingid=disk_offering_10_GB.id
|
||||
)
|
||||
|
||||
volumeSize = (volume.size / (1024**3))
|
||||
expectedCount += volumeSize
|
||||
|
||||
vm.attach_volume(apiclient, volume=volume)
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.domain.id,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
|
||||
expectedCount -= volumeSize
|
||||
vm.detach_volume(apiclient, volume=volume)
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.domain.id,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
except Exception as e:
|
||||
self.fail("Failure: %s" % e)
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_03_multiple_domains_multiple_volumes(self):
|
||||
"""Test primary storage counts in multiple child domains
|
||||
# Steps
|
||||
1. Create a parent domain and two sub-domains in it (also admin accounts
|
||||
of each domain)
|
||||
Repeat following steps for both the child domains
|
||||
2. Deploy VM in child domain
|
||||
3. Check if the resource count for domain is updated correctly
|
||||
4. Create multiple volumes and attach it to the VM
|
||||
5. Check if the primary storage resource count is updated correctly
|
||||
6. Delete one of the volumes and check if the primary storage resource count
|
||||
reduced by equivalent number
|
||||
7. Detach other volume and check primary storage resource count remains the same
|
||||
|
||||
"""
|
||||
# Setting up account and domain hierarchy
|
||||
result = self.setupAccounts()
|
||||
if result[0] == FAIL:
|
||||
self.fail("Failure while setting up accounts and domains: %s" % result[1])
|
||||
else:
|
||||
users = result[2]
|
||||
|
||||
templatesize = (self.template.size / (1024**3))
|
||||
|
||||
for domain, admin in users.items():
|
||||
self.account = admin
|
||||
self.domain = domain
|
||||
|
||||
apiclient = self.testClient.getUserApiClient(
|
||||
UserName=self.account.name,
|
||||
DomainName=self.account.domain)
|
||||
self.assertNotEqual(apiclient, FAILED,\
|
||||
"Failed to create api client for account: %s" % self.account.name)
|
||||
|
||||
try:
|
||||
vm = VirtualMachine.create(
|
||||
apiclient, self.services["virtual_machine"],
|
||||
accountid=self.account.name, domainid=self.account.domainid,
|
||||
diskofferingid=self.disk_offering.id, serviceofferingid=self.service_offering.id
|
||||
)
|
||||
|
||||
expectedCount = templatesize + self.disk_offering.disksize
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.domain.id,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
|
||||
volume1size = self.services["disk_offering"]["disksize"] = 15
|
||||
disk_offering_15_GB = DiskOffering.create(self.apiclient,
|
||||
services=self.services["disk_offering"])
|
||||
|
||||
self.cleanup.append(disk_offering_15_GB)
|
||||
|
||||
volume2size = self.services["disk_offering"]["disksize"] = 20
|
||||
disk_offering_20_GB = DiskOffering.create(self.apiclient,
|
||||
services=self.services["disk_offering"])
|
||||
|
||||
self.cleanup.append(disk_offering_20_GB)
|
||||
|
||||
volume_1 = Volume.create(
|
||||
apiclient, self.services["volume"],
|
||||
zoneid=self.zone.id, account=self.account.name,
|
||||
domainid=self.account.domainid, diskofferingid=disk_offering_15_GB.id
|
||||
)
|
||||
|
||||
volume_2 = Volume.create(
|
||||
apiclient, self.services["volume"],
|
||||
zoneid=self.zone.id, account=self.account.name,
|
||||
domainid=self.account.domainid, diskofferingid=disk_offering_20_GB.id
|
||||
)
|
||||
|
||||
vm.attach_volume(apiclient, volume=volume_1)
|
||||
vm.attach_volume(apiclient, volume=volume_2)
|
||||
|
||||
expectedCount += volume1size + volume2size
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.domain.id,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
|
||||
vm.detach_volume(apiclient, volume=volume_1)
|
||||
volume_1.delete(apiclient)
|
||||
|
||||
expectedCount -= volume1size
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.domain.id,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
|
||||
expectedCount -= volume2size
|
||||
vm.detach_volume(apiclient, volume=volume_2)
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.domain.id,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
except Exception as e:
|
||||
self.fail("Failure: %s" % e)
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_04_create_template_snapshot(self):
|
||||
"""Test create snapshot and templates from volume
|
||||
|
||||
# Validate the following
|
||||
1. Create parent domain with two child sub-domains (and their admin accounts)
|
||||
Follow these steps for both the domains
|
||||
# 1. Create template from snapshot and verify secondary storage resource count
|
||||
# 2. Create Volume from Snapshot and verify primary storage resource count
|
||||
# 3. Attach volume to instance which was created from snapshot and
|
||||
# verify primary storage resource count
|
||||
# 4. Detach volume from instance which was created from snapshot and
|
||||
# verify the primary storage resource count
|
||||
# 5. Delete volume which was created from snapshot and verify primary storage
|
||||
resource count"""
|
||||
|
||||
result = self.setupAccounts()
|
||||
if result[0] == FAIL:
|
||||
self.fail("Failure while setting up accounts and domains: %s" % result[1])
|
||||
users = result[2]
|
||||
|
||||
for domain, admin in users.items():
|
||||
self.account = admin
|
||||
self.domain = domain
|
||||
|
||||
try:
|
||||
apiclient = self.testClient.getUserApiClient(
|
||||
UserName=self.account.name,
|
||||
DomainName=self.account.domain)
|
||||
self.assertNotEqual(apiclient, FAILED,\
|
||||
"Failed to create api client for account: %s" % self.account.name)
|
||||
|
||||
vm = VirtualMachine.create(
|
||||
apiclient, self.services["virtual_machine"],
|
||||
accountid=self.account.name, domainid=self.account.domainid,
|
||||
diskofferingid=self.disk_offering.id, serviceofferingid=self.service_offering.id
|
||||
)
|
||||
|
||||
templatesize = (self.template.size / (1024**3))
|
||||
|
||||
initialResourceCount = expectedCount = templatesize + self.disk_offering.disksize
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.domain.id,
|
||||
initialResourceCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
|
||||
vm.stop(self.apiclient)
|
||||
|
||||
response = createSnapshotFromVirtualMachineVolume(apiclient, self.account, vm.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
snapshot = response[1]
|
||||
|
||||
response = snapshot.validateState(apiclient, Snapshot.BACKED_UP)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
self.services["volume"]["size"] = self.services["disk_offering"]["disksize"]
|
||||
volume = Volume.create_from_snapshot(apiclient,
|
||||
snapshot_id=snapshot.id,
|
||||
services=self.services["volume"],
|
||||
account=self.account.name,
|
||||
domainid=self.account.domainid)
|
||||
volumeSize = (volume.size / (1024**3))
|
||||
vm.attach_volume(apiclient, volume)
|
||||
expectedCount = initialResourceCount + (volumeSize)
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.domain.id,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
|
||||
expectedCount -= volumeSize
|
||||
vm.detach_volume(apiclient, volume)
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.domain.id,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
|
||||
volume.delete(apiclient)
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.domain.id,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
except Exception as e:
|
||||
self.fail("Failed with exception : %s" % e)
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_05_assign_virtual_machine_different_domain(self):
|
||||
"""Test assign virtual machine to account belonging to different domain
|
||||
|
||||
# Steps
|
||||
1. Create a parent domain and two sub-domains in it (also admin accounts
|
||||
of each domain)
|
||||
2. Deploy VM in child domain 1
|
||||
3. Check if the resource count for domain 1 is updated correctly
|
||||
4. Assign this virtual machine to account 2 in domain 2
|
||||
5. Verify that primaru storage resource count of domain 1 is now 0 and
|
||||
primary storage resource count of domain 2 is increased by equivalent number
|
||||
"""
|
||||
|
||||
# Setting up account and domain hierarchy
|
||||
result = self.setupAccounts()
|
||||
self.assertEqual(result[0], PASS, result[1])
|
||||
|
||||
apiclient = self.testClient.getUserApiClient(
|
||||
UserName=self.cadmin_1.name,
|
||||
DomainName=self.cadmin_1.domain)
|
||||
self.assertNotEqual(apiclient, FAILED,\
|
||||
"Failed to create api client for account: %s" % self.cadmin_1.name)
|
||||
|
||||
try:
|
||||
vm_1 = VirtualMachine.create(
|
||||
apiclient, self.services["virtual_machine"],
|
||||
accountid=self.cadmin_1.name, domainid=self.cadmin_1.domainid,
|
||||
diskofferingid=self.disk_offering.id, serviceofferingid=self.service_offering.id
|
||||
)
|
||||
|
||||
templatesize = (self.template.size / (1024**3))
|
||||
|
||||
expectedCount = templatesize + self.disk_offering.disksize
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.cadmin_1.domainid,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
|
||||
vm_1.stop(apiclient)
|
||||
vm_1.assign_virtual_machine(self.apiclient, account=self.cadmin_2.name,
|
||||
domainid=self.cadmin_2.domainid)
|
||||
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.cadmin_2.domainid,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
|
||||
expectedCount = 0
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.cadmin_1.domainid,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
except Exception as e:
|
||||
self.fail("Failed with exception: %s" % e)
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_06_destroy_recover_vm(self):
|
||||
"""Test primary storage counts while destroying and recovering VM
|
||||
# Steps
|
||||
1. Create a parent domain and two sub-domains in it (also admin accounts
|
||||
of each domain)
|
||||
Repeat following steps for both the child domains
|
||||
2. Deploy VM in child domain
|
||||
3. Check if the resource count for domain is updated correctly
|
||||
4. Destroy the VM
|
||||
5. Verify that the primary storage resource count remains the same
|
||||
6. Recover the VM
|
||||
7. Verify that the primary storage resource count remains the same
|
||||
"""
|
||||
|
||||
# Setting up account and domain hierarchy
|
||||
result = self.setupAccounts()
|
||||
self.assertEqual(result[0], PASS, result[1])
|
||||
users = result[2]
|
||||
|
||||
for domain, admin in users.items():
|
||||
self.account = admin
|
||||
self.domain = domain
|
||||
try:
|
||||
vm_1 = VirtualMachine.create(
|
||||
self.apiclient, self.services["virtual_machine"],
|
||||
accountid=self.account.name, domainid=self.account.domainid,
|
||||
diskofferingid=self.disk_offering.id, serviceofferingid=self.service_offering.id
|
||||
)
|
||||
|
||||
templatesize = (self.template.size / (1024**3))
|
||||
|
||||
expectedCount = templatesize + self.disk_offering.disksize
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.account.domainid,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
|
||||
vm_1.delete(self.apiclient)
|
||||
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.account.domainid,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
|
||||
vm_1.recover(self.apiclient)
|
||||
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.account.domainid,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
except Exception as e:
|
||||
self.fail("Failed with exception: %s" % e)
|
||||
return
|
||||
|
|
@ -0,0 +1,588 @@
|
|||
# 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.
|
||||
|
||||
""" P1 tests for primary storage limits
|
||||
|
||||
Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domain+or+accounts
|
||||
|
||||
Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-1466
|
||||
|
||||
Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domains+and+accounts
|
||||
"""
|
||||
# Import Local Modules
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase, unittest
|
||||
from marvin.lib.base import (
|
||||
Account,
|
||||
ServiceOffering,
|
||||
VirtualMachine,
|
||||
Domain,
|
||||
Volume,
|
||||
DiskOffering)
|
||||
from marvin.lib.common import (get_domain,
|
||||
get_zone,
|
||||
get_template,
|
||||
matchResourceCount,
|
||||
createSnapshotFromVirtualMachineVolume,
|
||||
isVmExpunged)
|
||||
from marvin.lib.utils import (cleanup_resources,
|
||||
validateList)
|
||||
from marvin.codes import (PASS,
|
||||
FAIL,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
CHILD_DOMAIN_ADMIN,
|
||||
ROOT_DOMAIN_ADMIN)
|
||||
from ddt import ddt, data
|
||||
|
||||
@ddt
|
||||
class TestVolumeLimits(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cloudstackTestClient = super(TestVolumeLimits,
|
||||
cls).getClsTestClient()
|
||||
cls.api_client = cloudstackTestClient.getApiClient()
|
||||
# Fill services from the external config file
|
||||
cls.services = cloudstackTestClient.getParsedTestDataConfig()
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client)
|
||||
cls.zone = get_zone(cls.api_client, cloudstackTestClient.getZoneForTests())
|
||||
cls.services["mode"] = cls.zone.networktype
|
||||
|
||||
cls.template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostype"]
|
||||
)
|
||||
|
||||
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
cls.services["virtual_machine"]["template"] = cls.template.id
|
||||
cls.services["volume"]["zoneid"] = cls.zone.id
|
||||
cls._cleanup = []
|
||||
try:
|
||||
cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"])
|
||||
cls._cleanup.append(cls.service_offering)
|
||||
except Exception as e:
|
||||
cls.tearDownClass()
|
||||
raise unittest.SkipTest("Exception in setUpClass: %s" % e)
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
# Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
try:
|
||||
self.services["disk_offering"]["disksize"] = 2
|
||||
self.disk_offering = DiskOffering.create(self.apiclient, self.services["disk_offering"])
|
||||
self.assertNotEqual(self.disk_offering, None,\
|
||||
"Disk offering is None")
|
||||
self.cleanup.append(self.disk_offering)
|
||||
except Exception as e:
|
||||
self.tearDown()
|
||||
self.skipTest("Failure in setup: %s" % e)
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
# Clean up, terminate the created instance, volumes and snapshots
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
pass
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setupAccount(self, accountType):
|
||||
"""Setup the account required for the test"""
|
||||
|
||||
try:
|
||||
if accountType == CHILD_DOMAIN_ADMIN:
|
||||
self.domain = Domain.create(self.apiclient,
|
||||
services=self.services["domain"],
|
||||
parentdomainid=self.domain.id)
|
||||
|
||||
self.account = Account.create(self.apiclient, self.services["account"],
|
||||
domainid=self.domain.id, admin=True)
|
||||
self.cleanup.append(self.account)
|
||||
if accountType == CHILD_DOMAIN_ADMIN:
|
||||
self.cleanup.append(self.domain)
|
||||
|
||||
self.virtualMachine = VirtualMachine.create(self.api_client, self.services["virtual_machine"],
|
||||
accountid=self.account.name, domainid=self.account.domainid,
|
||||
diskofferingid=self.disk_offering.id,
|
||||
serviceofferingid=self.service_offering.id)
|
||||
|
||||
accounts = Account.list(self.apiclient, id=self.account.id)
|
||||
|
||||
self.assertEqual(validateList(accounts)[0], PASS,
|
||||
"accounts list validation failed")
|
||||
|
||||
self.initialResourceCount = int(accounts[0].primarystoragetotal)
|
||||
except Exception as e:
|
||||
return [FAIL, e]
|
||||
return [PASS, None]
|
||||
|
||||
@data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_stop_start_vm(self, value):
|
||||
"""Test Deploy VM with 5 GB volume & verify the usage
|
||||
|
||||
# Validate the following
|
||||
# 1. Create a VM with custom disk offering and check the primary storage count
|
||||
# 2. Stop VM and verify the resource count remains same
|
||||
# 3. Start VM and verify resource count remains same"""
|
||||
|
||||
response = self.setupAccount(value)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
expectedCount = self.initialResourceCount
|
||||
# Stopping instance
|
||||
try:
|
||||
self.virtualMachine.stop(self.apiclient)
|
||||
except Exception as e:
|
||||
self.fail("Failed to stop instance: %s" % e)
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
# Starting instance
|
||||
try:
|
||||
self.virtualMachine.start(self.apiclient)
|
||||
except Exception as e:
|
||||
self.fail("Failed to start instance: %s" % e)
|
||||
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
return
|
||||
|
||||
@unittest.skip("skip")
|
||||
@data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_destroy_recover_vm(self, value):
|
||||
"""Test delete and recover instance
|
||||
|
||||
# Validate the following
|
||||
# 1. Create a VM with custom disk offering and check the primary storage count
|
||||
# 2. Destroy VM and verify the resource count remains same
|
||||
# 3. Recover VM and verify resource count remains same"""
|
||||
|
||||
response = self.setupAccount(value)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
expectedCount = self.initialResourceCount
|
||||
# Stopping instance
|
||||
try:
|
||||
self.virtualMachine.delete(self.apiclient)
|
||||
except Exception as e:
|
||||
self.fail("Failed to destroy instance: %s" % e)
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
# Recovering instance
|
||||
try:
|
||||
self.virtualMachine.recover(self.apiclient)
|
||||
except Exception as e:
|
||||
self.fail("Failed to start instance: %s" % e)
|
||||
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
return
|
||||
|
||||
@data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_attach_detach_volume(self, value):
|
||||
"""Stop attach and detach volume from VM
|
||||
|
||||
# Validate the following
|
||||
# 1. Create a VM with custom disk offering and check the primary storage count
|
||||
# of account
|
||||
# 2. Create custom volume in account
|
||||
# 3. Verify that primary storage count increases by same amount
|
||||
# 4. Attach volume to VM and verify resource count remains the same
|
||||
# 5. Detach volume and verify resource count remains the same"""
|
||||
|
||||
response = self.setupAccount(value)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
apiclient = self.apiclient
|
||||
if value == CHILD_DOMAIN_ADMIN:
|
||||
apiclient = self.testClient.getUserApiClient(
|
||||
UserName=self.account.name,
|
||||
DomainName=self.account.domain
|
||||
)
|
||||
self.assertNotEqual(apiclient, FAIL, "Failure while getting\
|
||||
api client of account: %s" % self.account.name)
|
||||
|
||||
try:
|
||||
self.services["disk_offering"]["disksize"] = 4
|
||||
expectedCount = self.initialResourceCount + int(self.services["disk_offering"]["disksize"])
|
||||
disk_offering = DiskOffering.create(self.apiclient,
|
||||
services=self.services["disk_offering"])
|
||||
|
||||
self.cleanup.append(disk_offering)
|
||||
|
||||
volume = Volume.create(
|
||||
apiclient,self.services["volume"],zoneid=self.zone.id,
|
||||
account=self.account.name,domainid=self.account.domainid,
|
||||
diskofferingid=disk_offering.id)
|
||||
except Exception as e:
|
||||
self.fail("Failure: %s" % e)
|
||||
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
try:
|
||||
self.virtualMachine.attach_volume(apiclient, volume=volume)
|
||||
except Exception as e:
|
||||
self.fail("Failed while attaching volume to VM: %s" % e)
|
||||
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
try:
|
||||
self.virtualMachine.detach_volume(apiclient, volume=volume)
|
||||
except Exception as e:
|
||||
self.fail("Failure while detaching volume: %s" % e)
|
||||
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
return
|
||||
|
||||
@data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_create_multiple_volumes(self, value):
|
||||
"""Test create multiple volumes
|
||||
|
||||
# Validate the following
|
||||
# 1. Create a VM with custom disk offering and check the primary storage count
|
||||
# of account
|
||||
# 2. Create multiple volumes in account
|
||||
# 3. Verify that primary storage count increases by same amount
|
||||
# 4. Attach volumes to VM and verify resource count remains the same
|
||||
# 5. Detach and delete both volumes one by one and verify resource count decreases
|
||||
# proportionately"""
|
||||
|
||||
# Creating service offering with 10 GB volume
|
||||
|
||||
response = self.setupAccount(value)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
apiclient = self.apiclient
|
||||
if value == CHILD_DOMAIN_ADMIN:
|
||||
apiclient = self.testClient.getUserApiClient(
|
||||
UserName=self.account.name,
|
||||
DomainName=self.account.domain
|
||||
)
|
||||
self.assertNotEqual(apiclient, FAIL, "Failure while getting\
|
||||
api client of account %s" % self.account.name)
|
||||
|
||||
try:
|
||||
self.services["disk_offering"]["disksize"] = 5
|
||||
disk_offering_5_GB = DiskOffering.create(self.apiclient,
|
||||
services=self.services["disk_offering"])
|
||||
self.cleanup.append(disk_offering_5_GB)
|
||||
|
||||
self.services["disk_offering"]["disksize"] = 10
|
||||
disk_offering_10_GB = DiskOffering.create(self.apiclient,
|
||||
services=self.services["disk_offering"])
|
||||
|
||||
self.cleanup.append(disk_offering_10_GB)
|
||||
|
||||
volume_1 = Volume.create(
|
||||
apiclient,self.services["volume"],zoneid=self.zone.id,
|
||||
account=self.account.name,domainid=self.account.domainid,
|
||||
diskofferingid=disk_offering_5_GB.id)
|
||||
|
||||
volume_2 = Volume.create(
|
||||
apiclient,self.services["volume"],zoneid=self.zone.id,
|
||||
account=self.account.name,domainid=self.account.domainid,
|
||||
diskofferingid=disk_offering_10_GB.id)
|
||||
|
||||
self.debug("Attaching volume %s to vm %s" % (volume_1.name, self.virtualMachine.name))
|
||||
self.virtualMachine.attach_volume(apiclient, volume=volume_1)
|
||||
|
||||
self.debug("Attaching volume %s to vm %s" % (volume_2.name, self.virtualMachine.name))
|
||||
self.virtualMachine.attach_volume(apiclient, volume=volume_2)
|
||||
except Exception as e:
|
||||
self.fail("Failure: %s" % e)
|
||||
|
||||
expectedCount = self.initialResourceCount + 15 # (5 + 10)
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
try:
|
||||
# Detaching and deleting volume 1
|
||||
self.virtualMachine.detach_volume(apiclient, volume=volume_1)
|
||||
volume_1.delete(apiclient)
|
||||
except Exception as e:
|
||||
self.fail("Failure while volume operation: %s" % e)
|
||||
|
||||
expectedCount -= 5 #After deleting first volume
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
try:
|
||||
# Detaching and deleting volume 2
|
||||
self.virtualMachine.detach_volume(apiclient, volume=volume_2)
|
||||
volume_2.delete(apiclient)
|
||||
except Exception as e:
|
||||
self.fail("Failure while volume operation: %s" % e)
|
||||
|
||||
expectedCount -= 10
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
return
|
||||
|
||||
@data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_deploy_multiple_vm(self, value):
|
||||
"""Test Deploy multiple VMs with & verify the usage
|
||||
# Validate the following
|
||||
# 1. Deploy multiple VMs with this service offering
|
||||
# 2. Update Resource count for the root admin Primary Storage usage
|
||||
# 3. Primary Storage usage should list properly
|
||||
# 4. Destroy one VM among multiple VM's and verify that primary storage count
|
||||
# decreases by equivalent amount
|
||||
"""
|
||||
|
||||
response = self.setupAccount(value)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
self.virtualMachine_2 = VirtualMachine.create(self.api_client, self.services["virtual_machine"],
|
||||
accountid=self.account.name, domainid=self.account.domainid,
|
||||
diskofferingid=self.disk_offering.id,
|
||||
serviceofferingid=self.service_offering.id)
|
||||
|
||||
expectedCount = (self.initialResourceCount * 2) #Total 2 vms
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
self.virtualMachine_3 = VirtualMachine.create(self.api_client, self.services["virtual_machine"],
|
||||
accountid=self.account.name, domainid=self.account.domainid,
|
||||
diskofferingid=self.disk_offering.id,
|
||||
serviceofferingid=self.service_offering.id)
|
||||
|
||||
expectedCount = (self.initialResourceCount * 3) #Total 3 vms
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
self.debug("Destroying instance: %s" % self.virtualMachine_2.name)
|
||||
try:
|
||||
self.virtualMachine_2.delete(self.apiclient)
|
||||
except Exception as e:
|
||||
self.fail("Failed to delete instance: %s" % e)
|
||||
|
||||
self.assertTrue(isVmExpunged(self.apiclient, self.virtualMachine_2.id), "VM not expunged \
|
||||
in allotted time")
|
||||
|
||||
expectedCount = (self.initialResourceCount * 2) #Total 2 vms
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
return
|
||||
|
||||
@data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
|
||||
@attr(tags=["advanced","selfservice"])
|
||||
def test_assign_vm_different_account(self, value):
|
||||
"""Test assign Vm to different account
|
||||
# Validate the following
|
||||
# 1. Deploy VM in account and check the primary storage resource count
|
||||
# 2. Assign VM to another account
|
||||
# 3. Resource count for first account should now equal to 0
|
||||
# 4. Resource count for the account to which VM is assigned should
|
||||
# increase to that of initial resource count of first account
|
||||
"""
|
||||
|
||||
response = self.setupAccount(value)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
try:
|
||||
account_2 = Account.create(self.apiclient, self.services["account"],
|
||||
domainid=self.domain.id, admin=True)
|
||||
self.cleanup.insert(0, account_2)
|
||||
except Exception as e:
|
||||
self.fail("Failed to create account: %s" % e)
|
||||
|
||||
expectedCount = self.initialResourceCount
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
try:
|
||||
self.virtualMachine.stop(self.apiclient)
|
||||
self.virtualMachine.assign_virtual_machine(self.apiclient,
|
||||
account_2.name ,account_2.domainid)
|
||||
except Exception as e:
|
||||
self.fail("Failed to assign virtual machine to account %s: %s" %
|
||||
(account_2.name,e))
|
||||
|
||||
# Checking resource count for account 2
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=account_2.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
expectedCount = 0
|
||||
# Checking resource count for original account
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
return
|
||||
|
||||
@data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_create_template_snapshot(self, value):
|
||||
"""Test create snapshot and templates from volume
|
||||
|
||||
# Validate the following
|
||||
# 1. Deploy VM with custoom disk offering and check the
|
||||
# primary storage resource count
|
||||
# 2. Stop the VM and create Snapshot from VM's volume
|
||||
# 3. Create volume againt from this snapshto and attach to VM
|
||||
# 4. Verify that primary storage count increases by the volume size
|
||||
# 5. Detach and delete volume, verify primary storage count decreaes by volume size"""
|
||||
|
||||
response = self.setupAccount(value)
|
||||
self.debug(response[0])
|
||||
self.debug(response[1])
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
apiclient = self.apiclient
|
||||
if value == CHILD_DOMAIN_ADMIN:
|
||||
apiclient = self.testClient.getUserApiClient(
|
||||
UserName=self.account.name,
|
||||
DomainName=self.account.domain
|
||||
)
|
||||
self.assertNotEqual(apiclient, FAIL, "Failure while getting api\
|
||||
client of account: %s" % self.account.name)
|
||||
|
||||
try:
|
||||
self.virtualMachine.stop(apiclient)
|
||||
except Exception as e:
|
||||
self.fail("Failed to stop instance: %s" % e)
|
||||
expectedCount = self.initialResourceCount
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
self.debug("Creating snapshot from ROOT volume: %s" % self.virtualMachine.name)
|
||||
snapshot = None
|
||||
response = createSnapshotFromVirtualMachineVolume(apiclient, self.account, self.virtualMachine.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
snapshot = response[1]
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
try:
|
||||
self.services["volume"]["size"] = self.services["disk_offering"]["disksize"]
|
||||
volume = Volume.create_from_snapshot(apiclient,
|
||||
snapshot_id=snapshot.id,
|
||||
services=self.services["volume"],
|
||||
account=self.account.name,
|
||||
domainid=self.account.domainid)
|
||||
|
||||
self.debug("Attaching the volume to vm: %s" % self.virtualMachine.name)
|
||||
self.virtualMachine.attach_volume(apiclient, volume)
|
||||
except Exception as e:
|
||||
self.fail("Failure in volume operation: %s" % e)
|
||||
|
||||
expectedCount += int(self.services["volume"]["size"])
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
try:
|
||||
self.virtualMachine.detach_volume(apiclient, volume)
|
||||
except Exception as e:
|
||||
self.fail("Failure in detach volume operation: %s" % e)
|
||||
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
try:
|
||||
self.debug("deleting the volume: %s" % volume.name)
|
||||
volume.delete(apiclient)
|
||||
except Exception as e:
|
||||
self.fail("Failure while deleting volume: %s" % e)
|
||||
|
||||
expectedCount -= int(self.services["volume"]["size"])
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.account.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
return
|
||||
|
|
@ -0,0 +1,300 @@
|
|||
# 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 praimary storage - Maximum Limits
|
||||
|
||||
Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domain+or+accounts
|
||||
|
||||
Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-1466
|
||||
|
||||
Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domains+and+accounts
|
||||
"""
|
||||
# Import Local Modules
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase, unittest
|
||||
from marvin.lib.base import (Account,
|
||||
ServiceOffering,
|
||||
VirtualMachine,
|
||||
Resources,
|
||||
Domain,
|
||||
Project,
|
||||
Volume,
|
||||
DiskOffering)
|
||||
from marvin.lib.common import (get_domain,
|
||||
get_zone,
|
||||
get_template)
|
||||
from marvin.lib.utils import (cleanup_resources,
|
||||
validateList)
|
||||
from marvin.codes import PASS, FAIL
|
||||
|
||||
class TestMaxPrimaryStorageLimits(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cloudstackTestClient = super(TestMaxPrimaryStorageLimits,
|
||||
cls).getClsTestClient()
|
||||
cls.api_client = cloudstackTestClient.getApiClient()
|
||||
# Fill services from the external config file
|
||||
cls.services = cloudstackTestClient.getParsedTestDataConfig()
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client)
|
||||
cls.zone = get_zone(cls.api_client, cloudstackTestClient.getZoneForTests())
|
||||
cls.services["mode"] = cls.zone.networktype
|
||||
|
||||
cls.template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostype"]
|
||||
)
|
||||
|
||||
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
cls.services["virtual_machine"]["template"] = cls.template.id
|
||||
cls.services["volume"]["zoneid"] = cls.zone.id
|
||||
cls._cleanup = []
|
||||
try:
|
||||
cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"])
|
||||
cls._cleanup.append(cls.service_offering)
|
||||
except Exception as e:
|
||||
cls.tearDownClass()
|
||||
raise unittest.SkipTest("Exception in setUpClass: %s" % e)
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
# Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
try:
|
||||
response = self.setupAccounts()
|
||||
if response[0] == FAIL:
|
||||
self.skipTest("Failure while setting up accounts: %s" % response[1])
|
||||
self.services["disk_offering"]["disksize"] = 2
|
||||
self.disk_offering = DiskOffering.create(self.apiclient, self.services["disk_offering"])
|
||||
self.cleanup.append(self.disk_offering)
|
||||
except Exception as e:
|
||||
self.tearDown()
|
||||
self.skipTest("Failure in setup: %s" % e)
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
# Clean up, terminate the created instance, volumes and snapshots
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setupAccounts(self):
|
||||
|
||||
try:
|
||||
self.child_domain = Domain.create(self.apiclient,services=self.services["domain"],
|
||||
parentdomainid=self.domain.id)
|
||||
|
||||
self.child_do_admin = Account.create(self.apiclient, self.services["account"], admin=True,
|
||||
domainid=self.child_domain.id)
|
||||
|
||||
# Create project as a domain admin
|
||||
self.project = Project.create(self.apiclient, self.services["project"],
|
||||
account=self.child_do_admin.name,
|
||||
domainid=self.child_do_admin.domainid)
|
||||
|
||||
# Cleanup created project at end of test
|
||||
self.cleanup.append(self.project)
|
||||
|
||||
# Cleanup accounts created
|
||||
self.cleanup.append(self.child_do_admin)
|
||||
self.cleanup.append(self.child_domain)
|
||||
except Exception as e:
|
||||
return [FAIL, e]
|
||||
return [PASS, None]
|
||||
|
||||
def updatePrimaryStorageLimits(self, accountLimit=None, domainLimit=None,
|
||||
projectLimit=None):
|
||||
|
||||
try:
|
||||
# Update resource limits for account
|
||||
if accountLimit:
|
||||
Resources.updateLimit(self.apiclient, resourcetype=10,
|
||||
max=accountLimit, account=self.child_do_admin.name,
|
||||
domainid=self.child_do_admin.domainid)
|
||||
|
||||
if projectLimit:
|
||||
Resources.updateLimit(self.apiclient, resourcetype=10,
|
||||
max=projectLimit, projectid=self.project.id)
|
||||
|
||||
if domainLimit:
|
||||
Resources.updateLimit(self.apiclient, resourcetype=10,
|
||||
max=domainLimit, domainid=self.child_domain.id)
|
||||
except Exception as e:
|
||||
return [FAIL, e]
|
||||
return [PASS, None]
|
||||
|
||||
@attr(tags=["advanced","selfservice"])
|
||||
def test_01_deploy_vm_domain_limit_reached(self):
|
||||
"""Test Try to deploy VM with admin account where account has not used
|
||||
the resources but @ domain they are not available
|
||||
|
||||
# Validate the following
|
||||
# 1. Try to deploy VM with admin account where account has not used the
|
||||
# resources but @ domain they are not available
|
||||
# 2. Deploy VM should error out saying ResourceAllocationException
|
||||
# with "resource limit exceeds"""
|
||||
|
||||
self.virtualMachine = VirtualMachine.create(self.api_client, self.services["virtual_machine"],
|
||||
accountid=self.child_do_admin.name, domainid=self.child_do_admin.domainid,
|
||||
serviceofferingid=self.service_offering.id)
|
||||
|
||||
accounts = Account.list(self.apiclient, id=self.child_do_admin.id)
|
||||
self.assertEqual(validateList(accounts)[0], PASS,
|
||||
"accounts list validation failed")
|
||||
|
||||
self.initialResourceCount = int(accounts[0].primarystoragetotal)
|
||||
domainLimit = self.initialResourceCount + 3
|
||||
|
||||
self.debug("Setting up account and domain hierarchy")
|
||||
response = self.updatePrimaryStorageLimits(domainLimit=domainLimit)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
self.services["volume"]["size"] = self.services["disk_offering"]["disksize"] = 2
|
||||
|
||||
try:
|
||||
disk_offering = DiskOffering.create(self.apiclient,
|
||||
services=self.services["disk_offering"])
|
||||
self.cleanup.append(disk_offering)
|
||||
Volume.create(self.apiclient,
|
||||
self.services["volume"],
|
||||
zoneid=self.zone.id,
|
||||
account=self.child_do_admin.name,
|
||||
domainid=self.child_do_admin.domainid,
|
||||
diskofferingid=disk_offering.id)
|
||||
except Exception as e:
|
||||
self.fail("Exception occured: %s" % e)
|
||||
|
||||
with self.assertRaises(Exception):
|
||||
Volume.create(self.apiclient,
|
||||
self.services["volume"],
|
||||
zoneid=self.zone.id,
|
||||
account=self.child_do_admin.name,
|
||||
domainid=self.child_do_admin.domainid,
|
||||
diskofferingid=disk_offering.id)
|
||||
return
|
||||
|
||||
@attr(tags=["advanced","selfservice"])
|
||||
def test_02_deploy_vm_account_limit_reached(self):
|
||||
"""Test Try to deploy VM with admin account where account has used
|
||||
the resources but @ domain they are available"""
|
||||
|
||||
self.virtualMachine = VirtualMachine.create(self.api_client, self.services["virtual_machine"],
|
||||
accountid=self.child_do_admin.name, domainid=self.child_do_admin.domainid,
|
||||
diskofferingid=self.disk_offering.id,
|
||||
serviceofferingid=self.service_offering.id)
|
||||
|
||||
accounts = Account.list(self.apiclient, id=self.child_do_admin.id)
|
||||
self.assertEqual(validateList(accounts)[0], PASS,
|
||||
"accounts list validation failed")
|
||||
|
||||
self.initialResourceCount = int(accounts[0].primarystoragetotal)
|
||||
accountLimit = self.initialResourceCount + 3
|
||||
|
||||
self.debug("Setting up account and domain hierarchy")
|
||||
response = self.updatePrimaryStorageLimits(accountLimit=accountLimit)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
self.services["volume"]["size"] = self.services["disk_offering"]["disksize"] = 2
|
||||
|
||||
try:
|
||||
disk_offering = DiskOffering.create(self.apiclient,
|
||||
services=self.services["disk_offering"])
|
||||
self.cleanup.append(disk_offering)
|
||||
Volume.create(self.apiclient,
|
||||
self.services["volume"],
|
||||
zoneid=self.zone.id,
|
||||
account=self.child_do_admin.name,
|
||||
domainid=self.child_do_admin.domainid,
|
||||
diskofferingid=disk_offering.id)
|
||||
except Exception as e:
|
||||
self.fail("failed to create volume: %s" % e)
|
||||
|
||||
with self.assertRaises(Exception):
|
||||
Volume.create(self.apiclient,
|
||||
self.services["volume"],
|
||||
zoneid=self.zone.id,
|
||||
account=self.child_do_admin.name,
|
||||
domainid=self.child_do_admin.domainid,
|
||||
diskofferingid=disk_offering.id)
|
||||
return
|
||||
|
||||
@attr(tags=["advanced","selfservice"])
|
||||
def test_03_deploy_vm_project_limit_reached(self):
|
||||
"""Test TTry to deploy VM with admin account where account has not used
|
||||
the resources but @ project they are not available
|
||||
|
||||
# Validate the following
|
||||
# 1. Try to deploy VM with admin account where account has not used the
|
||||
# resources but @ project they are not available
|
||||
# 2. Deploy VM should error out saying ResourceAllocationException
|
||||
# with "resource limit exceeds"""
|
||||
|
||||
self.virtualMachine = VirtualMachine.create(self.api_client, self.services["virtual_machine"],
|
||||
projectid=self.project.id,
|
||||
diskofferingid=self.disk_offering.id,
|
||||
serviceofferingid=self.service_offering.id)
|
||||
|
||||
try:
|
||||
projects = Project.list(self.apiclient, id=self.project.id, listall=True)
|
||||
except Exception as e:
|
||||
self.fail("failed to get projects list: %s" % e)
|
||||
|
||||
self.assertEqual(validateList(projects)[0], PASS,
|
||||
"projects list validation failed")
|
||||
self.initialResourceCount = int(projects[0].primarystoragetotal)
|
||||
|
||||
projectLimit = self.initialResourceCount + 3
|
||||
|
||||
self.debug("Setting up account and domain hierarchy")
|
||||
response = self.updatePrimaryStorageLimits(projectLimit=projectLimit)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
self.services["volume"]["size"] = self.services["disk_offering"]["disksize"] = 2
|
||||
|
||||
try:
|
||||
disk_offering = DiskOffering.create(self.apiclient,
|
||||
services=self.services["disk_offering"])
|
||||
self.cleanup.append(disk_offering)
|
||||
Volume.create(self.apiclient,
|
||||
self.services["volume"],
|
||||
zoneid=self.zone.id,
|
||||
projectid=self.project.id,
|
||||
diskofferingid=disk_offering.id)
|
||||
except Exception as e:
|
||||
self.fail("Exception occured: %s" % e)
|
||||
|
||||
with self.assertRaises(Exception):
|
||||
Volume.create(self.apiclient,
|
||||
self.services["volume"],
|
||||
zoneid=self.zone.id,
|
||||
projectid=self.project.id,
|
||||
diskofferingid=disk_offering.id)
|
||||
return
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
# 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.
|
||||
|
||||
""" P1 tests for primary storage Project limits
|
||||
|
||||
Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domain+or+accounts
|
||||
|
||||
Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-1466
|
||||
|
||||
Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domains+and+accounts
|
||||
"""
|
||||
# Import Local Modules
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase, unittest
|
||||
from marvin.lib.base import (Account,
|
||||
ServiceOffering,
|
||||
VirtualMachine,
|
||||
Host,
|
||||
Domain,
|
||||
Project,
|
||||
Volume)
|
||||
from marvin.lib.common import (get_domain,
|
||||
get_zone,
|
||||
get_template,
|
||||
matchResourceCount,
|
||||
isVmExpunged)
|
||||
from marvin.lib.utils import (cleanup_resources,
|
||||
validateList)
|
||||
from marvin.codes import (PASS,
|
||||
FAIL,
|
||||
RESOURCE_PRIMARY_STORAGE)
|
||||
import time
|
||||
|
||||
class TestProjectsVolumeLimits(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cloudstackTestClient = super(TestProjectsVolumeLimits,
|
||||
cls).getClsTestClient()
|
||||
cls.api_client = cloudstackTestClient.getApiClient()
|
||||
# Fill services from the external config file
|
||||
cls.services = cloudstackTestClient.getParsedTestDataConfig()
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client)
|
||||
cls.zone = get_zone(cls.api_client, cloudstackTestClient.getZoneForTests())
|
||||
cls.services["mode"] = cls.zone.networktype
|
||||
|
||||
cls.template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostype"]
|
||||
)
|
||||
|
||||
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
cls.services["volume"]["zoneid"] = cls.zone.id
|
||||
cls._cleanup = []
|
||||
try:
|
||||
cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"])
|
||||
cls._cleanup.append(cls.service_offering)
|
||||
except Exception as e:
|
||||
cls.tearDownClass()
|
||||
raise unittest.SkipTest("Exception in setUpClass: %s" % e)
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
# Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
|
||||
self.cleanup = []
|
||||
response = self.setupProjectAccounts()
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
try:
|
||||
self.vm = VirtualMachine.create(
|
||||
self.apiclient,self.services["virtual_machine"],
|
||||
templateid=self.template.id,projectid=self.project.id,
|
||||
serviceofferingid=self.service_offering.id)
|
||||
projects = Project.list(self.apiclient,id=self.project.id, listall=True)
|
||||
self.assertEqual(validateList(projects)[0], PASS,\
|
||||
"projects list validation failed")
|
||||
self.initialResourceCount = projects[0].primarystoragetotal
|
||||
except Exception as e:
|
||||
self.tearDown()
|
||||
self.skipTest("Exception occured in setup: %s" % e)
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
# Clean up, terminate the created instance, volumes and snapshots
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
pass
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setupProjectAccounts(self):
|
||||
|
||||
try:
|
||||
self.domain = Domain.create(self.apiclient,
|
||||
services=self.services["domain"],
|
||||
parentdomainid=self.domain.id)
|
||||
self.admin = Account.create(
|
||||
self.apiclient, self.services["account"],
|
||||
admin=True, domainid=self.domain.id)
|
||||
|
||||
# Create project as a domain admin
|
||||
self.project = Project.create(
|
||||
self.apiclient,self.services["project"],
|
||||
account=self.admin.name,domainid=self.admin.domainid)
|
||||
# Cleanup created project at end of test
|
||||
self.cleanup.append(self.project)
|
||||
self.cleanup.append(self.admin)
|
||||
self.cleanup.append(self.domain)
|
||||
except Exception as e:
|
||||
return [FAIL, e]
|
||||
return [PASS, None]
|
||||
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_01_VM_start_stop(self):
|
||||
"""Test project primary storage count with VM stop/start operation
|
||||
|
||||
# Validate the following
|
||||
# 1. Create VM with custom disk offering in a project and check
|
||||
# initial primary storage count
|
||||
# 2. Stop the VM and verify primary storage count remains the same
|
||||
# 3. Start the VM and verify priamay storage count remains the same
|
||||
"""
|
||||
|
||||
try:
|
||||
self.vm.stop(self.apiclient)
|
||||
except Exception as e:
|
||||
self.fail("Faield to stop VM: %s" % e)
|
||||
|
||||
expectedCount = self.initialResourceCount
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
projectid=self.project.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
try:
|
||||
self.vm.start(self.apiclient)
|
||||
except Exception as e:
|
||||
self.fail("Failed to start VM: %s" % e)
|
||||
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
projectid=self.project.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_02_migrate_vm(self):
|
||||
"""Test migrate VM in project
|
||||
|
||||
# Validate the following
|
||||
# 1. Create VM with custom disk offering in a project and check
|
||||
# initial primary storage count
|
||||
# 2. List the hosts suitable for migrating the VM
|
||||
# 3. Migrate the VM and verify that primary storage count of project remains same"""
|
||||
|
||||
try:
|
||||
hosts = Host.list(self.apiclient,virtualmachineid=self.vm.id,
|
||||
listall=True)
|
||||
self.assertEqual(validateList(hosts)[0], PASS, "hosts list validation failed")
|
||||
host = hosts[0]
|
||||
self.vm.migrate(self.apiclient, host.id)
|
||||
except Exception as e:
|
||||
self.fail("Exception occured" % e)
|
||||
|
||||
expectedCount = self.initialResourceCount
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
projectid=self.project.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_03_delete_vm(self):
|
||||
"""Test delete VM belonging to project
|
||||
|
||||
# Validate the following
|
||||
# 1. Create VM with custom disk offering in a project and check
|
||||
# initial primary storage count
|
||||
# 2. Delete VM and verify that it's expunged
|
||||
# 3. Verify that primary storage count of project equals 0"""
|
||||
|
||||
try:
|
||||
self.vm.delete(self.apiclient)
|
||||
except Exception as e:
|
||||
self.fail("Failed to detroy VM: %s" % e)
|
||||
|
||||
self.assertTrue(isVmExpunged(self.apiclient, self.vm.id, self.project.id),\
|
||||
"VM not expunged")
|
||||
|
||||
totalallottedtime = timeout = 600
|
||||
while timeout >= 0:
|
||||
volumes = Volume.list(self.apiclient, projectid=self.project.id, listall=True)
|
||||
if volumes is None:
|
||||
break
|
||||
if timeout == 0:
|
||||
self.fail("Volume attached to VM not cleaned up even\
|
||||
after %s seconds" % totalallottedtime)
|
||||
timeout -= 60
|
||||
time.sleep(60)
|
||||
|
||||
expectedCount = 0
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
projectid=self.project.id)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
return
|
||||
|
|
@ -0,0 +1,339 @@
|
|||
# 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.
|
||||
|
||||
""" P1 tests for testing resize volume functionality with primary storage limit constraints on
|
||||
account/domain
|
||||
|
||||
Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domain+or+accounts
|
||||
|
||||
Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-1466
|
||||
|
||||
Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domains+and+accounts
|
||||
"""
|
||||
# Import Local Modules
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase, unittest
|
||||
from marvin.lib.base import (Account,
|
||||
ServiceOffering,
|
||||
VirtualMachine,
|
||||
Resources,
|
||||
Domain,
|
||||
DiskOffering,
|
||||
Volume)
|
||||
from marvin.lib.common import (get_domain,
|
||||
get_zone,
|
||||
get_template,
|
||||
matchResourceCount,
|
||||
isDomainResourceCountEqualToExpectedCount)
|
||||
from marvin.lib.utils import (cleanup_resources,
|
||||
get_hypervisor_type)
|
||||
from marvin.codes import (PASS,
|
||||
FAIL,
|
||||
FAILED,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
RESOURCE_SECONDARY_STORAGE,
|
||||
XEN_SERVER)
|
||||
|
||||
class TestResizeVolume(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cloudstackTestClient = super(TestResizeVolume,
|
||||
cls).getClsTestClient()
|
||||
cls.api_client = cloudstackTestClient.getApiClient()
|
||||
# Fill services from the external config file
|
||||
cls.services = cloudstackTestClient.getParsedTestDataConfig()
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client)
|
||||
cls.zone = get_zone(cls.api_client, cloudstackTestClient.getZoneForTests())
|
||||
cls.services["mode"] = cls.zone.networktype
|
||||
cls.resourcetypemapping = {RESOURCE_PRIMARY_STORAGE: 10,
|
||||
RESOURCE_SECONDARY_STORAGE: 11}
|
||||
|
||||
cls.template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostype"]
|
||||
)
|
||||
|
||||
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
cls.services["virtual_machine"]["template"] = cls.template.id
|
||||
cls.services["volume"]["zoneid"] = cls.zone.id
|
||||
|
||||
cls._cleanup = []
|
||||
try:
|
||||
cls.hypervisor = str(get_hypervisor_type(cls.api_client)).lower()
|
||||
|
||||
# Creating service offering with normal config
|
||||
cls.service_offering = ServiceOffering.create(cls.api_client,
|
||||
cls.services["service_offering"])
|
||||
cls._cleanup.append(cls.service_offering)
|
||||
|
||||
cls.services["disk_offering"]["disksize"] = 5
|
||||
cls.disk_offering_5_GB = DiskOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["disk_offering"]
|
||||
)
|
||||
cls._cleanup.append(cls.disk_offering_5_GB)
|
||||
|
||||
cls.services["disk_offering"]["disksize"] = 20
|
||||
cls.disk_offering_20_GB = DiskOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["disk_offering"]
|
||||
)
|
||||
cls._cleanup.append(cls.disk_offering_20_GB)
|
||||
except Exception as e:
|
||||
cls.tearDownClass()
|
||||
raise unittest.SkipTest("Failure while creating disk offering: %s" % e)
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
# Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
# Clean up, terminate the created instance, volumes and snapshots
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
pass
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def updateResourceLimits(self, accountLimit=None, domainLimit=None):
|
||||
"""Update primary storage limits of the parent domain and its
|
||||
child domains"""
|
||||
|
||||
try:
|
||||
if domainLimit:
|
||||
#Update resource limit for domain
|
||||
Resources.updateLimit(self.apiclient, resourcetype=10,
|
||||
max=domainLimit,
|
||||
domainid=self.parent_domain.id)
|
||||
if accountLimit:
|
||||
#Update resource limit for domain
|
||||
Resources.updateLimit(self.apiclient, resourcetype=10,
|
||||
max=accountLimit, account=self.parentd_admin.name,
|
||||
domainid=self.parent_domain.id)
|
||||
except Exception as e:
|
||||
return [FAIL, e]
|
||||
return [PASS, None]
|
||||
|
||||
def setupAccounts(self):
|
||||
try:
|
||||
self.parent_domain = Domain.create(self.apiclient,
|
||||
services=self.services["domain"],
|
||||
parentdomainid=self.domain.id)
|
||||
self.parentd_admin = Account.create(self.apiclient, self.services["account"],
|
||||
admin=True, domainid=self.parent_domain.id)
|
||||
|
||||
# Cleanup the resources created at end of test
|
||||
self.cleanup.append(self.parentd_admin)
|
||||
self.cleanup.append(self.parent_domain)
|
||||
except Exception as e:
|
||||
return [FAIL, e]
|
||||
return [PASS, None]
|
||||
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_01_increase_volume_size_within_account_limit(self):
|
||||
"""Test increasing volume size within the account limit and verify primary storage usage
|
||||
|
||||
# Validate the following
|
||||
# 1. Create a domain and its admin account
|
||||
# 2. Set account primary storage limit well beyond (20 GB volume + template size of VM)
|
||||
# 3. Deploy a VM without any disk offering (only root disk)
|
||||
# 4. Create a volume of 5 GB in the account and attach it to the VM
|
||||
# 5. Increase (resize) the volume to 20 GB
|
||||
# 6. Resize opearation should be successful and primary storage counnt for
|
||||
# account should be updated successfully"""
|
||||
|
||||
# Setting up account and domain hierarchy
|
||||
result = self.setupAccounts()
|
||||
self.assertEqual(result[0], PASS, result[1])
|
||||
|
||||
apiclient = self.testClient.getUserApiClient(
|
||||
UserName=self.parentd_admin.name,
|
||||
DomainName=self.parentd_admin.domain)
|
||||
self.assertNotEqual(apiclient, FAILED, "Failed to get api client\
|
||||
of account: %s" % self.parentd_admin.name)
|
||||
|
||||
templateSize = (self.template.size / (1024**3))
|
||||
accountLimit = (templateSize + self.disk_offering_20_GB.disksize)
|
||||
response = self.updateResourceLimits(accountLimit=accountLimit)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
try:
|
||||
virtualMachine = VirtualMachine.create(
|
||||
apiclient, self.services["virtual_machine"],
|
||||
accountid=self.parentd_admin.name, domainid=self.parent_domain.id,
|
||||
serviceofferingid=self.service_offering.id
|
||||
)
|
||||
|
||||
volume = Volume.create(
|
||||
apiclient,self.services["volume"],zoneid=self.zone.id,
|
||||
account=self.parentd_admin.name,domainid=self.parent_domain.id,
|
||||
diskofferingid=self.disk_offering_5_GB.id)
|
||||
|
||||
virtualMachine.attach_volume(apiclient, volume=volume)
|
||||
|
||||
expectedCount = (templateSize + self.disk_offering_5_GB.disksize)
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.parentd_admin.id)
|
||||
if response[0] == FAIL:
|
||||
raise Exception(response[1])
|
||||
|
||||
if self.hypervisor == str(XEN_SERVER).lower():
|
||||
virtualMachine.stop(self.apiclient)
|
||||
volume.resize(apiclient, diskofferingid=self.disk_offering_20_GB.id)
|
||||
|
||||
expectedCount = (templateSize + self.disk_offering_20_GB.disksize)
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.parentd_admin.id)
|
||||
if response[0] == FAIL:
|
||||
raise Exception(response[1])
|
||||
except Exception as e:
|
||||
self.fail("Failed with exception: %s" % e)
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_02_increase_volume_size_above_account_limit(self):
|
||||
"""Test increasing volume size above the account limit
|
||||
|
||||
# Validate the following
|
||||
# 1. Create a domain and its admin account
|
||||
# 2. Set account primary storage limit more than (5 GB volume + template size of VM)
|
||||
# and less than (20 GB volume+ template size of VM)
|
||||
# 3. Deploy a VM without any disk offering (only root disk)
|
||||
# 4. Create a volume of 5 GB in the account and attach it to the VM
|
||||
# 5. Try to (resize) the volume to 20 GB
|
||||
# 6. Resize opearation should fail"""
|
||||
|
||||
# Setting up account and domain hierarchy
|
||||
result = self.setupAccounts()
|
||||
self.assertEqual(result[0], PASS, result[1])
|
||||
|
||||
templateSize = (self.template.size / (1024**3))
|
||||
accountLimit = ((templateSize + self.disk_offering_20_GB.disksize) - 1)
|
||||
response = self.updateResourceLimits(accountLimit=accountLimit)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
apiclient = self.testClient.getUserApiClient(
|
||||
UserName=self.parentd_admin.name,
|
||||
DomainName=self.parentd_admin.domain)
|
||||
self.assertNotEqual(apiclient, FAILED, "Failed to get api client\
|
||||
of account: %s" % self.parentd_admin.name)
|
||||
|
||||
try:
|
||||
virtualMachine = VirtualMachine.create(
|
||||
apiclient, self.services["virtual_machine"],
|
||||
accountid=self.parentd_admin.name, domainid=self.parent_domain.id,
|
||||
serviceofferingid=self.service_offering.id
|
||||
)
|
||||
|
||||
volume = Volume.create(
|
||||
apiclient,self.services["volume"],zoneid=self.zone.id,
|
||||
account=self.parentd_admin.name,domainid=self.parent_domain.id,
|
||||
diskofferingid=self.disk_offering_5_GB.id)
|
||||
|
||||
virtualMachine.attach_volume(apiclient, volume=volume)
|
||||
|
||||
expectedCount = (templateSize + self.disk_offering_5_GB.disksize)
|
||||
response = matchResourceCount(
|
||||
self.apiclient, expectedCount,
|
||||
RESOURCE_PRIMARY_STORAGE,
|
||||
accountid=self.parentd_admin.id)
|
||||
if response[0] == FAIL:
|
||||
raise Exception(response[1])
|
||||
except Exception as e:
|
||||
self.fail("Failed with exception: %s" % e)
|
||||
|
||||
if self.hypervisor == str(XEN_SERVER).lower():
|
||||
virtualMachine.stop(self.apiclient)
|
||||
with self.assertRaises(Exception):
|
||||
volume.resize(apiclient, diskofferingid=self.disk_offering_20_GB.id)
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "selfservice"])
|
||||
def test_03_increase_volume_size_above_domain_limit(self):
|
||||
"""Test increasing volume size above the domain limit
|
||||
|
||||
# Validate the following
|
||||
# 1. Create a domain and its admin account
|
||||
# 2. Set domain primary storage limit more than (5 GB volume + template size of VM)
|
||||
# and less than (20 GB volume+ template size of VM)
|
||||
# 3. Deploy a VM without any disk offering (only root disk)
|
||||
# 4. Create a volume of 5 GB in the account and attach it to the VM
|
||||
# 5. Try to (resize) the volume to 20 GB
|
||||
# 6. Resize opearation should fail"""
|
||||
|
||||
# Setting up account and domain hierarchy
|
||||
result = self.setupAccounts()
|
||||
self.assertEqual(result[0], PASS, result[1])
|
||||
|
||||
templateSize = (self.template.size / (1024**3))
|
||||
domainLimit = ((templateSize + self.disk_offering_20_GB.disksize) - 1)
|
||||
response = self.updateResourceLimits(domainLimit=domainLimit)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
apiclient = self.testClient.getUserApiClient(
|
||||
UserName=self.parentd_admin.name,
|
||||
DomainName=self.parentd_admin.domain)
|
||||
self.assertNotEqual(apiclient, FAILED, "Failed to get api client\
|
||||
of account: %s" % self.parentd_admin.name)
|
||||
|
||||
try:
|
||||
virtualMachine = VirtualMachine.create(
|
||||
apiclient, self.services["virtual_machine"],
|
||||
accountid=self.parentd_admin.name, domainid=self.parent_domain.id,
|
||||
serviceofferingid=self.service_offering.id
|
||||
)
|
||||
|
||||
volume = Volume.create(
|
||||
apiclient,self.services["volume"],zoneid=self.zone.id,
|
||||
account=self.parentd_admin.name,domainid=self.parent_domain.id,
|
||||
diskofferingid=self.disk_offering_5_GB.id)
|
||||
|
||||
virtualMachine.attach_volume(apiclient, volume=volume)
|
||||
|
||||
expectedCount = (templateSize + self.disk_offering_5_GB.disksize)
|
||||
result = isDomainResourceCountEqualToExpectedCount(
|
||||
self.apiclient, self.parent_domain.id,
|
||||
expectedCount, RESOURCE_PRIMARY_STORAGE)
|
||||
self.assertFalse(result[0], result[1])
|
||||
self.assertTrue(result[2], "Resource count does not match")
|
||||
except Exception as e:
|
||||
self.fail("Failed with exception: %s" % e)
|
||||
|
||||
if self.hypervisor == str(XEN_SERVER).lower():
|
||||
virtualMachine.stop(self.apiclient)
|
||||
with self.assertRaises(Exception):
|
||||
volume.resize(apiclient, diskofferingid=self.disk_offering_20_GB.id)
|
||||
return
|
||||
|
|
@ -30,12 +30,28 @@
|
|||
@DateAdded: 20th October 2013
|
||||
"""
|
||||
|
||||
'''
|
||||
VM STATES - START
|
||||
'''
|
||||
RUNNING = "Running"
|
||||
STOPPED = "Stopped"
|
||||
STOPPING = "Stopping"
|
||||
STARTING = "Starting"
|
||||
DESTROYED = "Destroyed"
|
||||
EXPUNGING = "Expunging"
|
||||
'''
|
||||
VM STATES - END
|
||||
'''
|
||||
|
||||
'''
|
||||
Snapshot States - START
|
||||
'''
|
||||
BACKED_UP = "backedup"
|
||||
BACKING_UP = "backingup"
|
||||
'''
|
||||
Snapshot States - END
|
||||
'''
|
||||
|
||||
RECURRING = "RECURRING"
|
||||
ENABLED = "Enabled"
|
||||
NETWORK_OFFERING = "network_offering"
|
||||
|
|
@ -81,3 +97,11 @@ USER = 0
|
|||
XEN_SERVER = "XenServer"
|
||||
ADMIN_ACCOUNT = 'ADMIN_ACCOUNT'
|
||||
USER_ACCOUNT = 'USER_ACCOUNT'
|
||||
RESOURCE_CPU = 8
|
||||
RESOURCE_MEMORY = 9
|
||||
RESOURCE_PRIMARY_STORAGE = 10
|
||||
RESOURCE_SECONDARY_STORAGE = 11
|
||||
KVM = "kvm"
|
||||
VMWARE = "vmware"
|
||||
ROOT_DOMAIN_ADMIN="root domain admin"
|
||||
CHILD_DOMAIN_ADMIN="child domain admin"
|
||||
|
|
|
|||
|
|
@ -20,11 +20,10 @@
|
|||
"""
|
||||
|
||||
import marvin
|
||||
from utils import is_server_ssh_ready, random_gen
|
||||
from marvin.cloudstackAPI import *
|
||||
from marvin.codes import (FAILED, FAIL, PASS, RUNNING, STOPPED,
|
||||
STARTING, DESTROYED, EXPUNGING,
|
||||
STOPPING)
|
||||
STOPPING, BACKED_UP, BACKING_UP)
|
||||
from marvin.cloudstackException import GetDetailExceptionInfo
|
||||
from marvin.lib.utils import validateList, is_server_ssh_ready, random_gen
|
||||
# Import System modules
|
||||
|
|
@ -946,6 +945,12 @@ class Volume:
|
|||
class Snapshot:
|
||||
"""Manage Snapshot Lifecycle
|
||||
"""
|
||||
'''Class level variables'''
|
||||
# Variables denoting possible Snapshot states - start
|
||||
BACKED_UP = BACKED_UP
|
||||
BACKING_UP = BACKING_UP
|
||||
# Variables denoting possible Snapshot states - end
|
||||
|
||||
def __init__(self, items):
|
||||
self.__dict__.update(items)
|
||||
|
||||
|
|
@ -979,6 +984,31 @@ class Snapshot:
|
|||
cmd.listall = True
|
||||
return(apiclient.listSnapshots(cmd))
|
||||
|
||||
def validateState(self, apiclient, snapshotstate, timeout=600):
|
||||
"""Check if snapshot is in required state
|
||||
returnValue: List[Result, Reason]
|
||||
@Result: PASS if snapshot is in required state,
|
||||
else FAIL
|
||||
@Reason: Reason for failure in case Result is FAIL
|
||||
"""
|
||||
isSnapshotInRequiredState = False
|
||||
try:
|
||||
while timeout >= 0:
|
||||
snapshots = Snapshot.list(apiclient, id=self.id)
|
||||
assert validateList(snapshots)[0] == PASS, "snapshots list\
|
||||
validation failed"
|
||||
if str(snapshots[0].state).lower() == snapshotstate:
|
||||
isSnapshotInRequiredState = True
|
||||
break
|
||||
timeout -= 60
|
||||
time.sleep(60)
|
||||
#end while
|
||||
if isSnapshotInRequiredState:
|
||||
return[PASS, None]
|
||||
else:
|
||||
raise Exception("Snapshot not in required state")
|
||||
except Exception as e:
|
||||
return [FAIL, e]
|
||||
|
||||
class Template:
|
||||
"""Manage template life cycle"""
|
||||
|
|
|
|||
|
|
@ -62,12 +62,29 @@ from marvin.cloudstackAPI import (listConfigurations,
|
|||
|
||||
|
||||
from marvin.sshClient import SshClient
|
||||
from marvin.codes import (PASS, ISOLATED_NETWORK, VPC_NETWORK,
|
||||
BASIC_ZONE, FAIL, NAT_RULE, STATIC_NAT_RULE, FAILED)
|
||||
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_CPU, RESOURCE_MEMORY)
|
||||
from marvin.lib.utils import (validateList, xsplit, get_process_status)
|
||||
from marvin.lib.base import (PhysicalNetwork,
|
||||
PublicIPAddress,
|
||||
NetworkOffering,
|
||||
NATRule,
|
||||
StaticNATRule,
|
||||
Volume,
|
||||
Account,
|
||||
Project,
|
||||
Snapshot,
|
||||
NetScaler,
|
||||
VirtualMachine,
|
||||
FireWallRule,
|
||||
Template,
|
||||
Network,
|
||||
Host,
|
||||
Resources,
|
||||
Configurations)
|
||||
import random
|
||||
from marvin.lib.utils import *
|
||||
from marvin.lib.base import *
|
||||
from marvin.codes import PASS
|
||||
|
||||
|
||||
# Import System modules
|
||||
|
|
@ -1182,3 +1199,111 @@ def getPortableIpRangeServices(config):
|
|||
services = FAILED
|
||||
|
||||
return services
|
||||
|
||||
|
||||
def uploadVolume(apiclient, zoneid, account, services):
|
||||
try:
|
||||
# Upload the volume
|
||||
volume = Volume.upload(apiclient, services["volume"],
|
||||
zoneid=zoneid, account=account.name,
|
||||
domainid=account.domainid, url=services["url"])
|
||||
|
||||
volume.wait_for_upload(apiclient)
|
||||
|
||||
# Check List Volume response for newly created volume
|
||||
volumes = Volume.list(apiclient, id=volume.id,
|
||||
zoneid=zoneid, listall=True)
|
||||
validationresult = validateList(volumes)
|
||||
assert validationresult[0] == PASS,\
|
||||
"volumes list validation failed: %s" % validationresult[2]
|
||||
assert str(volumes[0].state).lower() == "uploaded",\
|
||||
"Volume state should be 'uploaded' but it is %s" % volumes[0].state
|
||||
except Exception as e:
|
||||
return [FAIL, e]
|
||||
return [PASS, volume]
|
||||
|
||||
def matchResourceCount(apiclient, expectedCount, resourceType,
|
||||
accountid=None, projectid=None):
|
||||
"""Match the resource count of account/project with the expected
|
||||
resource count"""
|
||||
try:
|
||||
resourceholderlist = None
|
||||
if accountid:
|
||||
resourceholderlist = Account.list(apiclient, id=accountid)
|
||||
elif projectid:
|
||||
resourceholderlist = Project.list(apiclient, id=projectid, listall=True)
|
||||
validationresult = validateList(resourceholderlist)
|
||||
assert validationresult[0] == PASS,\
|
||||
"accounts list validation failed"
|
||||
if resourceType == RESOURCE_PRIMARY_STORAGE:
|
||||
resourceCount = resourceholderlist[0].primarystoragetotal
|
||||
elif resourceType == RESOURCE_SECONDARY_STORAGE:
|
||||
resourceCount = resourceholderlist[0].secondarystoragetotal
|
||||
elif resourceType == RESOURCE_CPU:
|
||||
resourceCount = resourceholderlist[0].cputotal
|
||||
elif resourceType == RESOURCE_MEMORY:
|
||||
resourceCount = resourceholderlist[0].memorytotal
|
||||
assert str(resourceCount) == str(expectedCount),\
|
||||
"Resource count %s should match with the expected resource count %s" %\
|
||||
(resourceCount, expectedCount)
|
||||
except Exception as e:
|
||||
return [FAIL, e]
|
||||
return [PASS, None]
|
||||
|
||||
def createSnapshotFromVirtualMachineVolume(apiclient, account, vmid):
|
||||
"""Create snapshot from volume"""
|
||||
|
||||
try:
|
||||
volumes = Volume.list(apiclient, account=account.name,
|
||||
domainid=account.domainid, virtualmachineid=vmid)
|
||||
validationresult = validateList(volumes)
|
||||
assert validateList(volumes)[0] == PASS,\
|
||||
"List volumes should return a valid response"
|
||||
snapshot = Snapshot.create(apiclient, volume_id=volumes[0].id,
|
||||
account=account.name, domainid=account.domainid)
|
||||
snapshots = Snapshot.list(apiclient, id=snapshot.id,
|
||||
listall=True)
|
||||
validationresult = validateList(snapshots)
|
||||
assert validationresult[0] == PASS,\
|
||||
"List snapshot should return a valid list"
|
||||
except Exception as e:
|
||||
return[FAIL, e]
|
||||
return [PASS, snapshot]
|
||||
|
||||
def isVmExpunged(apiclient, vmid, projectid=None, timeout=600):
|
||||
"""Verify if VM is expunged or not"""
|
||||
vmExpunged= False
|
||||
while timeout>=0:
|
||||
try:
|
||||
vms = VirtualMachine.list(apiclient, id=vmid, projectid=projectid)
|
||||
if vms is None:
|
||||
vmExpunged = True
|
||||
break
|
||||
timeout -= 60
|
||||
time.sleep(60)
|
||||
except Exception:
|
||||
vmExpunged = True
|
||||
break
|
||||
#end while
|
||||
return vmExpunged
|
||||
|
||||
def isDomainResourceCountEqualToExpectedCount(apiclient, domainid, expectedcount,
|
||||
resourcetype):
|
||||
"""Get the resource count of specific domain 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,
|
||||
resourcetype=resourcetype)
|
||||
except Exception as e:
|
||||
reasonForException = "Failed while updating resource count: %s" % e
|
||||
isExceptionOccured = True
|
||||
return [isExceptionOccured, reasonForException, isResourceCountEqual]
|
||||
|
||||
resourcecount = (response[0].resourcecount / (1024**3))
|
||||
if resourcecount == expectedcount:
|
||||
isResourceCountEqual = True
|
||||
return [isExceptionOccured, reasonForException, isResourceCountEqual]
|
||||
|
|
|
|||
Loading…
Reference in New Issue