You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2014/07/28 23:13:55 UTC
[27/50] [abbrv] git commit: updated refs/heads/4.4 to 2025f35
CLOUDSTACK-1466: Automation - Priamary Storage Limits
(cherry picked from commit a0f19d4bd5d7bec6613aa8130b3da9ecffc71d0b)
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/12b6cf1b
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/12b6cf1b
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/12b6cf1b
Branch: refs/heads/4.4
Commit: 12b6cf1be5fafe918328937d33aad5b377d9eead
Parents: f753272
Author: Gaurav Aradhye <ga...@clogeny.com>
Authored: Tue Jun 17 20:32:12 2014 -0700
Committer: Daan Hoogland <da...@onecht.net>
Committed: Mon Jul 28 23:12:49 2014 +0200
----------------------------------------------------------------------
.../component/test_ps_domain_limits.py | 690 +++++++++++++++++++
test/integration/component/test_ps_limits.py | 588 ++++++++++++++++
.../integration/component/test_ps_max_limits.py | 300 ++++++++
.../component/test_ps_project_limits.py | 238 +++++++
.../component/test_ps_resize_volume.py | 339 +++++++++
tools/marvin/marvin/codes.py | 24 +
tools/marvin/marvin/lib/base.py | 36 +-
tools/marvin/marvin/lib/common.py | 135 +++-
8 files changed, 2343 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b6cf1b/test/integration/component/test_ps_domain_limits.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_ps_domain_limits.py b/test/integration/component/test_ps_domain_limits.py
new file mode 100644
index 0000000..afb0955
--- /dev/null
+++ b/test/integration/component/test_ps_domain_limits.py
@@ -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
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b6cf1b/test/integration/component/test_ps_limits.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_ps_limits.py b/test/integration/component/test_ps_limits.py
new file mode 100644
index 0000000..1993e93
--- /dev/null
+++ b/test/integration/component/test_ps_limits.py
@@ -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
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b6cf1b/test/integration/component/test_ps_max_limits.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_ps_max_limits.py b/test/integration/component/test_ps_max_limits.py
new file mode 100644
index 0000000..8d047ef
--- /dev/null
+++ b/test/integration/component/test_ps_max_limits.py
@@ -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
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b6cf1b/test/integration/component/test_ps_project_limits.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_ps_project_limits.py b/test/integration/component/test_ps_project_limits.py
new file mode 100644
index 0000000..471b4a1
--- /dev/null
+++ b/test/integration/component/test_ps_project_limits.py
@@ -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