Enhancement of Fail Response Parameters

- Added support for all necessary response
  parameters for Fail API

- UT and FT assertion is also improved to
  be able to confirm these response params

Implements: blueprint support-error-handling
Spec: https://specs.openstack.org/openstack/tacker-specs/specs/wallaby/support-error-handling-based-on-ETSI-NFV.html
Change-Id: I31b179a9f9703432c4e38eb29da9140311841e2f
This commit is contained in:
Aldinson Esto 2021-03-02 04:14:09 +09:00 committed by Aldinson C. Esto
parent 87ea725784
commit ef8d4727e8
3 changed files with 159 additions and 1 deletions

View File

@ -1300,6 +1300,7 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest):
resp, _ = self._fail_op_occs(vnflcm_op_occ_id) resp, _ = self._fail_op_occs(vnflcm_op_occ_id)
self._wait_lcm_done('FAILED', vnf_instance_id=vnf_instance_id) self._wait_lcm_done('FAILED', vnf_instance_id=vnf_instance_id)
self.assert_fail_vnf(resp, vnf_instance_id) self.assert_fail_vnf(resp, vnf_instance_id)
self._assert_fail_vnf_response(_)
# occ-show # occ-show
resp, op_occs_info = self._show_op_occs(vnflcm_op_occ_id) resp, op_occs_info = self._show_op_occs(vnflcm_op_occ_id)
@ -1412,6 +1413,7 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest):
resp, _ = self._fail_op_occs(vnflcm_op_occ_id) resp, _ = self._fail_op_occs(vnflcm_op_occ_id)
self._wait_lcm_done('FAILED', vnf_instance_id=vnf_instance_id) self._wait_lcm_done('FAILED', vnf_instance_id=vnf_instance_id)
self.assert_fail_vnf(resp, vnf_instance_id) self.assert_fail_vnf(resp, vnf_instance_id)
self._assert_fail_vnf_response(_)
# occ-show # occ-show
resp, op_occs_info = self._show_op_occs(vnflcm_op_occ_id) resp, op_occs_info = self._show_op_occs(vnflcm_op_occ_id)
@ -1613,3 +1615,51 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest):
self.assertIsNotNone(_links.get('vnfInstance').get('href')) self.assertIsNotNone(_links.get('vnfInstance').get('href'))
self.assertIsNotNone(_links.get('grant')) self.assertIsNotNone(_links.get('grant'))
self.assertIsNotNone(_links.get('grant').get('href')) self.assertIsNotNone(_links.get('grant').get('href'))
def _assert_fail_vnf_response(self, fail_response):
# Only check parameters with cardinality = 1
self.assertIsNotNone(fail_response.get('id'))
self.assertIsNotNone(fail_response.get('operationState'))
self.assertIsNotNone(fail_response.get('stateEnteredTime'))
self.assertIsNotNone(fail_response.get('startTime'))
self.assertIsNotNone(fail_response.get('vnfInstanceId'))
self.assertIsNotNone(fail_response.get('operation'))
self.assertIsNotNone(fail_response.get('isAutomaticInvocation'))
self.assertIsNotNone(fail_response.get('isCancelPending'))
changed_ext_connectivity = fail_response.get(
'changedExtConnectivity', None)
if changed_ext_connectivity is not None:
self.assertIsNotNone(
changed_ext_connectivity._get_changed_ext_connectivity('id'))
resource_handle = \
changed_ext_connectivity._get_changed_ext_connectivity(
'resourceHandle')
self.assertIsNotNone(resource_handle)
self.assertIsNotNone(resource_handle.get('resourceId'))
ext_link_ports = \
changed_ext_connectivity._get_changed_ext_connectivity(
'extLinkPorts', None)
if ext_link_ports is not None:
self.assertIsNotNone(ext_link_ports.get('id'))
ext_link_ports_resource_handle = ext_link_ports.get(
'resourceHandle')
self.assertIsNotNone(ext_link_ports_resource_handle)
self.assertIsNotNone(ext_link_ports_resource_handle.get(
'resourceId'))
self.assertIsNotNone(ext_link_ports.get('cpInstanceId'))
_links = fail_response.get('_links')
self.assertIsNotNone(_links.get('self'))
self.assertIsNotNone(_links.get('self').get('href'))
self.assertIsNotNone(_links.get('vnfInstance'))
self.assertIsNotNone(_links.get('vnfInstance').get('href'))
if _links.get('retry') is not None:
self.assertIsNotNone(_links.get('retry').get('href'))
if _links.get('fail') is not None:
self.assertIsNotNone(_links.get('fail').get('href'))
if _links.get('rollback') is not None:
self.assertIsNotNone(_links.get('rollback').get('href'))
if _links.get('grant') is not None:
self.assertIsNotNone(_links.get('grant').get('href'))

View File

@ -908,6 +908,20 @@ def vnflcm_rollback_insta(error_point=7):
def vnflcm_fail_insta(error_point=7): def vnflcm_fail_insta(error_point=7):
default_datetime = datetime.datetime( default_datetime = datetime.datetime(
2000, 1, 1, 1, 1, 1, tzinfo=iso8601.UTC) 2000, 1, 1, 1, 1, 1, tzinfo=iso8601.UTC)
ext_link_port_info = objects.ExtLinkPortInfo(
resource_handle=objects.ResourceHandle(
resource_id="109f5049-b51e-409a-9a99-d740ba5f3acb",
vim_level_resource_type="LINKPORT"),
cp_instance_id="f5c68d94-5736-4e38-ade5-c9462514f8b9",
id="1d868d02-ecd4-4402-8e6b-54e77ebdcc28")
changed_ext_connectivity_values = objects.ExtVirtualLinkInfo(
id=constants.UUID,
resource_handle=objects.ResourceHandle(
vim_connection_id=constants.UUID,
resource_id=constants.UUID,
vim_level_resource_type="OS::Neutron::Net"),
ext_link_ports=[ext_link_port_info]
)
return objects.VnfLcmOpOcc( return objects.VnfLcmOpOcc(
state_entered_time=default_datetime, state_entered_time=default_datetime,
start_time=default_datetime, start_time=default_datetime,
@ -918,7 +932,51 @@ def vnflcm_fail_insta(error_point=7):
operation_params='{}', operation_params='{}',
error_point=error_point, error_point=error_point,
id=constants.UUID, id=constants.UUID,
created_at=default_datetime) grant_id=constants.UUID,
created_at=default_datetime,
changed_ext_connectivity=[changed_ext_connectivity_values])
def vnflcm_fail_check_added_params(error_point=7):
ext_link_port_info = objects.ExtLinkPortInfo(
resource_handle=objects.ResourceHandle(
resource_id="109f5049-b51e-409a-9a99-d740ba5f3acb",
vim_level_resource_type="LINKPORT"),
cp_instance_id="f5c68d94-5736-4e38-ade5-c9462514f8b9",
id="1d868d02-ecd4-4402-8e6b-54e77ebdcc28")
changed_ext_connectivity_values = objects.ExtVirtualLinkInfo(
id=constants.UUID,
resource_handle=objects.ResourceHandle(
vim_connection_id=constants.UUID,
resource_id=constants.UUID,
vim_level_resource_type="OS::Neutron::Net"),
ext_link_ports=[ext_link_port_info]
)
changed_info_values = objects.VnfInfoModifications(
vnf_instance_name="fake_name",
vnf_instance_description="fake_vnf_instance_description",
vnfd_id="f26f181d-7891-4720-b022-b074ec1733ef",
vnf_provider="fake_vnf_provider",
vnf_product_name="fake_vnf_product_name",
vnf_software_version="fake_vnf_software_version",
vnfd_version="fake_vnfd_version")
return objects.VnfLcmOpOcc(
state_entered_time=datetime.datetime(2000, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
start_time=datetime.datetime(2000, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
vnf_instance_id=constants.UUID,
operation='INSTANTIATE',
operation_state='FAILED_TEMP',
is_automatic_invocation=False,
operation_params='{}',
error_point=error_point,
id=constants.UUID,
grant_id=constants.UUID,
created_at=datetime.datetime(2000, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
changed_ext_connectivity=[changed_ext_connectivity_values],
changed_info=changed_info_values)
def vnflcm_rollback_active(): def vnflcm_rollback_active():

View File

@ -14,6 +14,7 @@
# under the License. # under the License.
import codecs import codecs
import copy
import ddt import ddt
from http import client as http_client from http import client as http_client
import json import json
@ -3504,3 +3505,52 @@ class TestController(base.TestCase):
mock_op_occ_list.return_value = vnf_lcm_op_occ mock_op_occ_list.return_value = vnf_lcm_op_occ
self.assertRaises( self.assertRaises(
exceptions.ValidationError, self.controller.list_lcm_op_occs, req) exceptions.ValidationError, self.controller.list_lcm_op_occs, req)
@mock.patch.object(controller.VnfLcmController,
"_update_vnf_fail_status")
@mock.patch.object(objects.VnfInstance, "save")
@mock.patch.object(objects.VnfInstance, "get_by_id")
@mock.patch.object(objects.VnfLcmOpOcc, "save")
@mock.patch.object(objects.VnfLcmOpOcc, "get_by_id")
def test_fail_lcm_op_occs_changed_info_missing(self, mock_lcm_get_by_id,
mock_lcm_save, mock_vnf_get_by_id,
mock_vnf_save, mock_update):
req = fake_request.HTTPRequest.blank(
'/vnf_lcm_op_occs/%s/fail' % constants.UUID)
mock_lcm_get_by_id.return_value = \
fakes.vnflcm_fail_insta()
res_dict = self.controller.fail(req, constants.UUID)
ref_dict = copy.deepcopy(fakes.VNFLCMOPOCC_RESPONSE)
del ref_dict["changedInfo"]
self.assertEqual(ref_dict.keys(), res_dict.keys())
mock_lcm_get_by_id.assert_called_once()
mock_vnf_get_by_id.assert_called_once()
@mock.patch.object(controller.VnfLcmController,
"_update_vnf_fail_status")
@mock.patch.object(objects.VnfInstance, "save")
@mock.patch.object(objects.VnfInstance, "get_by_id")
@mock.patch.object(objects.VnfLcmOpOcc, "save")
@mock.patch.object(objects.VnfLcmOpOcc, "get_by_id")
def test_fail_lcm_op_occs_check_added_params(self, mock_lcm_get_by_id,
mock_lcm_save, mock_vnf_get_by_id,
mock_vnf_save, mock_update):
req = fake_request.HTTPRequest.blank(
'/vnf_lcm_op_occs/%s/fail' % constants.UUID)
mock_lcm_get_by_id.return_value = \
fakes.vnflcm_fail_check_added_params()
res_dict = self.controller.fail(req, constants.UUID)
ref_dict = fakes.VNFLCMOPOCC_RESPONSE
self.assertEqual(ref_dict.keys(), res_dict.keys())
self.assertEqual(
res_dict.get('changedInfo').keys(),
ref_dict.get('changedInfo').keys())
self.assertEqual(
res_dict.get('_links').keys(),
ref_dict.get('_links').keys())
mock_lcm_get_by_id.assert_called_once()
mock_vnf_get_by_id.assert_called_once()