cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sanj...@apache.org
Subject git commit: updated refs/heads/master to fe6f0cf
Date Thu, 28 Aug 2014 07:10:29 GMT
Repository: cloudstack
Updated Branches:
  refs/heads/master 4c69609fa -> fe6f0cf62


CLOUDSTACK-1466: Automation - Secondary Storage Test Cases


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/fe6f0cf6
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/fe6f0cf6
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/fe6f0cf6

Branch: refs/heads/master
Commit: fe6f0cf6268dc299984c1dfef6e9d807cdd8d796
Parents: 4c69609
Author: Ashutosh K <ashutosh@clogeny.com>
Authored: Tue Jun 17 01:07:35 2014 -0700
Committer: sanjeev <sanjeev@apache.org>
Committed: Thu Aug 28 12:39:41 2014 +0530

----------------------------------------------------------------------
 .../component/test_ss_domain_limits.py          | 580 +++++++++++++++++++
 test/integration/component/test_ss_limits.py    | 377 ++++++++++++
 .../integration/component/test_ss_max_limits.py | 279 +++++++++
 .../component/test_ss_project_limits.py         | 262 +++++++++
 tools/marvin/marvin/config/test_data.py         |   1 +
 tools/marvin/marvin/lib/base.py                 |   8 +-
 6 files changed, 1506 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fe6f0cf6/test/integration/component/test_ss_domain_limits.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_ss_domain_limits.py b/test/integration/component/test_ss_domain_limits.py
new file mode 100644
index 0000000..998bb8b
--- /dev/null
+++ b/test/integration/component/test_ss_domain_limits.py
@@ -0,0 +1,580 @@
+# 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 secondary 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
+from marvin.lib.base import (Account,
+                             Resources,
+                             Domain,
+                             Template)
+from marvin.lib.common import (get_domain,
+                               get_zone,
+                               get_template,
+                               get_builtin_template_info,
+                               list_zones,
+                               isDomainResourceCountEqualToExpectedCount)
+from marvin.lib.utils import (cleanup_resources, validateList)
+from marvin.codes import (PASS,
+                          FAIL,
+                          RESOURCE_SECONDARY_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._cleanup = []
+        return
+
+    @classmethod
+    def tearDownClass(cls):
+        try:
+            # Cleanup resources used
+            cleanup_resources(cls.api_client, cls._cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.dbclient = self.testClient.getDbConnection()
+        self.cleanup = []
+        return
+
+    def tearDown(self):
+        try:
+            # Clean up, terminate the created instance, volumes and snapshots
+            cleanup_resources(self.apiclient, self.cleanup)
+            pass
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    def updateDomainResourceLimits(self, parentdomainlimit, subdomainlimit):
+        """Update secondary storage limits of the parent domain and its
+        child domains"""
+
+        try:
+            #Update resource limit for domain
+            Resources.updateLimit(self.apiclient, resourcetype=11,
+                              max=parentdomainlimit,
+                              domainid=self.parent_domain.id)
+
+            # Update Resource limit for sub-domains
+            Resources.updateLimit(self.apiclient, resourcetype=11,
+                              max=subdomainlimit,
+                              domainid=self.cadmin_1.domainid)
+
+            Resources.updateLimit(self.apiclient, resourcetype=11,
+                              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"], required_hardware="false")
+    def test_01_multiple_domains_secondary_storage_limits(self):
+        """Test secondary 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. Register template in child domain 1 so that total secondary storage
+           is less than the limit of child domain
+        3. Set the child domain limit equal to template size and parent domain
+           domain limit as double of the template size
+        4. Repeat step 2 for child domain 2
+        5. Try to register template in parent domain now so that the total secondary storage in
+           parent domain (including that in sub-domains is more than the secondary
+           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 template in account 2 and check secondary storage count
+           of parent domain
+
+        # Validations:
+        1. Step 2 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, result[1])
+
+        try:
+            builtin_info = get_builtin_template_info(self.apiclient, self.zone.id)
+            self.services["template_2"]["url"] = builtin_info[0]
+            self.services["template_2"]["hypervisor"] = builtin_info[1]
+            self.services["template_2"]["format"] = builtin_info[2]
+
+            templateChildAccount1 = Template.register(self.apiclient,
+                                     self.services["template_2"],
+                                     zoneid=self.zone.id,
+                                     account=self.cadmin_1.name,
+                                     domainid=self.cadmin_1.domainid)
+
+            templateChildAccount1.download(self.apiclient)
+
+            templates = Template.list(self.apiclient,
+                                      templatefilter=\
+                                      self.services["template_2"]["templatefilter"],
+                                      id=templateChildAccount1.id)
+            if validateList(templates)[0] == FAIL:
+                raise Exception("templates list validation failed")
+
+            self.templateSize = int(int(templates[0].size) / (1024**3))
+        except Exception as e:
+            self.fail("Failed with exception as ee: %s" % e)
+
+        subdomainlimit = (self.templateSize)
+
+        result = self.updateDomainResourceLimits(((subdomainlimit*2)), subdomainlimit)
+        self.assertEqual(result[0], PASS, result[1])
+
+        # Checking Primary Storage count of Parent domain admin before deleting child domain user account
+        result = isDomainResourceCountEqualToExpectedCount(
+                        self.apiclient, self.cadmin_1.domainid,
+                        self.templateSize, RESOURCE_SECONDARY_STORAGE)
+        self.assertFalse(result[0], result[1])
+        self.assertTrue(result[2], "Resource count does not match")
+
+        try:
+            templateChildAccount2 = Template.register(self.apiclient,
+                                     self.services["template_2"],
+                                     zoneid=self.zone.id,
+                                     account=self.cadmin_2.name,
+                                     domainid=self.cadmin_2.domainid)
+
+            templateChildAccount2.download(self.apiclient)
+        except Exception as e:
+            self.fail("Failed while registering/downloading template: %s" % e)
+
+        result = isDomainResourceCountEqualToExpectedCount(
+                        self.apiclient, self.cadmin_2.domainid,
+                        self.templateSize, RESOURCE_SECONDARY_STORAGE)
+        self.assertFalse(result[0], result[1])
+        self.assertTrue(result[2], "Resource count does not match")
+
+        with self.assertRaises(Exception):
+            Template.register(self.apiclient,
+                                     self.services["template_2"],
+                                     zoneid=self.zone.id,
+                                     account=self.parentd_admin.name,
+                                     domainid=self.parentd_admin.domainid)
+
+        self.cadmin_1.delete(self.apiclient)
+        self.cleanup.remove(self.cadmin_1)
+
+        result = isDomainResourceCountEqualToExpectedCount(
+                        self.apiclient, self.parent_domain.id,
+                        self.templateSize, RESOURCE_SECONDARY_STORAGE)
+        self.assertFalse(result[0], result[1])
+        self.assertTrue(result[2], "Resource count does not match")
+
+        try:
+            templateChildAccount2.delete(self.apiclient)
+        except Exception as e:
+            self.fail("Failed to delete template: %s" % e)
+
+        result = isDomainResourceCountEqualToExpectedCount(
+                        self.apiclient, self.parent_domain.id,
+                        0, RESOURCE_SECONDARY_STORAGE)
+        self.assertFalse(result[0], result[1])
+        self.assertTrue(result[2], "Resource count does not match")
+        return
+
+    @attr(tags=["advanced"], required_hardware="false")
+    def test_02_multiple_domains_secondary_storage_counts(self):
+        """Test secondary 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. Register template in child domain
+        3. Check if the resource count for domain is updated correctly
+        4. Delete the template
+        5. Verify that the resource count for the domain is 0
+
+        """
+        users = None
+        # 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:
+                builtin_info = get_builtin_template_info(self.apiclient, self.zone.id)
+                self.services["template_2"]["url"] = builtin_info[0]
+                self.services["template_2"]["hypervisor"] = builtin_info[1]
+                self.services["template_2"]["format"] = builtin_info[2]
+
+                template = Template.register(self.apiclient,
+                                     self.services["template_2"],
+                                     zoneid=self.zone.id,
+                                     account=self.account.name,
+                                     domainid=self.account.domainid)
+
+                template.download(self.apiclient)
+
+                templates = Template.list(self.apiclient,
+                                      templatefilter=\
+                                      self.services["template_2"]["templatefilter"],
+                                      id=template.id)
+                if validateList(templates)[0] == FAIL:
+                    raise Exception("templates list validation failed")
+
+                templateSize = int(int(templates[0].size) / (1024**3))
+                expectedCount = templateSize
+                result = isDomainResourceCountEqualToExpectedCount(
+                                    self.apiclient, self.domain.id,
+                                    expectedCount, RESOURCE_SECONDARY_STORAGE)
+                self.assertFalse(result[0], result[1])
+                self.assertTrue(result[2], "Resource count does not match")
+
+                template.delete(self.apiclient)
+
+                expectedCount = 0
+                result = isDomainResourceCountEqualToExpectedCount(
+                                    self.apiclient, self.domain.id,
+                                    expectedCount, RESOURCE_SECONDARY_STORAGE)
+                self.assertFalse(result[0], result[1])
+                self.assertTrue(result[2], "Resource count does not match")
+            except Exception as e:
+                self.fail("Failed to get zone list: %s" % e)
+	    return
+
+    @attr(tags=["advanced"], required_hardware="false")
+    def test_03_copy_template(self):
+        """Test secondary 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. Register template in child domain
+        3. Check if the resource count for domain is updated correctly
+        4. Copy template to other zone
+        5. Verify that secondary storage count for the domain is doubled
+           as there are two templates now
+        """
+
+        zones = list_zones(self.apiclient)
+        self.assertEqual(validateList(zones)[0], PASS, "zones list validation faield")
+
+        if len(zones) < 2:
+            self.skipTest("At least 2 zones should be present for this test case")
+
+        users = None
+        # 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:
+                builtin_info = get_builtin_template_info(self.apiclient, self.zone.id)
+                self.services["template_2"]["url"] = builtin_info[0]
+                self.services["template_2"]["hypervisor"] = builtin_info[1]
+                self.services["template_2"]["format"] = builtin_info[2]
+
+                template = Template.register(self.apiclient,
+                                     self.services["template_2"],
+                                     zoneid=self.zone.id,
+                                     account=self.account.name,
+                                     domainid=self.account.domainid)
+
+                template.download(self.apiclient)
+
+                templates = Template.list(self.apiclient,
+                                      templatefilter=\
+                                      self.services["template_2"]["templatefilter"],
+                                      id=template.id)
+                if validateList(templates)[0] == FAIL:
+                    raise Exception("templates list validation failed")
+
+                templateSize = int(int(templates[0].size) / (1024**3))
+                expectedCount = templateSize
+                result = isDomainResourceCountEqualToExpectedCount(
+                                    self.apiclient, self.domain.id,
+                                    expectedCount, RESOURCE_SECONDARY_STORAGE)
+                self.assertFalse(result[0], result[1])
+                self.assertTrue(result[2], "Resource count does not match")
+
+                templateDestinationZoneId = None
+                for zone in zones:
+                    if template.zoneid != zone.id :
+                        templateDestinationZoneId = zone.id
+                        break
+
+                template.copy(self.apiclient, destzoneid=templateDestinationZoneId,
+                              sourcezoneid = template.zoneid)
+
+                expectedCount *= 2
+                result = isDomainResourceCountEqualToExpectedCount(
+                                    self.apiclient, self.domain.id,
+                                    expectedCount, RESOURCE_SECONDARY_STORAGE)
+                self.assertFalse(result[0], result[1])
+                self.assertTrue(result[2], "Resource count does not match")
+            except Exception as e:
+                self.fail("Failed to get zone list: %s" % e)
+	    return
+
+class TestDeleteAccount(cloudstackTestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cloudstackTestClient = super(TestDeleteAccount,
+                               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)
+        cls.services["mode"] = cls.zone.networktype
+        cls.template = get_template(
+                            cls.api_client,
+                            cls.zone.id,
+                            cls.services["ostype"]
+                            )
+        cls._cleanup = []
+        return
+
+    @classmethod
+    def tearDownClass(cls):
+        try:
+            # Cleanup resources used
+            cleanup_resources(cls.api_client, cls._cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.dbclient = self.testClient.getDbConnection()
+        self.cleanup = []
+        return
+
+    def tearDown(self):
+        try:
+            # Clean up, terminate the created instance, volumes and snapshots
+            cleanup_resources(self.apiclient, self.cleanup)
+            pass
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    def 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_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"], required_hardware="false")
+    def test_04_create_template_delete_account(self):
+        """Test secondary 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. Register template in child domain 1
+        3. Verify that the secondary storage count for child domain 1 equals
+           the template size
+        4. Register template in child domain 2
+        5. Vreify that the seconday storage count for child domain 2 equals
+           the template size
+        6. Verify that the secondary storage count for parent domain equals
+           double of template size
+        7. Delete child domain 1 admin account
+        8. Verify that secondary storage count for parent domain now equals
+           to only 1 template size
+        """
+
+        # Setting up account and domain hierarchy
+        result = self.setupAccounts()
+        self.assertEqual(result[0], PASS, result[1])
+
+        try:
+            builtin_info = get_builtin_template_info(self.apiclient, self.zone.id)
+            self.services["template_2"]["url"] = builtin_info[0]
+            self.services["template_2"]["hypervisor"] = builtin_info[1]
+            self.services["template_2"]["format"] = builtin_info[2]
+
+            template = Template.register(self.apiclient,
+                                     self.services["template_2"],
+                                     zoneid=self.zone.id,
+                                     account=self.cadmin_1.name,
+                                     domainid=self.cadmin_1.domainid)
+
+            template.download(self.apiclient)
+
+            templates = Template.list(self.apiclient,
+                                      templatefilter=\
+                                      self.services["template_2"]["templatefilter"],
+                                      id=template.id)
+            if validateList(templates)[0] == FAIL:
+                raise Exception("templates list validation failed")
+
+            self.templateSize = int(int(templates[0].size) / (1024**3))
+        except Exception as e:
+            self.fail("Failed with exception as ee: %s" % e)
+
+        # Checking Primary Storage count of Parent domain admin before deleting child domain user account
+        expectedCount = self.templateSize
+        result = isDomainResourceCountEqualToExpectedCount(
+                                    self.apiclient, self.cadmin_1.domainid,
+                                    expectedCount, RESOURCE_SECONDARY_STORAGE)
+        self.assertFalse(result[0], result[1])
+        self.assertTrue(result[2], "Resource count does not match")
+
+        try:
+            template = Template.register(self.apiclient,
+                                     self.services["template_2"],
+                                     zoneid=self.zone.id,
+                                     account=self.cadmin_2.name,
+                                     domainid=self.cadmin_2.domainid)
+
+            template.download(self.apiclient)
+        except Exception as e:
+            self.fail("Failed while registering/downloading template: %s" % e)
+
+        result = isDomainResourceCountEqualToExpectedCount(
+                                    self.apiclient, self.cadmin_2.domainid,
+                                    expectedCount, RESOURCE_SECONDARY_STORAGE)
+        self.assertFalse(result[0], result[1])
+        self.assertTrue(result[2], "Resource count does not match")
+
+        expectedCount *= 2
+        result = isDomainResourceCountEqualToExpectedCount(
+                                    self.apiclient, self.parent_domain.id,
+                                    expectedCount, RESOURCE_SECONDARY_STORAGE)
+        self.assertFalse(result[0], result[1])
+        self.assertTrue(result[2], "Resource count does not match")
+
+        try:
+            self.cadmin_1.delete(self.apiclient)
+        except Exception as e:
+            self.fail("Failed to delete account: %s" % e)
+
+        expectedCount /= 2
+        result = isDomainResourceCountEqualToExpectedCount(
+                                    self.apiclient, self.parent_domain.id,
+                                    expectedCount, RESOURCE_SECONDARY_STORAGE)
+        self.assertFalse(result[0], result[1])
+        self.assertTrue(result[2], "Resource count does not match")
+        return

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fe6f0cf6/test/integration/component/test_ss_limits.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_ss_limits.py b/test/integration/component/test_ss_limits.py
new file mode 100644
index 0000000..4d6efc4
--- /dev/null
+++ b/test/integration/component/test_ss_limits.py
@@ -0,0 +1,377 @@
+# 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 secondary 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,
+                             Template,
+                             Iso)
+from marvin.lib.common import (get_domain,
+                               get_zone,
+                               get_template,
+                               matchResourceCount,
+                               createSnapshotFromVirtualMachineVolume,
+                               list_zones,
+                               get_builtin_template_info)
+from marvin.lib.utils import (cleanup_resources,
+                              validateList)
+from marvin.codes import (PASS,
+                          FAIL,
+                          FAILED,
+                          RESOURCE_SECONDARY_STORAGE,
+                          CHILD_DOMAIN_ADMIN,
+                          ROOT_DOMAIN_ADMIN)
+from ddt import ddt, data
+import time
+
+@ddt
+class TestSecondaryStorageLimits(cloudstackTestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cloudstackTestClient = super(TestSecondaryStorageLimits,
+                               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.hypervisor = cloudstackTestClient.getHypervisorInfo()
+
+        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"])
+            if cls.service_offering == FAILED:
+                raise Exception("Creating service offering failed")
+        except Exception as e:
+            cls.tearDownClass()
+            raise unittest.SkipTest("Exception in setup class: %s" % e)
+        return
+
+    @classmethod
+    def tearDownClass(cls):
+        try:
+            # Cleanup resources used
+            cleanup_resources(cls.api_client, cls._cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.dbclient = self.testClient.getDbConnection()
+        self.cleanup = []
+        return
+
+    def tearDown(self):
+        try:
+            # Clean up, terminate the created instance, volumes and snapshots
+            cleanup_resources(self.apiclient, self.cleanup)
+            pass
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    def 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)
+        except Exception as e:
+            return [FAIL, e]
+        return [PASS, None]
+
+    @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
+    @attr(tags = ["advanced"], required_hardware="false")
+    def test_01_register_template(self, value):
+        """Test register template
+        # Validate the following:
+        1. Create a root domain admin/ child domain admin account
+        2. Register and download a template according to hypervisor type
+        3. Verify that the template is listed
+        4. Verify that the secondary storage count for the account equals the size
+           of the template
+        5. Delete the template
+        6. Verify that the secondary storage resource count of the account equals 0
+       """
+        response = self.setupAccount(value)
+        self.assertEqual(response[0], PASS, response[1])
+
+        builtin_info = get_builtin_template_info(self.apiclient, self.zone.id)
+        self.services["template_2"]["url"] = builtin_info[0]
+        self.services["template_2"]["hypervisor"] = builtin_info[1]
+        self.services["template_2"]["format"] = builtin_info[2]
+
+        try:
+            template = Template.register(self.apiclient,
+                                     self.services["template_2"],
+                                     zoneid=self.zone.id,
+                                     account=self.account.name,
+                                     domainid=self.account.domainid,
+                                     hypervisor=self.hypervisor)
+
+            template.download(self.apiclient)
+        except Exception as e:
+            self.fail("Failed to register template: %s" % e)
+
+        templates = Template.list(self.apiclient,
+                                      templatefilter=\
+                                      self.services["template_2"]["templatefilter"],
+                                      id=template.id)
+        self.assertEqual(validateList(templates)[0],PASS,\
+                        "templates list validation failed")
+
+        templateSize = (templates[0].size / (1024**3))
+        expectedCount = templateSize
+        response = matchResourceCount(
+                        self.apiclient, expectedCount,
+                        RESOURCE_SECONDARY_STORAGE,
+                        accountid=self.account.id)
+        self.assertEqual(response[0], PASS, response[1])
+
+        try:
+            template.delete(self.apiclient)
+        except Exception as e:
+            self.fail("Failed to delete template: %s" % e)
+
+        expectedCount = 0
+        response = matchResourceCount(
+                        self.apiclient, expectedCount,
+                        RESOURCE_SECONDARY_STORAGE,
+                        accountid=self.account.id)
+        self.assertEqual(response[0], PASS, response[1])
+        return
+
+    @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
+    @attr(tags=["advanced"], required_hardware="false")
+    def test_02_create_template_snapshot(self, value):
+        """Test create snapshot and templates from volume
+
+        # Validate the following
+        1. Create root domain/child domain admin account
+        2. Deploy VM in the account
+        3. Create snapshot from the virtual machine root volume
+        4. Create template from the snapshot
+        5. Verify that the secondary storage count of the account equals
+           the size of the template"""
+
+        response = self.setupAccount(value)
+        self.assertEqual(response[0], PASS, response[1])
+
+        self.virtualMachine = VirtualMachine.create(self.api_client, self.services["virtual_machine"],
+                            accountid=self.account.name, domainid=self.account.domainid,
+                            serviceofferingid=self.service_offering.id)
+
+        self.assertNotEqual(self.virtualMachine, FAILED, "VM deployment failed")
+
+        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:
+            self.virtualMachine.stop(apiclient)
+        except Exception as e:
+            self.fail("Failed to stop instance: %s" % e)
+
+        self.debug("Creating snapshot from ROOT volume: %s" % self.virtualMachine.name)
+        response = createSnapshotFromVirtualMachineVolume(apiclient, self.account, self.virtualMachine.id)
+        self.assertEqual(response[0], PASS, response[1])
+        snapshot = response[1]
+
+        try:
+            template = Template.create_from_snapshot(apiclient,
+                                        snapshot=snapshot,
+                                        services=self.services["template_2"])
+        except Exception as e:
+            self.fail("Failed to create template: %s" % e)
+
+        templateSize = (template.size / (1024**3))
+        response = matchResourceCount(self.apiclient, templateSize,
+                                      resourceType=RESOURCE_SECONDARY_STORAGE,
+                                      accountid=self.account.id)
+        self.assertEqual(response[0], PASS, response[1])
+        return
+
+    @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
+    @attr(tags = ["advanced"], required_hardware="false")
+    def test_03_register_iso(self, value):
+        """Test register iso
+        Steps and validations:
+        1. Create a root domain/child domain admin account
+        2. Register a test iso in the account
+        3. Wait till the iso is downloaded and is in ready state
+        3. Verify that secondary storage resource count of the account equals the
+           iso size
+        4. Delete the iso
+        5. Verify that the secondary storage count of the account equals 0
+        """
+        response = self.setupAccount(value)
+        self.assertEqual(response[0], PASS, response[1])
+
+        self.services["iso"]["zoneid"] = self.zone.id
+        try:
+            iso = Iso.create(
+                         self.apiclient,
+                         self.services["iso"],
+                         account=self.account.name,
+                         domainid=self.account.domainid
+                         )
+        except Exception as e:
+            self.fail("Failed to create Iso: %s" % e)
+
+        timeout = 600
+        isoList = None
+        while timeout >= 0:
+            isoList = Iso.list(self.apiclient,
+                                      isofilter="self",
+                                      id=iso.id)
+            self.assertEqual(validateList(isoList)[0],PASS,\
+                            "iso list validation failed")
+            if isoList[0].isready:
+                break
+            time.sleep(60)
+            timeout -= 60
+
+        self.assertNotEqual(timeout, 0,\
+                "template not downloaded completely")
+
+        isoSize = (isoList[0].size / (1024**3))
+        expectedCount = isoSize
+        response = matchResourceCount(self.apiclient, expectedCount,
+                                      resourceType=RESOURCE_SECONDARY_STORAGE,
+                                      accountid=self.account.id)
+        self.assertEqual(response[0], PASS, response[1])
+
+        try:
+            iso.delete(self.apiclient)
+        except Exception as e:
+            self.fail("Failed to delete Iso")
+
+        expectedCount = 0
+        response = matchResourceCount(self.apiclient, expectedCount,
+                                      resourceType=RESOURCE_SECONDARY_STORAGE,
+                                      accountid=self.account.id)
+        self.assertEqual(response[0], PASS, response[1])
+        return
+
+    @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
+    @attr(tags = ["advanced"], required_hardware="false")
+    def test_04_copy_template(self, value):
+        """Test copy template between zones
+
+        Steps and validations:
+        This test requires at least two zones present in the setup
+        1. Create a root domain/child domain admin account
+        2. Register and download a template in the account
+        3. Verify the secondary storage resource count of the account
+           equals the size of the template
+        4. Copy this template to other zone
+        5. Verify that the secondary storage resource count is now doubled
+           as there are two templates now in two zones under the admin account
+        """
+
+        zones = list_zones(self.apiclient)
+        self.assertEqual(validateList(zones)[0], PASS, "zones list validation faield")
+
+        if len(zones) < 2:
+            self.skipTest("At least 2 zones should be present for this test case")
+
+        response = self.setupAccount(value)
+        self.assertEqual(response[0], PASS, response[1])
+
+        builtin_info = get_builtin_template_info(self.apiclient, self.zone.id)
+        self.services["template_2"]["url"] = builtin_info[0]
+        self.services["template_2"]["hypervisor"] = builtin_info[1]
+        self.services["template_2"]["format"] = builtin_info[2]
+
+        try:
+            template = Template.register(self.apiclient,
+                                     self.services["template_2"],
+                                     zoneid=self.zone.id,
+                                     account=self.account.name,
+                                     domainid=self.account.domainid,
+                                     hypervisor=self.hypervisor)
+
+            template.download(self.apiclient)
+        except Exception as e:
+            self.fail("Failed to register template: %s" % e)
+
+        templates = Template.list(self.apiclient,
+                                      templatefilter=\
+                                      self.services["template_2"]["templatefilter"],
+                                      id=template.id)
+        self.assertEqual(validateList(templates)[0],PASS,\
+                         "templates list validation failed")
+
+        templateSize = (templates[0].size / (1024**3))
+        expectedCount = templateSize
+        response = matchResourceCount(
+                        self.apiclient, expectedCount,
+                        RESOURCE_SECONDARY_STORAGE,
+                        accountid=self.account.id)
+        self.assertEqual(response[0], PASS, response[1])
+
+        templateDestinationZoneId = None
+        for zone in zones:
+            if template.zoneid != zone.id :
+                templateDestinationZoneId = zone.id
+                break
+
+        template.copy(self.apiclient, destzoneid=templateDestinationZoneId,
+                      sourcezoneid = template.zoneid)
+
+        expectedCount = (templateSize * 2)
+        response = matchResourceCount(
+                        self.apiclient, expectedCount,
+                        RESOURCE_SECONDARY_STORAGE,
+                        accountid=self.account.id)
+        self.assertEqual(response[0], PASS, response[1])
+        return

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fe6f0cf6/test/integration/component/test_ss_max_limits.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_ss_max_limits.py b/test/integration/component/test_ss_max_limits.py
new file mode 100644
index 0000000..ba886e8
--- /dev/null
+++ b/test/integration/component/test_ss_max_limits.py
@@ -0,0 +1,279 @@
+# 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 secondary 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
+from marvin.lib.base import (Account,
+                             ServiceOffering,
+                             Resources,
+                             Domain,
+                             Project,
+                             Template)
+from marvin.lib.common import (get_domain,
+                               get_zone,
+                               get_template,
+                               get_builtin_template_info,
+                               matchResourceCount)
+from marvin.lib.utils import (cleanup_resources,
+                              validateList)
+from marvin.codes import PASS, FAIL, RESOURCE_SECONDARY_STORAGE
+
+class TestMaxSecondaryStorageLimits(cloudstackTestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cloudstackTestClient = super(TestMaxSecondaryStorageLimits,
+                               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.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"])
+        cls._cleanup = [cls.service_offering]
+        return
+
+    @classmethod
+    def tearDownClass(cls):
+        try:
+            # Cleanup resources used
+            cleanup_resources(cls.api_client, cls._cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.dbclient = self.testClient.getDbConnection()
+        self.cleanup = []
+        return
+
+    def tearDown(self):
+        try:
+            # Clean up, terminate the created instance, volumes and snapshots
+            cleanup_resources(self.apiclient, self.cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    def registerTemplate(self, inProject=False):
+        """Register and download template by default in the account/domain,
+        in project if stated so"""
+
+        try:
+            builtin_info = get_builtin_template_info(self.apiclient, self.zone.id)
+            self.services["template_2"]["url"] = builtin_info[0]
+            self.services["template_2"]["hypervisor"] = builtin_info[1]
+            self.services["template_2"]["format"] = builtin_info[2]
+
+            template = Template.register(self.apiclient,
+                                     self.services["template_2"],
+                                     zoneid=self.zone.id,
+                                     account=self.child_do_admin.name if not inProject else None,
+                                     domainid=self.child_do_admin.domainid if not inProject else None,
+                                     projectid=self.project.id if inProject else None)
+
+            template.download(self.apiclient)
+
+            templates = Template.list(self.apiclient,
+                                      templatefilter=\
+                                      self.services["template_2"]["templatefilter"],
+                                      id=template.id)
+            self.assertEqual(validateList(templates)[0], PASS,\
+                             "templates list validation failed")
+
+            self.templateSize = (templates[0].size / (1024**3))
+        except Exception as e:
+            return [FAIL, e]
+        return [PASS, None]
+
+    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 updateSecondaryStorageLimits(self, accountLimit=None, domainLimit=None, projectLimit=None):
+
+        try:
+            # Update resource limits for account
+            if accountLimit:
+                Resources.updateLimit(self.apiclient, resourcetype=11,
+                                max=accountLimit, account=self.child_do_admin.name,
+                                domainid=self.child_do_admin.domainid)
+
+            if projectLimit:
+                Resources.updateLimit(self.apiclient, resourcetype=11,
+                                              max=projectLimit, projectid=self.project.id)
+
+            if domainLimit:
+                Resources.updateLimit(self.apiclient, resourcetype=11,
+                                              max=domainLimit, domainid=self.child_domain.id)
+        except Exception as e:
+            return [FAIL, e]
+        return [PASS, None]
+
+    @attr(tags=["advanced"], required_hardware="false")
+    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 register template with admin account where account has not used the
+        #    resources but @ domain they are not available
+        # 2. Template registration should fail"""
+
+        response = self.setupAccounts()
+        self.assertEqual(response[0], PASS, response[1])
+
+        response = self.registerTemplate()
+        self.assertEqual(response[0], PASS, response[1])
+
+        expectedCount = self.templateSize
+        response = matchResourceCount(
+                        self.apiclient, expectedCount,
+                        RESOURCE_SECONDARY_STORAGE,
+                        accountid=self.child_do_admin.id)
+        self.assertEqual(response[0], PASS, response[1])
+
+        domainLimit = self.templateSize
+
+        response = self.updateSecondaryStorageLimits(domainLimit=domainLimit)
+        self.assertEqual(response[0], PASS, response[1])
+
+        with self.assertRaises(Exception):
+            template = Template.register(self.apiclient,
+                                     self.services["template_2"],
+                                     zoneid=self.zone.id,
+                                     account=self.child_do_admin.name,
+                                     domainid=self.child_do_admin.domainid)
+        return
+
+    @attr(tags=["advanced"], required_hardware="false")
+    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
+
+        # Validate the following
+        # 1. Try to register template with admin account where account has used the
+        #    resources but @ domain they are available
+        # 2. Template registration should fail"""
+
+        response = self.setupAccounts()
+        self.assertEqual(response[0], PASS, response[1])
+
+        response = self.registerTemplate()
+        self.assertEqual(response[0], PASS, response[1])
+
+        expectedCount = self.templateSize
+        response = matchResourceCount(
+                        self.apiclient, expectedCount,
+                        RESOURCE_SECONDARY_STORAGE,
+                        accountid=self.child_do_admin.id)
+        self.assertEqual(response[0], PASS, response[1])
+
+        accountLimit = self.templateSize
+
+        response = self.updateSecondaryStorageLimits(accountLimit=accountLimit)
+        self.assertEqual(response[0], PASS, response[1])
+
+        with self.assertRaises(Exception):
+            template = Template.register(self.apiclient,
+                                     self.services["template_2"],
+                                     zoneid=self.zone.id,
+                                     account=self.child_do_admin.name,
+                                     domainid=self.child_do_admin.domainid)
+        return
+
+    @attr(tags=["advanced"], required_hardware="false")
+    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 register template with admin account where account has not used the
+        #    resources but @ project they are not available
+        # 2. Template registration should error out saying  ResourceAllocationException
+        #    with "resource limit exceeds"""
+
+        response = self.setupAccounts()
+        self.assertEqual(response[0], PASS, response[1])
+
+        response = self.registerTemplate(inProject=True)
+        self.assertEqual(response[0], PASS, response[1])
+
+        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.assertEqual(self.templateSize, projects[0].secondarystoragetotal, "Resource count %s\
+                 not matching with the expcted count: %s" %
+                 (projects[0].secondarystoragetotal, self.templateSize))
+
+        projectLimit = self.templateSize
+
+        response = self.updateSecondaryStorageLimits(projectLimit=projectLimit)
+        self.assertEqual(response[0], PASS, response[1])
+
+        with self.assertRaises(Exception):
+            template = Template.register(self.apiclient,
+                                     self.services["template_2"],
+                                     zoneid=self.zone.id,
+                                     projectid=self.project.id)
+        return

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fe6f0cf6/test/integration/component/test_ss_project_limits.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_ss_project_limits.py b/test/integration/component/test_ss_project_limits.py
new file mode 100644
index 0000000..0668f07
--- /dev/null
+++ b/test/integration/component/test_ss_project_limits.py
@@ -0,0 +1,262 @@
+# 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 secondary 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,
+                             Domain,
+                             Project,
+                             Template,
+                             Iso,
+                             Resources)
+from marvin.lib.common import (get_domain,
+                               get_zone,
+                               get_template,
+                               matchResourceCount,
+                               get_builtin_template_info,
+                               createSnapshotFromVirtualMachineVolume)
+from marvin.lib.utils import (cleanup_resources,
+                              validateList)
+from marvin.codes import (PASS,
+                          FAIL,
+                          FAILED,
+                          RESOURCE_SECONDARY_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)
+        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 = []
+        response = self.setupProjectAccounts()
+        self.assertEqual(response[0], PASS, response[1])
+        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.parentDomain = Domain.create(self.apiclient,
+                                        services=self.services["domain"],
+                                        parentdomainid=self.domain.id)
+            self.domainAdmin = Account.create(
+                            self.apiclient, self.services["account"],
+                            admin=True, domainid=self.parentDomain.id)
+
+            # Create project as a domain admin
+            self.project = Project.create(
+                            self.apiclient,self.services["project"],
+                            account=self.domainAdmin.name,domainid=self.parentDomain.id)
+            # Cleanup created project at end of test
+            self.cleanup.append(self.project)
+            self.cleanup.append(self.domainAdmin)
+            self.cleanup.append(self.parentDomain)
+        except Exception as e:
+            return [FAIL, e]
+        return [PASS, None]
+
+    @attr(tags=["advanced"], required_hardware="false")
+    def test_01_register_template_with_project(self):
+        """Test register template
+        # Validate the following:
+        1. Create a project
+        2. Register and download a template according to hypervisor type in the project
+        3. Verify that the template is listed
+        4. Verify that the secondary storage count for the project equals the size
+           of the template
+        5. Delete the template
+        6. Verify that the secondary storage resource count of the project equals 0
+       """
+
+        builtin_info = get_builtin_template_info(self.apiclient, self.zone.id)
+        self.services["template_2"]["url"] = builtin_info[0]
+        self.services["template_2"]["hypervisor"] = builtin_info[1]
+        self.services["template_2"]["format"] = builtin_info[2]
+
+        try:
+            template = Template.register(self.apiclient,
+                                            self.services["template_2"],
+                                            zoneid=self.zone.id,
+                                            projectid=self.project.id)
+
+            template.download(self.apiclient)
+        except Exception as e:
+            self.fail("Failed to register template: %s" % e)
+
+        templates = Template.list(self.apiclient,
+                                      templatefilter=\
+                                      self.services["template_2"]["templatefilter"],
+                                      id=template.id,
+                                      )
+        self.assertEqual(validateList(templates)[0],PASS,\
+                        "templates list validation failed")
+
+        templates = Template.list(self.apiclient,
+                                      templatefilter=\
+                                      self.services["template_2"]["templatefilter"],
+                                      id=template.id,
+                                      )
+        self.assertEqual(validateList(templates)[0],PASS,\
+                        "templates list validation failed")
+
+        templateSize = (templates[0].size / (1024**3))
+        expectedCount = templateSize
+        response = matchResourceCount(
+                        self.apiclient, expectedCount,
+                        RESOURCE_SECONDARY_STORAGE,
+                        projectid=self.project.id)
+        self.assertEqual(response[0], PASS, response[1])
+
+        try:
+            template.delete(self.apiclient)
+        except Exception as e:
+            self.fail("Failed to delete template: %s" % e)
+
+        expectedCount = 0
+        response = matchResourceCount(
+                        self.apiclient, expectedCount,
+                        RESOURCE_SECONDARY_STORAGE,
+                        projectid=self.project.id)
+        self.assertEqual(response[0], PASS, response[1])
+        return
+
+    @attr(tags = ["advanced"], required_hardware="false")
+    def test_02_register_iso(self):
+        """Test register iso
+        Steps and validations:
+        1. Create a root domain/child domain admin account
+        2. Register a test iso in the account
+        3. Wait till the iso is downloaded and is in ready state
+        3. Verify that secondary storage resource count of the account equals the
+           iso size
+        4. Delete the iso
+        5. Verify that the secondary storage count of the account equals 0
+        """
+        try:
+            self.projectMember = Account.create(
+                            self.apiclient, self.services["account"],
+                            domainid=self.parentDomain.id)
+            self.cleanup.insert(0, self.projectMember)
+            self.project.addAccount(self.apiclient, account=self.projectMember.name)
+        except Exception as e:
+            self.fail("Exception occured: %s" % e)
+
+        self.services["iso"]["zoneid"] = self.zone.id
+        try:
+            iso = Iso.create(
+                         self.apiclient,
+                         self.services["iso"],
+                         account=self.projectMember.name,
+                         domainid=self.projectMember.domainid
+                         )
+        except Exception as e:
+            self.fail("Failed to create Iso: %s" % e)
+
+        timeout = 600
+        isoList = None
+        while timeout >= 0:
+            isoList = Iso.list(self.apiclient,
+                                      isofilter="self",
+                                      id=iso.id)
+            self.assertEqual(validateList(isoList)[0],PASS,\
+                            "iso list validation failed")
+            if isoList[0].isready:
+                break
+            time.sleep(60)
+            timeout -= 60
+
+        self.assertNotEqual(timeout, 0,\
+                "template not downloaded completely")
+
+        isoSize = (isoList[0].size / (1024**3))
+        expectedCount = isoSize
+        response = matchResourceCount(self.apiclient, expectedCount,
+                                      resourceType=RESOURCE_SECONDARY_STORAGE,
+                                      projectid=self.project.id)
+        self.assertEqual(response[0], PASS, response[1])
+
+        try:
+            iso.delete(self.apiclient)
+        except Exception as e:
+            self.fail("Failed to delete Iso")
+
+        expectedCount = 0
+        response = matchResourceCount(self.apiclient, expectedCount,
+                                      resourceType=RESOURCE_SECONDARY_STORAGE,
+                                      projectid=self.project.id)
+        self.assertEqual(response[0], PASS, response[1])
+        return

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fe6f0cf6/tools/marvin/marvin/config/test_data.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py
index ade8657..fca2442 100644
--- a/tools/marvin/marvin/config/test_data.py
+++ b/tools/marvin/marvin/config/test_data.py
@@ -770,6 +770,7 @@ test_data = {
         "ispublic": True,
         "isextractable": True,
         "mode": "HTTP_DOWNLOAD",
+        "templatefilter": "self"
     },
     "templatefilter": 'self',
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fe6f0cf6/tools/marvin/marvin/lib/base.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py
index a43ec5e..982986b 100755
--- a/tools/marvin/marvin/lib/base.py
+++ b/tools/marvin/marvin/lib/base.py
@@ -1076,7 +1076,8 @@ class Template:
 
     @classmethod
     def register(cls, apiclient, services, zoneid=None,
-                 account=None, domainid=None, hypervisor=None):
+                 account=None, domainid=None, hypervisor=None,
+                 projectid=None):
         """Create template from URL"""
 
         # Create template from Virtual machine and Volume ID
@@ -1125,6 +1126,11 @@ class Template:
         if domainid:
             cmd.domainid = domainid
 
+        if projectid:
+            cmd.projectid = projectid
+        elif "projectid" in services:
+            cmd.projectid = services["projectid"]
+
         # Register Template
         template = apiclient.registerTemplate(cmd)
 


Mime
View raw message