summaryrefslogtreecommitdiff
path: root/tempest/scenario
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2022-03-05 03:46:56 +0000
committerGerrit Code Review <review@openstack.org>2022-03-05 03:46:56 +0000
commit914b096dfd6b829ea963d537aaa1db6c12bd28f2 (patch)
tree61c6fd7bca6e5e8aa5eace914982a0fe11adefa2 /tempest/scenario
parent721504b102f35d062b725997bccfdfda40d2c371 (diff)
parentbadb24c546f59277a90fbcd5e517525d58591615 (diff)
downloadtempest-914b096dfd6b829ea963d537aaa1db6c12bd28f2.tar.gz
Merge "Tests for nova unified quotas"
Diffstat (limited to 'tempest/scenario')
-rw-r--r--tempest/scenario/test_compute_unified_limits.py166
1 files changed, 166 insertions, 0 deletions
diff --git a/tempest/scenario/test_compute_unified_limits.py b/tempest/scenario/test_compute_unified_limits.py
new file mode 100644
index 000000000..bacf526ef
--- /dev/null
+++ b/tempest/scenario/test_compute_unified_limits.py
@@ -0,0 +1,166 @@
+# Copyright 2021 Red Hat, Inc.
+# All Rights Reserved.
+#
+# 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.
+
+import testtools
+
+from tempest.common import utils
+from tempest.common import waiters
+from tempest import config
+from tempest.lib import decorators
+from tempest.lib import exceptions as lib_exc
+from tempest.scenario import manager
+
+CONF = config.CONF
+
+
+@testtools.skipUnless(CONF.compute_feature_enabled.unified_limits,
+ 'Compute unified limits are not enabled')
+class ComputeProjectQuotaTest(manager.ScenarioTest):
+ """The test base class for compute unified limits tests.
+
+ Dynamic credentials (unique tenants) are created on a per-class basis, so
+ we test different quota limits in separate test classes to prevent a quota
+ limit update in one test class from affecting a test running in another
+ test class in parallel.
+
+ https://docs.openstack.org/tempest/latest/configuration.html#dynamic-credentials
+ """
+ credentials = ['primary', 'system_admin']
+ force_tenant_isolation = True
+
+ @classmethod
+ def resource_setup(cls):
+ super(ComputeProjectQuotaTest, cls).resource_setup()
+
+ # Figure out and record the nova service id
+ services = cls.os_system_admin.identity_services_v3_client.\
+ list_services()
+ nova_services = [x for x in services['services']
+ if x['name'] == 'nova']
+ cls.nova_service_id = nova_services[0]['id']
+
+ # Pre-create quota limits in subclasses and record their IDs so we can
+ # update them in-place without needing to know which ones have been
+ # created and in which order.
+ cls.limit_ids = {}
+
+ @classmethod
+ def _create_limit(cls, name, value):
+ return cls.os_system_admin.identity_limits_client.create_limit(
+ CONF.identity.region, cls.nova_service_id,
+ cls.servers_client.tenant_id, name, value)['limits'][0]['id']
+
+ def _update_limit(self, name, value):
+ self.os_system_admin.identity_limits_client.update_limit(
+ self.limit_ids[name], value)
+
+
+@testtools.skipUnless(CONF.compute_feature_enabled.unified_limits,
+ 'Compute unified limits are not enabled')
+class ServersQuotaTest(ComputeProjectQuotaTest):
+
+ @classmethod
+ def resource_setup(cls):
+ super(ServersQuotaTest, cls).resource_setup()
+
+ try:
+ cls.limit_ids['servers'] = cls._create_limit(
+ 'servers', 5)
+ cls.limit_ids['class:VCPU'] = cls._create_limit(
+ 'class:VCPU', 10)
+ cls.limit_ids['class:MEMORY_MB'] = cls._create_limit(
+ 'class:MEMORY_MB', 25 * 1024)
+ cls.limit_ids['class:DISK_GB'] = cls._create_limit(
+ 'class:DISK_GB', 10)
+ except lib_exc.Forbidden:
+ raise cls.skipException('Target system is not configured with '
+ 'compute unified limits')
+
+ @decorators.idempotent_id('555d8bbf-d2ed-4e39-858c-4235899402d9')
+ @utils.services('compute')
+ def test_server_count_vcpu_memory_disk_quota(self):
+ # Set a quota on the number of servers for our tenant to one.
+ self._update_limit('servers', 1)
+
+ # Create one server.
+ first = self.create_server(name='first')
+
+ # Second server would put us over quota, so expect failure.
+ # NOTE: In nova, quota exceeded raises 403 Forbidden.
+ self.assertRaises(lib_exc.Forbidden,
+ self.create_server,
+ name='second')
+
+ # Update our limit to two.
+ self._update_limit('servers', 2)
+
+ # Now the same create should succeed.
+ second = self.create_server(name='second')
+
+ # Third server would put us over quota, so expect failure.
+ self.assertRaises(lib_exc.Forbidden,
+ self.create_server,
+ name='third')
+
+ # Delete the first server to put us under quota.
+ self.servers_client.delete_server(first['id'])
+ waiters.wait_for_server_termination(self.servers_client, first['id'])
+
+ # Now the same create should succeed.
+ third = self.create_server(name='third')
+
+ # Set the servers limit back to 10 to test other resources.
+ self._update_limit('servers', 10)
+
+ # Default flavor has: VCPU=1, MEMORY_MB=512, DISK_GB=1
+ # We are currently using 2 VCPU, set the limit to 2.
+ self._update_limit('class:VCPU', 2)
+
+ # Server create should fail as it would go over quota.
+ self.assertRaises(lib_exc.Forbidden,
+ self.create_server,
+ name='fourth')
+
+ # Delete the second server to put us under quota.
+ self.servers_client.delete_server(second['id'])
+ waiters.wait_for_server_termination(self.servers_client, second['id'])
+
+ # Same create should now succeed.
+ fourth = self.create_server(name='fourth')
+
+ # We are currently using 2 DISK_GB. Set limit to 1.
+ self._update_limit('class:DISK_GB', 1)
+
+ # Server create should fail because we're already over (new) quota.
+ self.assertRaises(lib_exc.Forbidden,
+ self.create_server,
+ name='fifth')
+
+ # Delete the third server.
+ self.servers_client.delete_server(third['id'])
+ waiters.wait_for_server_termination(self.servers_client, third['id'])
+
+ # Server create should fail again because it would still put us over
+ # quota.
+ self.assertRaises(lib_exc.Forbidden,
+ self.create_server,
+ name='fifth')
+
+ # Delete the fourth server.
+ self.servers_client.delete_server(fourth['id'])
+ waiters.wait_for_server_termination(self.servers_client, fourth['id'])
+
+ # Server create should succeed now.
+ self.create_server(name='fifth')