| # 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() |
| cls.services = cloudstackTestClient.getParsedTestDataConfig() |
| 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): |
| super(TestMultipleChildDomain,cls).tearDownClass() |
| |
| def setUp(self): |
| self.apiclient = self.testClient.getApiClient() |
| self.dbclient = self.testClient.getDbConnection() |
| self.cleanup = [] |
| return |
| |
| def tearDown(self): |
| super(TestMultipleChildDomain,self).tearDown() |
| |
| def updateDomainResourceLimits(self, parentdomainlimit, subdomainlimit): |
| """Update secondary storage limits of the parent domain and its |
| child domains""" |
| |
| try: |
| Resources.updateLimit(self.apiclient, resourcetype=11, |
| max=parentdomainlimit, |
| domainid=self.parent_domain.id) |
| |
| 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.cleanup.append(self.parent_domain) |
| self.parentd_admin = Account.create(self.apiclient, self.services["account"], |
| admin=True, domainid=self.parent_domain.id) |
| self.cleanup.append(self.parentd_admin) |
| |
| # Create sub-domains and their admin accounts |
| self.cdomain_1 = Domain.create(self.apiclient, |
| services=self.services["domain"], |
| parentdomainid=self.parent_domain.id) |
| self.cleanup.append(self.cdomain_1) |
| self.cdomain_2 = Domain.create(self.apiclient, |
| services=self.services["domain"], |
| parentdomainid=self.parent_domain.id) |
| self.cleanup.append(self.cdomain_2) |
| |
| self.cadmin_1 = Account.create(self.apiclient, self.services["account"], |
| admin=True, domainid=self.cdomain_1.id) |
| self.cleanup.append(self.cadmin_1) |
| |
| self.cadmin_2 = Account.create(self.apiclient, self.services["account"], |
| admin=True, domainid=self.cdomain_2.id) |
| self.cleanup.append(self.cadmin_2) |
| |
| 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="true") |
| 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] |
| self.services["template_2"]["ispublic"] = False |
| |
| 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="true") |
| 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 list(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] |
| self.services["template_2"]["ispublic"] = False |
| |
| 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="true") |
| 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 list(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] |
| self.services["template_2"]["ispublic"] = False |
| |
| 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 copy template cross zones: %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): |
| super(TestDeleteAccount,cls).tearDownClass() |
| |
| def setUp(self): |
| self.apiclient = self.testClient.getApiClient() |
| self.dbclient = self.testClient.getDbConnection() |
| self.cleanup = [] |
| return |
| |
| def tearDown(self): |
| super(TestDeleteAccount,self).tearDown() |
| |
| def setupAccounts(self): |
| try: |
| self.parent_domain = Domain.create(self.apiclient, |
| services=self.services["domain"], |
| parentdomainid=self.domain.id) |
| self.cleanup.append(self.parent_domain) |
| self.parentd_admin = Account.create(self.apiclient, self.services["account"], |
| admin=True, domainid=self.parent_domain.id) |
| self.cleanup.append(self.parentd_admin) |
| |
| self.cdomain_1 = Domain.create(self.apiclient, |
| services=self.services["domain"], |
| parentdomainid=self.parent_domain.id) |
| self.cleanup.append(self.cdomain_1) |
| self.cdomain_2 = Domain.create(self.apiclient, |
| services=self.services["domain"], |
| parentdomainid=self.parent_domain.id) |
| self.cleanup.append(self.cdomain_2) |
| |
| self.cadmin_1 = Account.create(self.apiclient, self.services["account"], |
| admin=True, domainid=self.cdomain_1.id) |
| self.cleanup.append(self.cadmin_1) |
| |
| self.cadmin_2 = Account.create(self.apiclient, self.services["account"], |
| admin=True, domainid=self.cdomain_2.id) |
| self.cleanup.append(self.cadmin_2) |
| |
| 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="true") |
| 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] |
| self.services["template_2"]["ispublic"] = False |
| |
| 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") |
| |
| self.templateSize = int((int(templates[0].size)*2) / (1024**3)) |
| |
| expectedCount = self.templateSize |
| 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) |
| self.cleanup.remove(self.cadmin_1) |
| 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 |