Add quota tests in api tests.
The quotas tests in the case of create resources over limit value
are not covered enough in unit tests/functional tests.
This patch include test case of api functional tests.
Change-Id: Ibde1cdff068ae8ac130d05143d53b6b783ad0fa3
Closes-bug: #1567743
diff --git a/neutron/tests/tempest/api/admin/test_quotas.py b/neutron/tests/tempest/api/admin/test_quotas.py
index 4e00da2..3bf52c5 100644
--- a/neutron/tests/tempest/api/admin/test_quotas.py
+++ b/neutron/tests/tempest/api/admin/test_quotas.py
@@ -21,9 +21,44 @@
from neutron.tests.tempest.api import base
-class QuotasTest(base.BaseAdminNetworkTest):
+class QuotasTestBase(base.BaseAdminNetworkTest):
- """
+ @classmethod
+ @test.requires_ext(extension="quotas", service="network")
+ def resource_setup(cls):
+ super(QuotasTestBase, cls).resource_setup()
+
+ def _create_tenant(self):
+ # Add a tenant to conduct the test
+ test_tenant = data_utils.rand_name('test_tenant_')
+ test_description = data_utils.rand_name('desc_')
+ tenant = self.identity_admin_client.create_tenant(
+ name=test_tenant,
+ description=test_description)['tenant']
+ self.addCleanup(
+ self.identity_admin_client.create_tenant, tenant['id'])
+ return tenant
+
+ def _setup_quotas(self, project_id, **new_quotas):
+ # Change quotas for tenant
+ quota_set = self.admin_client.update_quotas(project_id,
+ **new_quotas)
+ self.addCleanup(self._cleanup_quotas, project_id)
+ return quota_set
+
+ def _cleanup_quotas(self, project_id):
+ # Try to clean up the resources. If it fails, then
+ # assume that everything was already deleted, so
+ # it is OK to continue.
+ try:
+ self.admin_client.reset_quotas(project_id)
+ except lib_exc.NotFound:
+ pass
+
+
+class QuotasTest(QuotasTestBase):
+ """Test the Neutron API of Quotas.
+
Tests the following operations in the Neutron API using the REST client for
Neutron:
@@ -39,29 +74,14 @@
quota_driver = neutron.db.driver.DbQuotaDriver
"""
- @classmethod
- @test.requires_ext(extension="quotas", service="network")
- def resource_setup(cls):
- super(QuotasTest, cls).resource_setup()
-
@test.attr(type='gate')
@test.idempotent_id('2390f766-836d-40ef-9aeb-e810d78207fb')
def test_quotas(self):
- # Add a tenant to conduct the test
- test_tenant = data_utils.rand_name('test_tenant_')
- test_description = data_utils.rand_name('desc_')
- tenant = self.identity_admin_client.create_tenant(
- name=test_tenant,
- description=test_description)['tenant']
- tenant_id = tenant['id']
- self.addCleanup(self.identity_admin_client.delete_tenant, tenant_id)
-
+ tenant_id = self._create_tenant()['id']
new_quotas = {'network': 0, 'security_group': 0}
# Change quotas for tenant
- quota_set = self.admin_client.update_quotas(tenant_id,
- **new_quotas)
- self.addCleanup(self._cleanup_quotas, tenant_id)
+ quota_set = self._setup_quotas(tenant_id, **new_quotas)
for key, value in six.iteritems(new_quotas):
self.assertEqual(value, quota_set[key])
@@ -84,12 +104,3 @@
non_default_quotas = self.admin_client.list_quotas()
for q in non_default_quotas['quotas']:
self.assertNotEqual(tenant_id, q['tenant_id'])
-
- def _cleanup_quotas(self, project_id):
- # Try to clean up the resources. If it fails, then
- # assume that everything was already deleted, so
- # it is OK to continue.
- try:
- self.admin_client.reset_quotas(project_id)
- except lib_exc.NotFound:
- pass
diff --git a/neutron/tests/tempest/api/admin/test_quotas_negative.py b/neutron/tests/tempest/api/admin/test_quotas_negative.py
new file mode 100644
index 0000000..12ae0be
--- /dev/null
+++ b/neutron/tests/tempest/api/admin/test_quotas_negative.py
@@ -0,0 +1,173 @@
+# Licensed 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.
+
+from tempest.lib.common.utils import data_utils
+from tempest.lib import exceptions as lib_exc
+from tempest import test
+
+from neutron.tests.tempest.api.admin import test_quotas
+from neutron.tests.tempest import config
+
+CONF = config.CONF
+
+
+class QuotasAdminNegativeTestJSON(test_quotas.QuotasTestBase):
+
+ @test.attr(type='negative')
+ @test.idempotent_id('952f9b24-9156-4bdc-90f3-682a3d4302f0')
+ def test_create_network_when_quotas_is_full(self):
+ tenant_id = self._create_tenant()['id']
+ new_quotas = {'network': 1}
+ self._setup_quotas(tenant_id, **new_quotas)
+
+ net_args = {'tenant_id': tenant_id}
+ net = self.admin_client.create_network(**net_args)['network']
+ self.addCleanup(self.admin_client.delete_network, net['id'])
+
+ self.assertRaises(lib_exc.Conflict,
+ self.admin_client.create_network, **net_args)
+
+ @test.attr(type='negative')
+ @test.idempotent_id('0b7f99e3-9f77-45ce-9a89-b39a184de618')
+ def test_create_subnet_when_quotas_is_full(self):
+ tenant_id = self._create_tenant()['id']
+ new_quotas = {'subnet': 1}
+ self._setup_quotas(tenant_id, **new_quotas)
+
+ net_args = {'tenant_id': tenant_id}
+ net = self.admin_client.create_network(**net_args)['network']
+ self.addCleanup(self.admin_client.delete_network, net['id'])
+
+ subnet_args = {'tenant_id': tenant_id,
+ 'network_id': net['id'],
+ 'cidr': '10.0.0.0/24',
+ 'ip_version': '4'}
+ subnet = self.admin_client.create_subnet(**subnet_args)['subnet']
+ self.addCleanup(self.admin_client.delete_subnet, subnet['id'])
+
+ subnet_args['cidr'] = '10.1.0.0/24'
+ self.assertRaises(lib_exc.Conflict,
+ self.admin_client.create_subnet, **subnet_args)
+
+ @test.attr(type='negative')
+ @test.idempotent_id('fe20d9f9-346c-4a20-bbfa-d9ca390f4dc6')
+ def test_create_port_when_quotas_is_full(self):
+ tenant_id = self._create_tenant()['id']
+ new_quotas = {'port': 1}
+ self._setup_quotas(tenant_id, **new_quotas)
+
+ net_args = {'tenant_id': tenant_id}
+ net = self.admin_client.create_network(**net_args)['network']
+ self.addCleanup(self.admin_client.delete_network, net['id'])
+
+ subnet_args = {'tenant_id': tenant_id,
+ 'network_id': net['id'],
+ 'cidr': '10.0.0.0/24',
+ 'ip_version': '4'}
+ subnet = self.admin_client.create_subnet(**subnet_args)['subnet']
+ self.addCleanup(self.admin_client.delete_subnet, subnet['id'])
+
+ port_args = {'tenant_id': tenant_id,
+ 'network_id': net['id']}
+ port = self.admin_client.create_port(**port_args)['port']
+ self.addCleanup(self.admin_client.delete_port, port['id'])
+
+ self.assertRaises(lib_exc.Conflict,
+ self.admin_client.create_port, **port_args)
+
+ @test.attr(type='negative')
+ @test.idempotent_id('bb1e9c3c-7e6f-41f1-b579-63dbc655ecb7')
+ @test.requires_ext(extension="router", service="network")
+ def test_create_router_when_quotas_is_full(self):
+ tenant_id = self._create_tenant()['id']
+ new_quotas = {'router': 1}
+ self._setup_quotas(tenant_id, **new_quotas)
+
+ name = data_utils.rand_name('test_router_')
+ router_args = {'tenant_id': tenant_id}
+ router = self.admin_client.create_router(
+ name, True, **router_args)['router']
+ self.addCleanup(self.admin_client.delete_router, router['id'])
+
+ self.assertRaises(lib_exc.Conflict,
+ self.admin_client.create_router,
+ name, True, **router_args)
+
+ @test.attr(type='negative')
+ @test.idempotent_id('5c924ff7-b7a9-474f-92a3-dbe0f976ec13')
+ @test.requires_ext(extension="security-group", service="network")
+ def test_create_security_group_when_quotas_is_full(self):
+ tenant_id = self._create_tenant()['id']
+ sg_args = {'tenant_id': tenant_id}
+ # avoid a number that is made by default
+ sg_list = self.admin_client.list_security_groups(
+ tenant_id=tenant_id)['security_groups']
+ num = len(sg_list) + 1
+
+ new_quotas = {'security_group': num}
+ self._setup_quotas(tenant_id, **new_quotas)
+
+ sg = self.admin_client.create_security_group(
+ **sg_args)['security_group']
+ self.addCleanup(self.admin_client.delete_security_group, sg['id'])
+
+ self.assertRaises(lib_exc.Conflict,
+ self.admin_client.create_security_group, **sg_args)
+
+ @test.attr(type='negative')
+ @test.idempotent_id('b7143480-6118-4ed4-be38-1b6f15f30d05')
+ @test.requires_ext(extension="security-group", service="network")
+ def test_create_security_group_rule_when_quotas_is_full(self):
+ tenant_id = self._create_tenant()['id']
+ sg_args = {'tenant_id': tenant_id}
+
+ sg = self.admin_client.create_security_group(
+ **sg_args)['security_group']
+ self.addCleanup(self.admin_client.delete_security_group, sg['id'])
+
+ # avoid a number that is made by default
+ sg_rule_list = self.admin_client.list_security_group_rules(
+ tenant_id=tenant_id)['security_group_rules']
+ num = len(sg_rule_list) + 1
+
+ new_quotas = {'security_group_rule': num}
+ self._setup_quotas(tenant_id, **new_quotas)
+
+ sg_rule_args = {'tenant_id': tenant_id,
+ 'security_group_id': sg['id'],
+ 'direction': 'ingress'}
+ sg_rule = self.admin_client.create_security_group_rule(
+ **sg_rule_args)['security_group_rule']
+ self.addCleanup(
+ self.admin_client.delete_security_group_rule, sg_rule['id'])
+
+ sg_rule_args['direction'] = 'egress'
+ self.assertRaises(lib_exc.Conflict,
+ self.admin_client.create_security_group_rule,
+ **sg_rule_args)
+
+ @test.attr(type='negative')
+ @test.idempotent_id('d00fe5bb-9db8-4e1a-9c31-490f52897e6f')
+ @test.requires_ext(extension="router", service="network")
+ def test_create_floatingip_when_quotas_is_full(self):
+ tenant_id = self._create_tenant()['id']
+ new_quotas = {'floatingip': 1}
+ self._setup_quotas(tenant_id, **new_quotas)
+
+ ext_net_id = CONF.network.public_network_id
+ fip_args = {'tenant_id': tenant_id,
+ 'floating_network_id': ext_net_id}
+ fip = self.admin_client.create_floatingip(**fip_args)['floatingip']
+ self.addCleanup(self.admin_client.delete_floatingip, fip['id'])
+
+ self.assertRaises(lib_exc.Conflict,
+ self.admin_client.create_floatingip, **fip_args)