From 446168b7bdb6e7bc915cecab8480822bf542c543 Mon Sep 17 00:00:00 2001 From: Chi Lo Date: Thu, 5 Nov 2020 15:56:02 -0800 Subject: [PATCH] Display Ranger error response messasge in tempest exception When resource creation failed, the region's error message is retrieved and included as part of the tempest exception message. Change-Id: I6309b29ad516651b9a89ffe54763d11fb56949a4 --- ranger_tempest_plugin/tests/api/cms_base.py | 64 ++++--- ranger_tempest_plugin/tests/api/fms_base.py | 164 ++++++++---------- ranger_tempest_plugin/tests/api/ims_base.py | 34 ++-- ranger_tempest_plugin/tests/api/rms_base.py | 27 ++- .../tests/api/test_customers.py | 6 +- .../tests/api/test_flavors.py | 20 ++- .../tests/api/test_images.py | 19 +- 7 files changed, 170 insertions(+), 164 deletions(-) diff --git a/ranger_tempest_plugin/tests/api/cms_base.py b/ranger_tempest_plugin/tests/api/cms_base.py index 491ad6d..ae895a4 100755 --- a/ranger_tempest_plugin/tests/api/cms_base.py +++ b/ranger_tempest_plugin/tests/api/cms_base.py @@ -38,21 +38,15 @@ class CmsBaseOrmTest(base.BaseOrmTest): cls.setup_customer = cls._get_customer_params() cls.setup_customer['uuid'] = uuid.uuid4().hex - cls.addClassResourceCleanup( - cls._del_cust_validate_deletion_on_dcp_and_lcp, - cls.setup_customer['uuid']) cls.setup_customer_id = \ cls._create_cust_validate_creation_on_dcp_and_lcp( - **cls.setup_customer) + cleanup=True, **cls.setup_customer) cls.bare_customer = cls._get_bare_customer_params() cls.bare_customer['uuid'] = uuid.uuid4().hex - cls.addClassResourceCleanup( - cls._del_cust_validate_deletion_on_dcp_and_lcp, - cls.bare_customer['uuid']) cls.bare_customer_id = \ cls._create_cust_validate_creation_on_dcp_and_lcp( - **cls.bare_customer) + cleanup=True, **cls.bare_customer) @classmethod def setup_clients(cls): @@ -157,7 +151,7 @@ class CmsBaseOrmTest(base.BaseOrmTest): return [region] @classmethod - def _create_cust_validate_creation_on_dcp_and_lcp(cls, **kwargs): + def _create_cust_validate_creation_on_dcp_and_lcp(cls, cleanup, **kwargs): """Creates a customer record kwargs contains field data needed for customer POST body: @@ -174,34 +168,50 @@ class CmsBaseOrmTest(base.BaseOrmTest): """ _, body = cls.client.create_customer(**kwargs) customer_id = body["customer"]["id"] + + if cleanup: + cls.addClassResourceCleanup( + cls._del_cust_validate_deletion_on_dcp_and_lcp, + customer_id) + _, customer = cls.client.get_customer(customer_id) - if customer["name"] == kwargs["name"]: - if customer["regions"] == []: - customer_status = "no regions" - else: - customer_status = "Success" - else: - message = "customer %s not created successfully" % kwargs["name"] + + if customer["name"] != kwargs["name"]: + message = "Customer %s creation FAILED" % kwargs["name"] exceptions.TempestException(message) - cls._wait_for_status(customer_id, customer_status) + + if customer["regions"] != []: + cls._wait_for_status(customer_id, "Success") + return customer_id @classmethod def _wait_for_status(cls, customer_id, status): - customer_status = cls.client.get_customer(customer_id)[1]["status"] + _, customer = cls.client.get_customer(customer_id) + customer_status = customer["status"] start = int(time.time()) while customer_status != status: time.sleep(cls.build_interval) - customer_status = cls.client.get_customer(customer_id)[1]["status"] + _, customer = cls.client.get_customer(customer_id) + customer_status = customer["status"] + if customer_status == 'Error': - message = ('customer %s failed to reach %s status' - ' and is in ERROR status on orm' % - (customer_id, status)) - raise exceptions.TempestException(message) + # Some test cases have multiple regions + message = "" + for region in customer["regions"]: + if "error_message" in region: + message += "Region %s Error: %s. " % ( + region["name"], region["error_message"]) + + if not message: + message = ('Customer %s failed to reach %s status and is' + ' in ERROR status' % (customer_id, status)) + raise exceptions.ServerFault(message) + if int(time.time()) - start >= cls.build_timeout: - message = ('customer %s failed to reach %s' + message = ('Customer %s failed to reach %s' 'status within the required time (%s s)' - 'on orm and is in %s status.' + 'and is in %s status.' % (customer_id, status, cls.build_timeout, customer_status)) @@ -217,7 +227,7 @@ class CmsBaseOrmTest(base.BaseOrmTest): for param in quota["compute"][0]: if param in body["quota_set"]: if (quota["compute"][0][param] - == str(body["quota_set"][param])): + == str(body["quota_set"][param])): actual_quota_count += 1 body = cls.volume_quotas_client.show_quota_set(cust_id) for param in quota["storage"][0]: @@ -228,7 +238,7 @@ class CmsBaseOrmTest(base.BaseOrmTest): for param in quota["network"][0]: if param in body["quota_set"]: if (quota["compute"][0][param] - == str(body["quota_set"][param])): + == str(body["quota_set"][param])): actual_quota_count += 1 return bool(expected_quota_count == actual_quota_count) diff --git a/ranger_tempest_plugin/tests/api/fms_base.py b/ranger_tempest_plugin/tests/api/fms_base.py index bdb1ad8..ef129e6 100755 --- a/ranger_tempest_plugin/tests/api/fms_base.py +++ b/ranger_tempest_plugin/tests/api/fms_base.py @@ -42,8 +42,12 @@ class FmsBaseOrmTest(base.BaseOrmTest): @classmethod def resource_setup(cls): super(FmsBaseOrmTest, cls).resource_setup() - cls.tenant_id = cls._create_customer() - cls.alt_tenant_id = cls._create_customer() + cls.tenant_id = None + cls.alt_tenant_id = None + + @classmethod + def resource_cleanup(cls): + super(FmsBaseOrmTest, cls).resource_cleanup() @classmethod def _create_customer(cls): @@ -56,36 +60,43 @@ class FmsBaseOrmTest(base.BaseOrmTest): cust['users'] = [] cust['uuid'] = uuid.uuid4().hex - cls.addClassResourceCleanup( - cls._del_cust_validate_deletion_on_dcp_and_lcp, - cust['uuid']) - _, body = cls.cms_client.create_customer(**cust) customer_id = body["customer"]["id"] _, customer = cls.cms_client.get_customer(customer_id) if customer["name"] != cust["name"]: - message = "customer %s not created successfully" % cust["name"] + message = "Customer %s creation FAILED" % cust["name"] exceptions.TempestException(message) - customer_status = cls.cms_client.get_customer(customer_id)[1]["status"] + customer_status = customer["status"] + expected_status = 'Success' start = int(time.time()) - while customer_status != 'Success': + while customer_status != expected_status: time.sleep(cls.build_interval) - customer_status = \ - cls.cms_client.get_customer(customer_id)[1]["status"] + _, customer = cls.cms_client.get_customer(customer_id) + customer_status = customer["status"] + if customer_status == 'Error': - message = ('customer %s failed to reach %s status' - ' and is in ERROR status on orm' % - (customer_id, customer_status)) - raise exceptions.TempestException(message) + message = "" + for region in customer["regions"]: + if "error_message" in region: + message += "Region %s Error: %s. " % ( + region["name"], region["error_message"]) + + if not message: + message = ('Customer %s failed to reach %s status and is' + ' in ERROR status' % (customer_id, + expected_status)) + raise exceptions.ServerFault(message) + if int(time.time()) - start >= cls.build_timeout: - message = ('customer %s failed to reach %s' + message = ('Customer %s failed to reach %s' 'status within the required time (%s s) ' - 'on orm and is in %s status.' - % (customer_id, customer_status, + 'and is in %s status.' + % (customer_id, expected_status, cls.build_timeout, customer_status)) + raise exceptions.TimeoutException(message) return customer_id @@ -96,62 +107,18 @@ class FmsBaseOrmTest(base.BaseOrmTest): [region['name'] for region in customer["regions"]] for region in regions_on_customer: - cls._delete_region_from_customer_and_validate_deletion( - customer_id, region) + cls.cms_client.delete_region_from_customer(customer_id, region) - cls.cms_client.delete_customer(customer_id) - cls._wait_for_customer_deletion_on_dcp(customer_id) - cls._validate_customer_deletion_on_lcp(customer_id) - - @classmethod - def _delete_region_from_customer_and_validate_deletion( - cls, customer_id, rname): - cls.cms_client.delete_region_from_customer(customer_id, rname) - - time.sleep(cls.build_interval) + time.sleep(cls.build_timeout) _, body = cls.cms_client.get_customer(customer_id) - start = int(time.time()) - for regions_on_customer in body['regions']: - if rname in regions_on_customer: - while rname in regions_on_customer: - time.sleep(cls.build_interval) - _, body = cls.cms_client.get_customer(customer_id) - regions_on_customer = body['regions'] - if int(time.time()) - start >= cls.build_timeout: - message = \ - ('Region %s failed to get deleted from customer %s' - % (rname, customer_id)) - raise exceptions.TempestException(message) + if len(body['regions']) != 0: + message = \ + 'Failed to delete regions for customer %s' % customer_id + raise exceptions.TimeoutException(message) - @classmethod - def _wait_for_customer_deletion_on_dcp(cls, customer_id): - _, body = cls.cms_client.list_customers() - customer_list = body["customers"] - customer_ids = [customer["id"] - for customer in customer_list - if customer["id"] == customer_id] - start = int(time.time()) - while customer_ids: - time.sleep(cls.build_interval) - _, body = cls.cms_client.list_customers()["customers"] - customer_list = body["customers"] - customer_ids = [customer["id"] - for customer in customer_list - if customer["id"] == customer_id] - if customer_ids: - customer_status = customer_ids[0]["status"] - if customer_status == 'Error': - message = "customer %s failed to get deleted and is in\ - error status" % customer_id - raise exceptions.TempestException(message) - if int(time.time()) - start >= cls.build_timeout: - message = ( - 'customer %s failed to get deleted within ' - 'the required time (%s s) and is in %s status.' - % (customer_id, cls.build_timeout, - customer_status)) - raise exceptions.TimeoutException(message) + cls.cms_client.delete_customer(customer_id) + cls._validate_customer_deletion_on_lcp(customer_id) @classmethod def _validate_customer_deletion_on_lcp(cls, customer_id): @@ -187,13 +154,13 @@ class FmsBaseOrmTest(base.BaseOrmTest): post_body["visibility"] = "private" if not public else "public" post_body['tag'] = {'a': 'b', 'c': 'd'} - if single_tenant: - post_body["tenants"] = [cls.tenant_id] - else: - post_body["tenants"] = [cls.tenant_id, cls.alt_tenant_id] - if public: post_body["tenants"] = [] + else: + if single_tenant: + post_body["tenants"] = [cls.tenant_id] + else: + post_body["tenants"] = [cls.tenant_id, cls.alt_tenant_id] return post_body @@ -216,19 +183,20 @@ class FmsBaseOrmTest(base.BaseOrmTest): _, body = cls.client.create_flavor(**kwargs) flavor = body["flavor"] flavor_id = flavor["id"] + _, body = cls.client.get_flavor(flavor_id) flavor_detail = body["flavor"] - if flavor_detail["vcpus"] == kwargs["vcpus"]: - if flavor_detail["regions"] == []: - flavor_status = "no regions" - else: - flavor_status = "Success" + + if flavor_detail["vcpus"] != kwargs["vcpus"]: + message = "Flavor %s not created successfully" % flavor_id + raise exceptions.TempestException(message) + + if flavor_detail["regions"] != []: flavor_id = flavor_detail["id"] - cls._wait_for_flavor_status_on_dcp(flavor_id, flavor_status) + cls._wait_for_flavor_status_on_dcp(flavor_id, 'Success') cls._validate_flavor_creation_on_lcp(flavor_id) - return flavor - message = "flavor %s not created successfully" % flavor_id - raise exceptions.TempestException(message) + + return flavor @classmethod def _wait_for_flavor_status_on_dcp(cls, flavor_id, status): @@ -241,13 +209,22 @@ class FmsBaseOrmTest(base.BaseOrmTest): _, body = cls.client.get_flavor(flavor_id) flavor = body["flavor"] flavor_status = flavor["status"] + if flavor_status == 'Error': - message = ('flavor %s failed to reach %s status' - ' and is in ERROR status' % - (flavor_id, status)) - raise exceptions.TempestException(message) + # Some test cases have multiple regions + message = "" + for region in flavor["regions"]: + if "error_message" in region: + message += "Region %s Error: %s. " % ( + region["name"], region["error_message"]) + + if not message: + message = ('Flavor %s failed to reach %s status' + ' and is in ERROR status' % (flavor_id, status)) + raise exceptions.ServerFault(message) + if int(time.time()) - start >= cls.build_timeout: - message = ('flavor %s failed to reach %s status within' + message = ('Flavor %s failed to reach %s status within' ' the required time (%s s) and is in' ' %s status.') % (flavor_id, status, cls.build_timeout, @@ -301,26 +278,25 @@ class FmsBaseOrmTest(base.BaseOrmTest): cls, flavor_id, rname): cls.client.delete_region_from_flavor(flavor_id, rname) - time.sleep(cls.build_interval) _, body = cls.client.get_flavor(flavor_id) loopcount = 0 while loopcount < 10: + if len(body['flavor']['regions']) == 0: + break for regions_on_flavor in body['flavor']['regions']: if regions_on_flavor['name'] == rname: time.sleep(cls.build_interval) _, body = cls.client.get_flavor(flavor_id) - continue + break loopcount += 1 - _, body = cls.client.get_flavor(flavor_id) - for regions_on_flavor in body['flavor']['regions']: if regions_on_flavor['name'] == rname: message = \ 'Region {} failed to get deleted from flavor {}' \ .format(rname, flavor_id) - raise exceptions.TempestException(message) + raise exceptions.TimeoutException(message) @classmethod def _wait_for_flavor_deletion_on_dcp(cls, flavor_id): diff --git a/ranger_tempest_plugin/tests/api/ims_base.py b/ranger_tempest_plugin/tests/api/ims_base.py index 39c1640..96dcd0f 100755 --- a/ranger_tempest_plugin/tests/api/ims_base.py +++ b/ranger_tempest_plugin/tests/api/ims_base.py @@ -98,17 +98,15 @@ class ImsBaseOrmTest(base.BaseOrmTest): _, body = cls.client.get_image(image_id) image_detail = body["image"] - if image_detail["name"] == kwargs["name"]: - if image_detail["regions"] == []: - image_status = "no regions" - else: - image_status = "Success" - cls._wait_for_image_status_on_dcp(image_id, image_status) - return image + if image_detail["name"] != kwargs["name"]: + message = ('Image %s not created successfully' % kwargs["name"]) + raise exceptions.TempestException(message) - message = ('image %s not created successfully' % kwargs["name"]) - raise exceptions.TempestException(message) + if image_detail["regions"] != []: + cls._wait_for_image_status_on_dcp(image_id, 'Success') + + return image @classmethod def _wait_for_image_status_on_dcp(cls, image_id, status): @@ -124,15 +122,21 @@ class ImsBaseOrmTest(base.BaseOrmTest): break if image_status == 'Error': - message = ('Image %s failed to reach %s status' - ' and is in ERROR status on orm' % - (image_id, status)) - raise exceptions.TempestException(message) + # Some test cases have multiple regions + message = "" + for region in body["image"]["regions"]: + if "error_message" in region: + message += "Region %s Error: %s. " % ( + region["name"], region["error_message"]) + if not message: + message = ('Image %s failed to reach %s status' + ' and is in ERROR status' % (image_id, status)) + raise exceptions.ServerFault(message) if int(time.time()) - start >= cls.image_build_timeout: message = ('Image %s failed to reach %s' - ' status within ''the required time (%s s)' - ' on orm and is in %s status.' + ' status within the required time (%s s)' + ' and is in %s status.' % (image_id, status, cls.image_build_timeout, image_status)) diff --git a/ranger_tempest_plugin/tests/api/rms_base.py b/ranger_tempest_plugin/tests/api/rms_base.py index e5e4dc6..fb31d70 100755 --- a/ranger_tempest_plugin/tests/api/rms_base.py +++ b/ranger_tempest_plugin/tests/api/rms_base.py @@ -120,21 +120,30 @@ class RmsBaseOrmTest(base.BaseOrmTest): @classmethod def _wait_for_status(cls, customer_id, status): - customer_status = cls.cms_client.get_customer(customer_id)[1]['status'] + _, customer = cls.cms_client.get_customer(customer_id) + customer_status = customer["status"] start = int(time.time()) while customer_status != status: time.sleep(cls.build_interval) - customer_status = cls.cms_client.get_customer( - customer_id)[1]['status'] + _, customer = cls.cms_client.get_customer(customer_id) + customer_status = customer["status"] + if customer_status == 'Error': - message = ('customer %s failed to reach %s status' - ' and is in ERROR status on orm' % - (customer_id, status)) - raise exceptions.TempestException(message) + message = "" + for region in customer["regions"]: + if "error_message" in region: + message += "Region %s Error: %s. " % ( + region["name"], region["error_message"]) + + if not message: + message = ('Customer %s failed to reach %s status and is' + ' in ERROR status' % (customer_id, status)) + raise exceptions.ServerFault(message) + if int(time.time()) - start >= cls.build_timeout: - message = ('customer %s failed to reach %s' + message = ('Customer %s failed to reach %s' 'status within the required time (%s s)' - 'on orm and is in %s status.' + 'and is in %s status.' % (customer_id, status, cls.build_timeout, customer_status)) diff --git a/ranger_tempest_plugin/tests/api/test_customers.py b/ranger_tempest_plugin/tests/api/test_customers.py index 6d2a238..eacc049 100755 --- a/ranger_tempest_plugin/tests/api/test_customers.py +++ b/ranger_tempest_plugin/tests/api/test_customers.py @@ -49,12 +49,8 @@ class TestTempestCms(cms_base.CmsBaseOrmTest): def _create_customer(self, post_body, cleanup=True): if post_body.get('uuid') is None: post_body['uuid'] = uuid.uuid4().hex - if cleanup: - self.addCleanup( - self._del_cust_validate_deletion_on_dcp_and_lcp, - post_body['uuid']) customer_id = self._create_cust_validate_creation_on_dcp_and_lcp( - **post_body) + cleanup, **post_body) return customer_id diff --git a/ranger_tempest_plugin/tests/api/test_flavors.py b/ranger_tempest_plugin/tests/api/test_flavors.py index a0a7dd8..524bb7e 100755 --- a/ranger_tempest_plugin/tests/api/test_flavors.py +++ b/ranger_tempest_plugin/tests/api/test_flavors.py @@ -43,12 +43,14 @@ class TestTempestFms(fms_base.FmsBaseOrmTest): @classmethod def resource_setup(cls): + super(TestTempestFms, cls).resource_setup() + # create customers for private flavor test cases + cls.tenant_id = cls._create_customer() + cls.alt_tenant_id = cls._create_customer() + # create flavor for use in test cases body = cls._get_flavor_params() - cls.addClassResourceCleanup( - cls._del_flv_and_validate_deletion_on_dcp_and_lcp, - body['id']) cls.flavor = cls._create_flv_and_validate_creation_on_dcp_and_lcp( **body) @@ -58,6 +60,14 @@ class TestTempestFms(fms_base.FmsBaseOrmTest): cls._wait_for_flavor_status_on_dcp(cls.flavor['id'], 'Success') cls.tags = cls.client.get_tags(cls.flavor['id']) + @classmethod + def resource_cleanup(cls): + cls._del_flv_and_validate_deletion_on_dcp_and_lcp(cls.flavor['id']) + cls._del_cust_validate_deletion_on_dcp_and_lcp(cls.tenant_id) + cls._del_cust_validate_deletion_on_dcp_and_lcp(cls.alt_tenant_id) + + super(TestTempestFms, cls).resource_cleanup() + def _get_flavor_details(self, flavor_id): _, body = self.client.get_flavor(flavor_id) return body["flavor"] @@ -74,11 +84,11 @@ class TestTempestFms(fms_base.FmsBaseOrmTest): return group_id def _data_setup(self, post_body): + flavor = self._create_flv_and_validate_creation_on_dcp_and_lcp( + **post_body) self.addCleanup( self._del_flv_and_validate_deletion_on_dcp_and_lcp, post_body['id']) - flavor = self._create_flv_and_validate_creation_on_dcp_and_lcp( - **post_body) return flavor def _exec_tags_function(self, flavor_id, req_json, action, para): diff --git a/ranger_tempest_plugin/tests/api/test_images.py b/ranger_tempest_plugin/tests/api/test_images.py index 2262647..d649686 100644 --- a/ranger_tempest_plugin/tests/api/test_images.py +++ b/ranger_tempest_plugin/tests/api/test_images.py @@ -51,23 +51,24 @@ class TestTempestIms(ims_base.ImsBaseOrmTest): cls.image_params_shared = \ cls._get_image_params(set_enabled=False) - cls.addClassResourceCleanup( - cls._del_img_validate_deletion_on_dcp_and_lcp, - cls.image_params_public['id']) - cls.addClassResourceCleanup( - cls._del_img_validate_deletion_on_dcp_and_lcp, - cls.image_params_shared['id']) - # setup public image for tempest testing cls.public_image = \ cls._create_img_and_validate_creation_on_dcp_and_lcp( **cls.image_params_public) + cls.addClassResourceCleanup( + cls._del_img_validate_deletion_on_dcp_and_lcp, + cls.image_params_public['id']) + # setup shared image for tempest testing cls.shared_image = \ cls._create_img_and_validate_creation_on_dcp_and_lcp( **cls.image_params_shared) + cls.addClassResourceCleanup( + cls._del_img_validate_deletion_on_dcp_and_lcp, + cls.image_params_shared['id']) + def _update_region(self, region_name, status=None): if status is None: status = {'status': 'functional'} @@ -75,11 +76,11 @@ class TestTempestIms(ims_base.ImsBaseOrmTest): region_name, status) def _data_setup(self, post_body): + image = self._create_img_and_validate_creation_on_dcp_and_lcp( + **post_body) self.addCleanup( self._del_img_validate_deletion_on_dcp_and_lcp, post_body['id']) - image = self._create_img_and_validate_creation_on_dcp_and_lcp( - **post_body) # only check for Success image status if "regions" is not empty if image["regions"]: self._wait_for_image_status_on_dcp(image['id'], 'Success')