Changes in "test_quotas.py" API script
1) Re-factoring:
1. Replacing underscores by indexes
2. Moving all negative tests into the dedicated class
3. Using all_projects_header
2) Changing "test_show_quotas" test logic.
The existing test is based and depends on "quotas update" API
and it has almost the same logic as:"test_update_quotas".
New scenario is about to validate that all expected quota types
are listed in "Show API" response and that their values are integers.
Note: test uses both: admin and primary users to cover both "show" APIs:
https://docs.openstack.org/api-ref/dns/?expanded=get-the-name-servers-
for-a-zone-detail#view-quotas
https://docs.openstack.org/api-ref/dns/?expanded=get-the-name-servers-
for-a-zone-detail#view-current-project-s-quotas
3) "test_admin_sets_not_existing_quota_type" - try to set quotas using
not existing quota type in its body, expected: quota_resource_unknown
Change-Id: I9b3d6ee5fc27011b8852739f0ca3ab33fd04d58e
diff --git a/designate_tempest_plugin/services/dns/v2/json/quotas_client.py b/designate_tempest_plugin/services/dns/v2/json/quotas_client.py
index 97398c0..1b1d005 100644
--- a/designate_tempest_plugin/services/dns/v2/json/quotas_client.py
+++ b/designate_tempest_plugin/services/dns/v2/json/quotas_client.py
@@ -58,17 +58,29 @@
return resp, body
@base.handle_errors
- def show_quotas(self, project_id, params=None, headers=None):
+ def show_quotas(self, project_id=None, params=None, headers=None):
"""Gets a specific quota.
- :param project_id: Show the quotas of this project id
+ :param project_id: if provided - show the quotas of this project id.
+ https://docs.openstack.org/api-ref/dns/?expanded=
+ get-the-name-servers-for-a-zone-detail#view-quotas
+ If not - show the quotas for a current
+ project.
+ https://docs.openstack.org/api-ref/dns/?expanded=ge
+ t-the-name-servers-for-a-zone-detail#view-current-p
+ roject-s-quotas
+
:param params: A Python dict that represents the query paramaters to
include in the request URI.
:param headers (dict): The headers to use for the request.
:return: Serialized quota as a dictionary.
"""
- return self._show_request('quotas', project_id, params=params,
- headers=headers, extra_headers=True)
+ if project_id is None:
+ return self._show_request(
+ 'quotas', uuid=None, params=params, headers=headers)
+ else:
+ return self._show_request(
+ 'quotas', project_id, params=params, headers=headers)
@base.handle_errors
def delete_quotas(self, project_id, params=None, headers=None):
@@ -100,13 +112,10 @@
:param headers (dict): The headers to use for the request.
:return: Serialized quota as a dictionary.
"""
- if headers is None:
- headers = {'content-type': 'application/json'}
- if 'content-type' not in [header.lower() for header in headers]:
- headers['content-type'] = 'application/json'
resp, body = self._update_request(
"quotas", project_id,
- data=quotas, params=params, headers=headers)
+ data=quotas, params=params, headers=headers,
+ extra_headers=True)
self.expected_success(200, resp.status)
return resp, body
diff --git a/designate_tempest_plugin/tests/api/v2/test_quotas.py b/designate_tempest_plugin/tests/api/v2/test_quotas.py
index db870af..0366843 100644
--- a/designate_tempest_plugin/tests/api/v2/test_quotas.py
+++ b/designate_tempest_plugin/tests/api/v2/test_quotas.py
@@ -23,6 +23,9 @@
CONF = config.CONF
LOG = logging.getLogger(__name__)
+quotas_types = ["api_export_size", "recordset_records",
+ "zone_records", "zone_recordsets", "zones"]
+
class QuotasV2Test(base.BaseDnsV2Test):
@@ -53,7 +56,6 @@
cls.admin_client = cls.os_admin.dns_v2.QuotasClient()
cls.quotas_client = cls.os_primary.dns_v2.QuotasClient()
cls.alt_client = cls.os_alt.dns_v2.QuotasClient()
- cls.alt_zone_client = cls.os_alt.dns_v2.ZonesClient()
def _store_quotas(self, project_id, cleanup=True):
"""Remember current quotas and reset them after the test"""
@@ -68,29 +70,33 @@
@decorators.idempotent_id('1dac991a-9e2e-452c-a47a-26ac37381ec5')
def test_show_quotas(self):
- self._store_quotas(project_id=self.quotas_client.project_id)
- LOG.info("Updating quotas")
- quotas = dns_data_utils.rand_quotas()
- _, body = self.admin_client.update_quotas(
- project_id=self.quotas_client.project_id,
- headers=self.all_projects_header,
- **quotas)
-
- LOG.info("Fetching quotas")
- _, body = self.admin_client.show_quotas(
- project_id=self.quotas_client.project_id,
- headers=self.all_projects_header)
-
- LOG.info("Ensuring the response has all quota types")
- self.assertExpected(quotas, body, [])
+ LOG.info("Show default quotas, validate all quota types exists and "
+ "their values are integers.")
+ for user in ['primary', 'admin']:
+ if user == 'primary':
+ body = self.quotas_client.show_quotas()[1]
+ if user == 'admin':
+ body = self.admin_client.show_quotas(
+ project_id=self.quotas_client.project_id,
+ headers=self.all_projects_header)[1]
+ for quota_type in quotas_types:
+ self.assertIn(
+ quota_type, body.keys(),
+ 'Failed, expected quota type:{} was not found '
+ 'in received quota body'.format(quota_type))
+ for quota_type, quota_value in body.items():
+ self.assertTrue(
+ isinstance(quota_value, int),
+ 'Failed, the value of:{} is:{}, expected integer'.format(
+ quota_type, quota_value))
@decorators.idempotent_id('0448b089-5803-4ce3-8a6c-5c15ff75a2cc')
- def test_delete_quotas(self):
+ def test_reset_quotas(self):
self._store_quotas(project_id=self.quotas_client.project_id)
- LOG.info("Deleting quotas")
- _, body = self.admin_client.delete_quotas(
+ LOG.info("Deleting (reset) quotas")
+ body = self.admin_client.delete_quotas(
project_id=self.quotas_client.project_id,
- headers=self.all_projects_header)
+ headers=self.all_projects_header)[1]
LOG.info("Ensuring an empty response body")
self.assertEqual(body.strip(), b"")
@@ -104,9 +110,9 @@
self._store_quotas(project_id=self.admin_client.project_id)
LOG.info("Updating quotas")
quotas = dns_data_utils.rand_quotas()
- _, body = self.admin_client.update_quotas(
+ body = self.admin_client.update_quotas(
project_id=self.admin_client.project_id,
- **quotas)
+ **quotas)[1]
LOG.info("Ensuring the response has all quota types")
self.assertExpected(quotas, body, [])
@@ -121,15 +127,15 @@
quotas = dns_data_utils.rand_quotas()
request = quotas.copy()
- _, body = self.admin_client.update_quotas(
+ body = self.admin_client.update_quotas(
project_id=project_id,
headers=self.all_projects_header,
- **request)
+ **request)[1]
LOG.info("Ensuring the response has all quota types")
self.assertExpected(quotas, body, [])
- _, client_body = self.quotas_client.show_quotas(project_id=project_id)
+ client_body = self.quotas_client.show_quotas(project_id=project_id)[1]
self.assertExpected(quotas, client_body, [])
@@ -145,15 +151,15 @@
project_id=project_id,
headers=self.all_projects_header)
- _, default_quotas = self.admin_client.show_quotas(
+ default_quotas = self.admin_client.show_quotas(
project_id=project_id,
- headers=self.all_projects_header)
+ headers=self.all_projects_header)[1]
LOG.info("Updating quotas for %s ", project_id)
quotas = dns_data_utils.rand_quotas()
request = quotas.copy()
- _, body = self.admin_client.update_quotas(
+ self.admin_client.update_quotas(
project_id=project_id,
headers=self.all_projects_header,
**request)
@@ -162,9 +168,9 @@
project_id=project_id,
headers=self.all_projects_header)
- _, final_quotas = self.admin_client.show_quotas(
+ final_quotas = self.admin_client.show_quotas(
project_id=project_id,
- headers=self.all_projects_header)
+ headers=self.all_projects_header)[1]
self.assertExpected(default_quotas, final_quotas, [])
@@ -188,16 +194,45 @@
**request)
LOG.info("Make sure that the quotas weren't changed")
- _, client_body = self.quotas_client.show_quotas(
- project_id=self.quotas_client.project_id)
+ client_body = self.quotas_client.show_quotas(
+ project_id=self.quotas_client.project_id)[1]
self.assertExpected(original_quotas, client_body, [])
+
+class QuotasV2TestNegative(base.BaseDnsV2Test):
+
+ credentials = ["primary", "admin", "system_admin"]
+
+ @classmethod
+ def setup_credentials(cls):
+ # Do not create network resources for these test.
+ cls.set_network_resources()
+ super(QuotasV2TestNegative, cls).setup_credentials()
+
+ @classmethod
+ def skip_checks(cls):
+ super(QuotasV2TestNegative, cls).skip_checks()
+
+ if not CONF.dns_feature_enabled.api_v2_quotas:
+ skip_msg = ("%s skipped as designate V2 Quotas API is not "
+ "available" % cls.__name__)
+ raise cls.skipException(skip_msg)
+
+ @classmethod
+ def setup_clients(cls):
+ super(QuotasV2TestNegative, cls).setup_clients()
+
+ if CONF.enforce_scope.designate:
+ cls.admin_client = cls.os_system_admin.dns_v2.QuotasClient()
+ else:
+ cls.admin_client = cls.os_admin.dns_v2.QuotasClient()
+ cls.quotas_client = cls.os_primary.dns_v2.QuotasClient()
+
@decorators.idempotent_id('ae82a0ba-da60-11eb-bf12-74e5f9e2a801')
def test_admin_sets_quota_for_a_project(self):
primary_project_id = self.quotas_client.project_id
- http_headers_to_use = [
- {'X-Auth-All-Projects': True},
+ http_headers_to_use = [self.all_projects_header,
{'x-auth-sudo-project-id': primary_project_id}]
for http_header in http_headers_to_use:
@@ -240,21 +275,33 @@
lib_exc.Forbidden, self.quotas_client.set_quotas,
project_id=self.quotas_client.project_id,
quotas=dns_data_utils.rand_quotas(),
- headers={'x-auth-all-projects': True})
+ headers=self.all_projects_header)
@decorators.idempotent_id('a6ce5b46-dcce-11eb-903e-74e5f9e2a801')
@decorators.skip_because(bug="1934596")
def test_admin_sets_invalid_quota_values(self):
primary_project_id = self.quotas_client.project_id
- http_header = {'X-Auth-All-Projects': True}
- for item in ['zones', 'zone_records',
- 'zone_recordsets', 'recordset_records']:
+ for item in quotas_types:
quota = dns_data_utils.rand_quotas()
quota[item] = tempest_data_utils.rand_name()
self.assertRaises(
lib_exc.BadRequest, self.admin_client.set_quotas,
project_id=primary_project_id,
quotas=quota,
- headers=http_header)
+ headers=self.all_projects_header)
+
+ @decorators.idempotent_id('ac212fd8-c602-11ec-b042-201e8823901f')
+ def test_admin_sets_not_existing_quota_type(self):
+
+ LOG.info('Try to set quota using not existing quota type in its body')
+ primary_project_id = self.quotas_client.project_id
+ quota = dns_data_utils.rand_quotas()
+ quota[tempest_data_utils.rand_name()] = 777
+
+ with self.assertRaisesDns(
+ lib_exc.ServerFault, 'quota_resource_unknown', 500):
+ self.admin_client.set_quotas(
+ project_id=primary_project_id,
+ quotas=quota, headers=self.all_projects_header)