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