Support of version 2.4.1 on Modify VNF

Version 2.4.1 of Modify VNF is supported.

Implements: blueprint support-etsi-nfv-specs
Spec: https://specs.openstack.org/openstack/tacker-specs/specs/victoria/enhancement_enhance-vnf-lcm-api-support.html

Change-Id: I6dd978463511672bc26034cc3ff339bd92090c33
This commit is contained in:
Aldinson Esto 2020-08-25 19:03:59 +09:00 committed by Aldinson C. Esto
parent 797554a378
commit e29026f3fc
13 changed files with 465 additions and 371 deletions

View File

@ -611,6 +611,7 @@ Request Parameters
- vnfInstanceName: vnf_instance_modify_request_name
- vnfInstanceDescription: vnf_instance_modify_request_description
- vnfdId: vnf_instance_modify_request_vnfd_id
- vnfPkgId: vnf_instance_modify_request_vnf_pkg_id
- metadata: vnf_instance_modify_request_metadata
- vimConnectionInfo: vnf_instance_modify_request_vim_connection_info
- id: vim_connection_info_id

View File

@ -600,8 +600,9 @@ class VnfLcmController(wsgi.Controller):
self._instantiate(context, vnf_instance, vnf, body)
@check_vnf_state(action="terminate",
instantiation_state=[fields.VnfInstanceState.INSTANTIATED],
task_state=[None])
instantiation_state=[
fields.VnfInstanceState.INSTANTIATED],
task_state=[None])
def _terminate(self, context, vnf_instance, request_body, vnf):
req_body = utils.convert_camelcase_to_snakecase(request_body)
terminate_vnf_req = \
@ -641,8 +642,9 @@ class VnfLcmController(wsgi.Controller):
req_body = utils.convert_camelcase_to_snakecase(request_body)
heal_vnf_request = objects.HealVnfRequest(context=context, **req_body)
inst_vnf_info = vnf_instance.instantiated_vnf_info
vnfc_resource_info_ids = [vnfc_resource_info.id for
vnfc_resource_info in inst_vnf_info.vnfc_resource_info]
vnfc_resource_info_ids = [
vnfc_resource_info.id for vnfc_resource_info in
inst_vnf_info.vnfc_resource_info]
for vnfc_id in heal_vnf_request.vnfc_instance_id:
# check if vnfc_id exists in vnfc_resource_info
@ -702,7 +704,13 @@ class VnfLcmController(wsgi.Controller):
context.can(vnf_lcm_policies.VNFLCM % 'update_vnf')
# get body
req_body = utils.convert_camelcase_to_snakecase(body)
body_data = {}
body_data['vnf_instance_name'] = body.get('vnfInstanceName')
body_data['vnf_instance_description'] = body.get(
'vnfInstanceDescription')
body_data['vnfd_id'] = body.get('vnfdId')
if (body.get('vnfdId') is None and body.get('vnfPkgId')):
body_data['vnf_pkg_id'] = body.get('vnfPkgId')
# According to the ETSI NFV SOL document,
# there is no API request/response
@ -725,8 +733,12 @@ class VnfLcmController(wsgi.Controller):
if (vnf_data.get("status") != fields.VnfStatus.ACTIVE and
vnf_data.get("status") != fields.VnfStatus.INACTIVE):
msg = _("VNF %(id)s status is %(state)s")
return self._make_problem_detail(msg % {"id": id,
"state": vnf_data.get("status")}, 409, 'Conflict')
return self._make_problem_detail(
msg % {
"id": id,
"state": vnf_data.get("status")},
409,
'Conflict')
try:
vnf_instance_data = objects.VnfInstanceList.vnf_instance_list(
@ -739,19 +751,27 @@ class VnfLcmController(wsgi.Controller):
return self._make_problem_detail(
str(e), 500, 'Internal Server Error')
if req_body['vnfd_id']:
vnfd_pkg_data = {}
if (body_data.get('vnfd_id') or body_data.get('vnf_pkg_id')):
try:
pkg_obj = objects.VnfPackageVnfd(context=context)
vnfd_pkg = pkg_obj.get_vnf_package_vnfd(req_body['vnfd_id'])
if (body_data.get('vnfd_id')):
input_id = 'vnfd_id'
vnfd_pkg = pkg_obj.get_vnf_package_vnfd(
body_data[input_id])
elif (body_data.get('vnf_pkg_id')):
input_id = 'vnf_pkg_id'
vnfd_pkg = pkg_obj.get_vnf_package_vnfd(
body_data[input_id], package_uuid=True)
if not vnfd_pkg:
msg = _(
"Can not find requested vnf package vnfd: %s") %\
req_body['vnfd_id']
body_data[input_id]
return self._make_problem_detail(msg, 400, 'Bad Request')
except Exception as e:
return self._make_problem_detail(
str(e), 500, 'Internal Server Error')
vnfd_pkg_data = {}
vnfd_pkg_data['vnf_provider'] = vnfd_pkg.get('vnf_provider')
vnfd_pkg_data['vnf_product_name'] = vnfd_pkg.get(
'vnf_product_name')
@ -759,13 +779,12 @@ class VnfLcmController(wsgi.Controller):
'vnf_software_version')
vnfd_pkg_data['vnfd_version'] = vnfd_pkg.get('vnfd_version')
vnfd_pkg_data['package_uuid'] = vnfd_pkg.get('package_uuid')
vnfd_pkg_data['vnfd_id'] = vnfd_pkg.get('vnfd_id')
# make op_occs_uuid
op_occs_uuid = uuidutils.generate_uuid()
# process vnf
if not req_body['vnfd_id']:
vnfd_pkg_data = ""
vnf_lcm_opoccs = {
'vnf_instance_id': id,
'id': op_occs_uuid,
@ -775,7 +794,7 @@ class VnfLcmController(wsgi.Controller):
self.rpc_api.update(
context,
vnf_lcm_opoccs,
req_body,
body_data,
vnfd_pkg_data,
vnf_data.get('vnfd_id'))

View File

@ -475,8 +475,8 @@ class Conductor(manager.Manager):
except (store_exceptions.GlanceStoreException) as e:
exc_msg = encodeutils.exception_to_unicode(e)
msg = (_("Exception raised from glance store can be "
"unrecoverable if it is not related to connection"
" error. Error: %s.") % exc_msg)
"unrecoverable if it is not related to connection"
" error. Error: %s.") % exc_msg)
raise exceptions.FailedToGetVnfdData(error=msg)
try:
return self._read_vnfd_files(csar_path)
@ -1241,18 +1241,15 @@ class Conductor(manager.Manager):
raise Exception(str(msg))
# update lcm_op_occs
changed_info = objects.vnf_lcm_op_occs.VnfInfoModifications()
changed_info.vnf_instance_name = body_data.get('vnf_instance_name')
changed_info.vnf_instance_description = body_data.get(
'vnf_instance_description')
if body_data.get('vnfd_id'):
changed_info.vnfd_id = body_data.get('vnfd_id')
changed_info.vnf_provider = vnfd_pkg_data.get('vnf_provider')
changed_info.vnf_product_name = vnfd_pkg_data.get(
'vnf_product_name')
changed_info.vnf_software_version = vnfd_pkg_data.get(
'vnf_software_version')
changed_info.vnfd_version = vnfd_pkg_data.get('vnfd_version')
if vnfd_pkg_data and len(vnfd_pkg_data) > 0:
changed_info = \
objects.vnf_lcm_op_occs.VnfInfoModifications._from_dict(
vnfd_pkg_data)
else:
changed_info = objects.vnf_lcm_op_occs.VnfInfoModifications()
changed_info.vnf_instance_name = body_data.get('vnf_instance_name')
changed_info.vnf_instance_description = body_data.get(
'vnf_instance_description')
# update vnf_lcm_op_occs
now = timeutils.utcnow()

View File

@ -85,6 +85,26 @@ class VNFLcmRPCAPI(object):
vnfd_pkg_data=vnfd_pkg_data,
vnfd_id=vnfd_id)
def update_vnf_instance_content(
self,
context,
vnf_lcm_opoccs,
body_data,
vnfd_pkg_data,
vnfd_id,
cast=True):
serializer = objects_base.TackerObjectSerializer()
client = rpc.get_client(self.target, version_cap=None,
serializer=serializer)
cctxt = client.prepare()
rpc_method = cctxt.cast if cast else cctxt.call
return rpc_method(context, 'update_lcm',
vnf_lcm_opoccs=vnf_lcm_opoccs,
body_data=body_data,
vnfd_pkg_data=vnfd_pkg_data,
vnfd_id=vnfd_id)
def send_notification(self, context, notification, cast=True):
serializer = objects_base.TackerObjectSerializer()

View File

@ -80,6 +80,19 @@ class VnfSoftwareImage(model_base.BASE, models.SoftDeleteMixin,
return {m.key: m.value for m in self._metadata}
class VnfArtifactMetadata(model_base.BASE, models.SoftDeleteMixin,
models.TimestampMixin):
"""Contains all info about vnf packages artifacts metadata."""
__tablename__ = 'vnf_artifact_metadata'
id = sa.Column(sa.Integer, nullable=False, primary_key=True)
artifact_uuid = sa.Column(sa.String(36),
sa.ForeignKey('vnf_artifacts.id'),
nullable=False)
key = sa.Column(sa.String(255), nullable=False)
value = sa.Column(sa.String(255), nullable=False)
class VnfDeploymentFlavour(model_base.BASE, models.SoftDeleteMixin,
models.TimestampMixin, models_v1.HasId):
"""Contains all info about vnf packages Deployment Flavours."""
@ -115,7 +128,9 @@ class VnfPackageVnfd(model_base.BASE, VnfPackageVnfdSoftDeleteMixin,
__tablename__ = 'vnf_package_vnfd'
__table_args__ = (
sa.schema.UniqueConstraint("vnfd_id", "deleted",
sa.schema.UniqueConstraint(
"vnfd_id",
"deleted",
name="uniq_vnf_package_vnfd0vnfd_id0deleted"),
)
@ -201,6 +216,7 @@ class VnfInstance(model_base.BASE, models.SoftDeleteMixin,
task_state = sa.Column(sa.String(255), nullable=True)
vim_connection_info = sa.Column(sa.JSON(), nullable=True)
tenant_id = sa.Column('tenant_id', sa.String(length=64), nullable=False)
vnf_pkg_id = sa.Column(types.Uuid, nullable=False)
vnf_metadata = sa.Column(sa.JSON(), nullable=True)
@ -211,8 +227,8 @@ class VnfInstantiatedInfo(model_base.BASE, models.SoftDeleteMixin,
__tablename__ = 'vnf_instantiated_info'
id = sa.Column(sa.Integer, primary_key=True, autoincrement=True)
vnf_instance_id = sa.Column(sa.String,
sa.ForeignKey('vnf_instances.id'),
nullable=False)
sa.ForeignKey('vnf_instances.id'),
nullable=False)
flavour_id = sa.Column(sa.String(255), nullable=False)
ext_cp_info = sa.Column(sa.JSON(), nullable=False)
ext_virtual_link_info = sa.Column(sa.JSON(), nullable=True)
@ -226,8 +242,11 @@ class VnfInstantiatedInfo(model_base.BASE, models.SoftDeleteMixin,
instantiation_level_id = sa.Column(sa.String(255), nullable=True)
additional_params = sa.Column(sa.JSON(), nullable=True)
vnf_instance = orm.relationship(VnfInstance,
backref=orm.backref('instantiated_vnf_info', uselist=False),
vnf_instance = orm.relationship(
VnfInstance,
backref=orm.backref(
'instantiated_vnf_info',
uselist=False),
foreign_keys=vnf_instance_id,
primaryjoin='and_(VnfInstantiatedInfo.vnf_instance_id == '
'VnfInstance.id, VnfInstantiatedInfo.deleted == 0)')
@ -264,8 +283,8 @@ class VnfLcmFilters(model_base.BASE):
__maxsize__ = 65536
id = sa.Column(sa.Integer, nullable=True, primary_key=True)
subscription_uuid = sa.Column(sa.String(36),
sa.ForeignKey('vnf_lcm_subscriptions.id'),
nullable=False)
sa.ForeignKey('vnf_lcm_subscriptions.id'),
nullable=False)
filter = sa.Column(sa.JSON, nullable=False)
notification_types = sa.Column(sa.VARBINARY(255), nullable=True)
notification_types_len = sa.Column(sa.Integer, nullable=True)

View File

@ -238,24 +238,30 @@ def _update_vnf_instances(
updated_values['vim_connection_info'] = merge_vim_connection_info
if body_data.get('vnfd_id'):
updated_values['vnfd_id'] = body_data.get('vnfd_id')
if vnfd_pkg_data and len(vnfd_pkg_data) > 0:
updated_values['vnfd_id'] = vnfd_pkg_data.get('vnfd_id')
updated_values['vnf_provider'] = vnfd_pkg_data.get('vnf_provider')
updated_values['vnf_product_name'] = vnfd_pkg_data.get(
'vnf_product_name')
updated_values['vnf_software_version'] = vnfd_pkg_data.get(
'vnf_software_version')
updated_values['vnf_pkg_id'] = vnfd_pkg_data.get('package_uuid')
api.model_query(context, models.VnfInstance). \
filter_by(id=vnf_lcm_opoccs.get('vnf_instance_id')). \
update(updated_values, synchronize_session=False)
vnf_now = timeutils.utcnow()
if body_data.get('vnfd_id'):
if (body_data.get('vnfd_id') or body_data.get('vnf_pkg_id')):
# update vnf
updated_values = {'vnfd_id': body_data.get('vnfd_id'),
'updated_at': vnf_now
}
if body_data.get('vnfd_id'):
updated_values = {'vnfd_id': body_data.get('vnfd_id'),
'updated_at': vnf_now
}
elif body_data.get('vnf_pkg_id'):
updated_values = {'vnfd_id': vnfd_pkg_data.get('vnfd_id'),
'updated_at': vnf_now
}
api.model_query(context, vnfm_db.VNF).\
filter_by(id=vnf_lcm_opoccs.get('vnf_instance_id')). \
update(updated_values, synchronize_session=False)
@ -308,7 +314,9 @@ class VnfInstance(base.TackerObject, base.TackerPersistentObject,
'id': fields.UUIDField(nullable=False),
'vnf_instance_name': fields.StringField(nullable=True),
'vnf_instance_description': fields.StringField(nullable=True),
'instantiation_state': fields.VnfInstanceStateField(nullable=False,
'instantiation_state':
fields.VnfInstanceStateField(
nullable=False,
default=fields.VnfInstanceState.NOT_INSTANTIATED),
'task_state': fields.StringField(nullable=True, default=None),
'vnfd_id': fields.StringField(nullable=False),
@ -320,6 +328,7 @@ class VnfInstance(base.TackerObject, base.TackerPersistentObject,
'VimConnectionInfo', nullable=True, default=[]),
'tenant_id': fields.StringField(nullable=False),
'vnf_metadata': fields.DictOfStringsField(nullable=True, default={}),
'vnf_pkg_id': fields.StringField(nullable=False),
'instantiated_vnf_info': fields.ObjectField('InstantiatedVnfInfo',
nullable=True, default=None)
}
@ -367,8 +376,8 @@ class VnfInstance(base.TackerObject, base.TackerPersistentObject,
setattr(vnf_instance, key, db_vnf_instance[key])
VnfInstance._load_instantiated_vnf_info_from_db_object(context,
vnf_instance, db_vnf_instance)
VnfInstance._load_instantiated_vnf_info_from_db_object(
context, vnf_instance, db_vnf_instance)
vim_connection_info = db_vnf_instance['vim_connection_info']
vim_connection_list = [objects.VimConnectionInfo.obj_from_primitive(
@ -384,9 +393,8 @@ class VnfInstance(base.TackerObject, base.TackerPersistentObject,
def _load_instantiated_vnf_info_from_db_object(context, vnf_instance,
db_vnf_instance):
if db_vnf_instance['instantiated_vnf_info']:
inst_vnf_info = \
objects.InstantiatedVnfInfo.obj_from_db_obj(context,
db_vnf_instance['instantiated_vnf_info'])
inst_vnf_info = objects.InstantiatedVnfInfo.obj_from_db_obj(
context, db_vnf_instance['instantiated_vnf_info'])
vnf_instance.instantiated_vnf_info = inst_vnf_info
@base.remotable
@ -440,8 +448,8 @@ class VnfInstance(base.TackerObject, base.TackerPersistentObject,
expected_attrs = ["instantiated_vnf_info"]
db_vnf_instance = _vnf_instance_update(self._context,
self.id, updates,
columns_to_join=expected_attrs)
self.id, updates,
columns_to_join=expected_attrs)
self._from_db_object(self._context, self, db_vnf_instance)
def _save_instantiated_vnf_info(self, context):
@ -481,7 +489,7 @@ class VnfInstance(base.TackerObject, base.TackerPersistentObject,
if (self.instantiation_state == fields.VnfInstanceState.INSTANTIATED
and self.instantiated_vnf_info):
data.update({'instantiated_vnf_info':
self.instantiated_vnf_info.to_dict()})
self.instantiated_vnf_info.to_dict()})
vim_connection_info_list = []
for vim_connection_info in self.vim_connection_info:

View File

@ -92,7 +92,7 @@ def _vnf_package_vnfd_get_by_id(context, vnfd_id):
read_deleted="no", project_only=False). \
filter_by(vnfd_id=vnfd_id).\
join((models.VnfPackage, models.VnfPackage.id ==
models.VnfPackageVnfd.package_uuid))
models.VnfPackageVnfd.package_uuid))
if tacker.context.is_user_context(context):
query = query.filter(models.VnfPackage.tenant_id == context.project_id)
@ -125,9 +125,9 @@ def _vnf_package_vnfd_get_by_packageId(context, packageId):
@db_api.context_manager.reader
def _vnf_package_vnfd_get_by_vnfdId(context, vnfdId):
query = api.model_query(context,
models.VnfPackageVnfd,
read_deleted="no",
project_only=True).filter_by(vnfd_id=vnfdId)
models.VnfPackageVnfd,
read_deleted="no",
project_only=True).filter_by(vnfd_id=vnfdId)
result = query.first()
@ -141,19 +141,19 @@ def _vnf_package_vnfd_get_by_vnfdId(context, vnfdId):
def _get_vnf_package_vnfd_by_vnfid(context, vnfpkgid):
sql = ("select"
" t1.vnfd_id,"
" t1.vnf_provider,"
" t1.vnf_product_name,"
" t1.vnf_software_version,"
" t1.vnfd_version,"
" t2.name"
" from "
" vnf_package_vnfd t1,"
" vnf t2 "
" where"
" t1.vnfd_id=t2.vnfd_id"
" and"
" t2.id= :vnfpkgid")
" t1.vnfd_id,"
" t1.vnf_provider,"
" t1.vnf_product_name,"
" t1.vnf_software_version,"
" t1.vnfd_version,"
" t2.name"
" from "
" vnf_package_vnfd t1,"
" vnf t2 "
" where"
" t1.vnfd_id=t2.vnfd_id"
" and"
" t2.id= :vnfpkgid")
result = context.session.execute(sql, {'vnfpkgid': vnfpkgid})
for line in result:

View File

@ -111,9 +111,9 @@ def get_lcm_op_occs_data():
'operation_state': 'PROCESSING',
'state_entered_time':
datetime.datetime(1900, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
tzinfo=iso8601.UTC),
'start_time': datetime.datetime(1900, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
tzinfo=iso8601.UTC),
'operation': 'MODIFY_INFO',
'is_automatic_invocation': 0,
'is_cancel_pending': 0,
@ -201,7 +201,8 @@ def _model_non_instantiated_vnf_instance(**updates):
'vnf_software_version': '1.0',
'tenant_id': uuidsentinel.tenant_id,
'vnfd_id': uuidsentinel.vnfd_id,
'vnfd_version': '1.0'}
'vnfd_version': '1.0',
'vnfPkgId': uuidsentinel.vnf_pkg_id}
if updates:
vnf_instance.update(**updates)
@ -236,16 +237,16 @@ def return_vnf_instance(
instantiated_vnf_info.update(
{"ext_cp_info": [],
'ext_virtual_link_info': [],
'ext_managed_virtual_link_info': [],
'vnfc_resource_info': [],
'vnf_virtual_link_resource_info': [],
'virtual_storage_resource_info': [],
"flavour_id": "simple",
"scale_status": [scale_status],
"vnf_instance_id": "171f3af2-a753-468a-b5a7-e3e048160a79",
"additional_params": {"key": "value"},
'vnf_state': "STARTED"})
'ext_virtual_link_info': [],
'ext_managed_virtual_link_info': [],
'vnfc_resource_info': [],
'vnf_virtual_link_resource_info': [],
'virtual_storage_resource_info': [],
"flavour_id": "simple",
"scale_status": [scale_status],
"vnf_instance_id": "171f3af2-a753-468a-b5a7-e3e048160a79",
"additional_params": {"key": "value"},
'vnf_state': "STARTED"})
info_data = objects.InstantiatedVnfInfo(**instantiated_vnf_info)
vnf_instance_obj.instantiated_vnf_info = info_data

View File

@ -133,6 +133,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
body_data['vnfd_id'] = "2c69a161-0000-4b0f-bcf8-391f8fc76600"
body_data['vnf_configurable_properties'] = {"test": "test_value"}
body_data['vnfc_info_modifications_delete_ids'] = ["test1"]
body_data['vnf_pkg_id'] = uuidsentinel.vnf_pkg_id
return body_data
def _create_vnf_lcm_opoccs(self):
@ -263,7 +264,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
@mock.patch.object(glance_store, 'load_csar')
def test_get_vnf_package_vnfd_exception_from_glance_store(self,
mock_load_csar):
mock_load_csar):
mock_load_csar.side_effect = store_exceptions.NotFound
self.assertRaises(exceptions.FailedToGetVnfdData,
self.conductor.get_vnf_package_vnfd, self.context,
@ -310,7 +311,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
lcm_op_occs_data = fakes.get_lcm_op_occs_data()
mock_vnf_by_id.return_value = \
objects.VnfLcmOpOcc(context=self.context,
**lcm_op_occs_data)
**lcm_op_occs_data)
vnf_package_vnfd = self._create_and_upload_vnf_package()
vnf_instance_data = fake_obj.get_vnf_instance_data(
@ -337,13 +338,13 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
@mock.patch.object(objects.VnfPackage, 'is_package_in_use')
@mock.patch('tacker.conductor.conductor_server.LOG')
@mock.patch.object(objects.VnfLcmOpOcc, "get_by_id")
def test_instantiate_vnf_instance_already_instantiated(self,
mock_vnf_by_id, mock_log, mock_package_in_use, mock_get_lock,
def test_instantiate_vnf_instance_already_instantiated(
self, mock_vnf_by_id, mock_log, mock_package_in_use, mock_get_lock,
mock_save):
lcm_op_occs_data = fakes.get_lcm_op_occs_data()
mock_vnf_by_id.return_value = \
objects.VnfLcmOpOcc(context=self.context,
**lcm_op_occs_data)
**lcm_op_occs_data)
vnf_package_vnfd = self._create_and_upload_vnf_package()
vnf_instance_data = fake_obj.get_vnf_instance_data(
@ -361,9 +362,10 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
self.vnflcm_driver.instantiate_vnf.assert_not_called()
mock_package_in_use.assert_not_called()
expected_log = 'Vnf instance %(id)s is already in %(state)s state.'
mock_log.error.assert_called_once_with(expected_log,
{'id': vnf_instance.id,
'state': fields.VnfInstanceState.INSTANTIATED})
mock_log.error.assert_called_once_with(
expected_log, {
'id': vnf_instance.id,
'state': fields.VnfInstanceState.INSTANTIATED})
@unittest.skip("Such test is no longer feasible.")
@mock.patch.object(objects.VnfLcmOpOcc, "save")
@ -372,14 +374,17 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
@mock.patch.object(objects.LccnSubscriptionRequest,
'vnf_lcm_subscriptions_get')
@mock.patch.object(objects.VnfLcmOpOcc, "get_by_id")
def test_instantiate_vnf_instance_with_vnf_package_in_use(self,
def test_instantiate_vnf_instance_with_vnf_package_in_use(
self,
mock_vnf_by_id,
mock_vnf_lcm_subscriptions_get,
mock_vnf_package_in_use, mock_get_lock, mock_save):
mock_vnf_package_in_use,
mock_get_lock,
mock_save):
lcm_op_occs_data = fakes.get_lcm_op_occs_data()
mock_vnf_by_id.return_value = \
objects.VnfLcmOpOcc(context=self.context,
**lcm_op_occs_data)
**lcm_op_occs_data)
vnf_package_vnfd = self._create_and_upload_vnf_package()
vnf_instance_data = fake_obj.get_vnf_instance_data(
@ -420,7 +425,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
lcm_op_occs_data = fakes.get_lcm_op_occs_data()
mock_vnf_by_id.return_value = \
objects.VnfLcmOpOcc(context=self.context,
**lcm_op_occs_data)
**lcm_op_occs_data)
vnf_package_vnfd = self._create_and_upload_vnf_package()
vnf_instance_data = fake_obj.get_vnf_instance_data(
@ -515,7 +520,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
vnf_instance_data['instantiation_state'] =\
fields.VnfInstanceState.NOT_INSTANTIATED
vnf_instance = objects.VnfInstance(context=self.context,
**vnf_instance_data)
**vnf_instance_data)
vnf_instance.create()
terminate_vnf_req = objects.TerminateVnfRequest(
@ -530,10 +535,11 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
self.vnflcm_driver.terminate_vnf.assert_not_called()
mock_package_in_use.assert_not_called()
expected_log = ('Terminate action cannot be performed on vnf %(id)s '
'which is in %(state)s state.')
mock_log.error.assert_called_once_with(expected_log,
{'id': vnf_instance.id,
'state': fields.VnfInstanceState.NOT_INSTANTIATED})
'which is in %(state)s state.')
mock_log.error.assert_called_once_with(
expected_log, {
'id': vnf_instance.id,
'state': fields.VnfInstanceState.NOT_INSTANTIATED})
@unittest.skip("Such test is no longer feasible.")
@mock.patch('tacker.conductor.conductor_server.Conductor.'
@ -549,7 +555,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
vnf_instance_data['instantiation_state'] =\
fields.VnfInstanceState.INSTANTIATED
vnf_instance = objects.VnfInstance(context=self.context,
**vnf_instance_data)
**vnf_instance_data)
vnf_instance.create()
mock_vnf_package_is_package_in_use.return_value = False
@ -581,7 +587,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
vnf_instance_data['instantiation_state'] =\
fields.VnfInstanceState.INSTANTIATED
vnf_instance = objects.VnfInstance(context=self.context,
**vnf_instance_data)
**vnf_instance_data)
vnf_instance.create()
mock_vnf_package_is_package_in_use.return_value = True
@ -630,7 +636,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
vnf_lcm_op_occs_id)
expected_msg = "Failed to update usage_state of vnf package %s"
mock_log.error.assert_called_once_with(expected_msg,
vnf_package_vnfd.package_uuid)
vnf_package_vnfd.package_uuid)
@mock.patch('tacker.conductor.conductor_server.Conductor.'
'_add_additional_vnf_info')
@ -647,7 +653,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
lcm_op_occs_data = fakes.get_lcm_op_occs_data()
mock_vnf_by_id.return_value = \
objects.VnfLcmOpOcc(context=self.context,
**lcm_op_occs_data)
**lcm_op_occs_data)
vnf_package_vnfd = self._create_and_upload_vnf_package()
vnf_instance_data = fake_obj.get_vnf_instance_data(
vnf_package_vnfd.vnfd_id)
@ -707,8 +713,8 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
@unittest.skip("Such test is no longer feasible.")
@mock.patch.object(coordination.Coordinator, 'get_lock')
@mock.patch('tacker.conductor.conductor_server.LOG')
def test_heal_vnf_instance_already_not_instantiated(self,
mock_log, mock_get_lock):
def test_heal_vnf_instance_already_not_instantiated(
self, mock_log, mock_get_lock):
vnf_package_vnfd = self._create_and_upload_vnf_package()
vnf_instance_data = fake_obj.get_vnf_instance_data(
vnf_package_vnfd.vnfd_id)
@ -723,14 +729,15 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
vnf_dict = {"fake": "fake_dict"}
vnf_lcm_op_occs_id = uuidsentinel.vnf_lcm_op_occs_id
self.conductor.heal(self.context, vnf_instance, vnf_dict,
heal_vnf_req, vnf_lcm_op_occs_id)
heal_vnf_req, vnf_lcm_op_occs_id)
self.vnflcm_driver.heal_vnf.assert_not_called()
expected_log = ('Heal action cannot be performed on vnf %(id)s '
'which is in %(state)s state.')
mock_log.error.assert_called_once_with(expected_log,
{'id': vnf_instance.id,
'state': fields.VnfInstanceState.NOT_INSTANTIATED})
mock_log.error.assert_called_once_with(
expected_log, {
'id': vnf_instance.id,
'state': fields.VnfInstanceState.NOT_INSTANTIATED})
@mock.patch.object(os, 'remove')
@mock.patch.object(shutil, 'rmtree')
@ -812,7 +819,8 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
mock_subscriptions_get):
self.requests_mock.register_uri('POST',
"https://localhost/callback",
headers={'Content-Type': 'application/json'},
headers={
'Content-Type': 'application/json'},
status_code=204)
mock_subscriptions_get.return_value = self._create_subscriptions()
@ -837,9 +845,11 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
'vnf_lcm_subscriptions_get')
def test_sendNotification_vnfIdentifierCreation(self,
mock_subscriptions_get):
self.requests_mock.register_uri('POST',
self.requests_mock.register_uri(
'POST',
"https://localhost/callback",
headers={'Content-Type': 'application/json'},
headers={
'Content-Type': 'application/json'},
status_code=204)
mock_subscriptions_get.return_value = self._create_subscriptions()
@ -861,9 +871,11 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
@mock.patch.object(objects.LccnSubscriptionRequest,
'vnf_lcm_subscriptions_get')
def test_sendNotification_with_auth_basic(self, mock_subscriptions_get):
self.requests_mock.register_uri('POST',
self.requests_mock.register_uri(
'POST',
"https://localhost/callback",
headers={'Content-Type': 'application/json'},
headers={
'Content-Type': 'application/json'},
status_code=204)
auth_user_name = 'test_user'
@ -897,17 +909,19 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
def test_sendNotification_with_auth_client_credentials(
self, mock_subscriptions_get):
auth.auth_manager = auth._AuthManager()
self.requests_mock.register_uri('POST',
self.requests_mock.register_uri(
'POST',
"https://localhost/callback",
headers={'Content-Type': 'application/json'},
headers={
'Content-Type': 'application/json'},
status_code=204)
auth_user_name = 'test_user'
auth_password = 'test_password'
token_endpoint = 'https://oauth2/tokens'
self.requests_mock.register_uri('GET',
token_endpoint,
json={'access_token': 'test_token', 'token_type': 'bearer'},
self.requests_mock.register_uri(
'GET', token_endpoint, json={
'access_token': 'test_token', 'token_type': 'bearer'},
headers={'Content-Type': 'application/json'},
status_code=200)
@ -938,10 +952,12 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
@mock.patch.object(objects.LccnSubscriptionRequest,
'vnf_lcm_subscriptions_get')
def test_sendNotification_retyNotification(self,
mock_subscriptions_get):
self.requests_mock.register_uri('POST',
mock_subscriptions_get):
self.requests_mock.register_uri(
'POST',
"https://localhost/callback",
headers={'Content-Type': 'application/json'},
headers={
'Content-Type': 'application/json'},
status_code=400)
mock_subscriptions_get.return_value = self._create_subscriptions()
@ -964,7 +980,8 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
'vnf_lcm_subscriptions_get')
def test_sendNotification_sendError(self,
mock_subscriptions_get):
self.requests_mock.register_uri('POST',
self.requests_mock.register_uri(
'POST',
"https://localhost/callback",
exc=requests.exceptions.HTTPError("MockException"))
@ -1019,3 +1036,25 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
self.body_data,
self.vnfd_pkg_data,
vnfd_id)
@mock.patch.object(conductor_server, 'revert_update_lcm')
@mock.patch.object(t_context.get_admin_context().session, "add")
@mock.patch.object(objects.vnf_lcm_op_occs.VnfLcmOpOcc, "save")
@mock.patch.object(objects.VnfInstance, "update")
@mock.patch.object(objects.vnf_lcm_op_occs.VnfLcmOpOcc, "create")
def test_update_lcm_with_vnf_pkg_id(self, mock_create,
mock_update, mock_save,
mock_add, mock_revert):
mock_create.return_value = "OK"
mock_update.return_value = datetime.datetime(
1900, 1, 1, 1, 1, 1, tzinfo=iso8601.UTC)
mock_add.return_value = "OK"
mock_save.return_value = "OK"
vnfd_id = "2c69a161-0000-4b0f-bcf8-391f8fc76600"
self.conductor.update(
self.context,
self.vnf_lcm_opoccs,
self.body_data,
self.vnfd_pkg_data,
vnfd_id)

View File

@ -118,7 +118,7 @@ lcm_op_occs_data = {
"tenant_id": uuidsentinel.tenant_id,
'operation_state': 'PROCESSING',
'state_entered_time': datetime.datetime(1900, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
tzinfo=iso8601.UTC),
'start_time': datetime.datetime(1900, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
'operation': 'MODIFY_INFO',
@ -178,6 +178,28 @@ vnf_artifacts = {
}
def fake_vnf_package_vnfd_dict(**updates):
vnf_pkg_vnfd = {
'package_uuid': uuidsentinel.package_uuid,
'vnfd_id': uuidsentinel.vnfd_id,
'vnf_provider': 'test vnf provider',
'vnf_product_name': 'Sample VNF',
'vnf_software_version': '1.0',
'vnfd_version': '1.0'
}
if updates:
vnf_pkg_vnfd.update(updates)
return vnf_pkg_vnfd
def return_vnf_package_vnfd_data():
model_obj = models.VnfPackageVnfd()
model_obj.update(fake_vnf_package_vnfd_dict())
return model_obj
def get_vnf_package_vnfd_data(vnf_package_id, vnfd_id):
return {
'package_uuid': vnf_package_id,
@ -185,6 +207,7 @@ def get_vnf_package_vnfd_data(vnf_package_id, vnfd_id):
'vnf_provider': 'test vnf provider',
'vnf_product_name': 'Sample VNF',
'vnf_software_version': '1.0',
"vnf_pkg_id": uuidsentinel.vnf_pkg_id,
'vnfd_version': '1.0',
}
@ -201,7 +224,7 @@ def get_vnf_instance_data(vnfd_id):
"vnfd_version": "1.0",
"tenant_id": uuidsentinel.tenant_id,
"vnf_pkg_id": uuidsentinel.vnf_pkg_id,
"vnf_metadata": {"key": "value"}
"vnf_metadata": {"key": "value"},
}
@ -218,7 +241,7 @@ def get_vnf_instance_data_with_id(vnfd_id):
"vnfd_version": "1.0",
"tenant_id": uuidsentinel.tenant_id,
"vnf_pkg_id": uuidsentinel.vnf_pkg_id,
"vnf_metadata": {"key": "value"}
"vnf_metadata": {"key": "value"},
}
@ -227,7 +250,7 @@ def get_lcm_op_occs_data(vnf_instance_id):
"tenant_id": uuidsentinel.tenant_id,
'operation_state': 'PROCESSING',
'state_entered_time': datetime.datetime(1900, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
tzinfo=iso8601.UTC),
'start_time': datetime.datetime(1900, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
'vnf_instance_id': vnf_instance_id,
@ -254,9 +277,9 @@ def fake_vnf_instance_model_dict(**updates):
'instantiation_state': 'NOT_INSTANTIATED',
'vim_connection_info': [],
'tenant_id': '33f8dbdae36142eebf214c1869eb4e4c',
'id': constants.UUID,
'vnf_pkg_id': uuidsentinel.vnf_pkg_id,
'vnf_metadata': {'key': 'value'}
'id': constants.UUID,
'vnf_metadata': {"key": "value"},
}
if updates:
@ -454,7 +477,7 @@ def vnf_instance_model_object(vnf_instance):
'tenant_id': vnf_instance.tenant_id,
'created_at': vnf_instance.created_at,
'vnf_pkg_id': vnf_instance.vnf_pkg_id,
'vnf_metadata': vnf_instance.vnf_metadata
'vnf_metadata': vnf_instance.vnf_metadata,
}
vnf_instance_db_obj = models.VnfInstance()

View File

@ -13,16 +13,17 @@
# License for the specific language governing permissions and limitations
# under the License.
import ddt
from unittest import mock
from tacker.common import exceptions
from tacker import context
from tacker.db import api as sqlalchemy_api
from tacker.db.db_sqlalchemy import api
from tacker.db.nfvo import nfvo_db
from tacker import objects
from tacker.tests.unit.db.base import SqlTestCase
from tacker.tests.unit.objects import fakes
from tacker.tests.unit.vnflcm import fakes as fakes_vnflcm
from tacker.tests import uuidsentinel
get_engine = sqlalchemy_api.get_engine
@ -54,6 +55,7 @@ class FakeApiModelQuery:
return self
@ddt.ddt
class TestVnfInstance(SqlTestCase):
maxDiff = None
@ -65,8 +67,12 @@ class TestVnfInstance(SqlTestCase):
self.vims = nfvo_db.Vim(**fakes.vim_data)
self.engine = get_engine()
self.conn = self.engine.connect()
self.body_data = self._create_body_data()
self.vnfd_pkg_data = self._create_vnfd_pkg_data()
self.vim = nfvo_db.Vim()
def _create_and_upload_vnf_package(self):
@mock.patch.object(objects.VnfPackageVnfd, 'create')
def _create_and_upload_vnf_package(self, mock_create):
vnf_package = objects.VnfPackage(context=self.context,
**fakes.vnf_package_data)
vnf_package.create()
@ -74,6 +80,7 @@ class TestVnfInstance(SqlTestCase):
vnf_pack_vnfd = fakes.get_vnf_package_vnfd_data(
vnf_package.id, uuidsentinel.vnfd_id)
mock_create.return_value = fakes.return_vnf_package_vnfd_data()
vnf_pack_vnfd_obj = objects.VnfPackageVnfd(
context=self.context, **vnf_pack_vnfd)
vnf_pack_vnfd_obj.create()
@ -83,6 +90,32 @@ class TestVnfInstance(SqlTestCase):
return vnf_pack_vnfd_obj
def _create_body_data(self):
body_data = {}
body_data['vnf_instance_name'] = "new_instance_name"
body_data['vnf_instance_description'] = "new_instance_discription"
body_data['vnfd_id'] = "2c69a161-0000-4b0f-bcf8-391f8fc76600"
body_data['vnf_configurable_properties'] = {"test": "test_value"}
body_data['vnfc_info_modifications_delete_ids'] = ["test1"]
body_data['vnf_pkg_id'] = uuidsentinel.vnf_pkg_id
return body_data
def _create_vnfd_pkg_data(self):
vnfd_pkg_data = {}
vnfd_pkg_data['vnf_provider'] =\
fakes.return_vnf_package_vnfd_data().get('vnf_provider')
vnfd_pkg_data['vnf_product_name'] =\
fakes.return_vnf_package_vnfd_data().get('vnf_product_name')
vnfd_pkg_data['vnf_software_version'] =\
fakes.return_vnf_package_vnfd_data().get('vnf_software_version')
vnfd_pkg_data['vnfd_version'] =\
fakes.return_vnf_package_vnfd_data().get('vnfd_version')
vnfd_pkg_data['package_uuid'] =\
fakes.return_vnf_package_vnfd_data().get('package_uuid')
vnfd_pkg_data['vnfd_id'] =\
fakes.return_vnf_package_vnfd_data().get('vnfd_id')
return vnfd_pkg_data
def test_create(self):
vnf_instance_data = fakes.get_vnf_instance_data(
self.vnf_package.vnfd_id)
@ -189,155 +222,21 @@ class TestVnfInstance(SqlTestCase):
self.assertRaises(exceptions.ObjectActionError,
vnf_instance_obj.destroy, self.context)
@mock.patch('tacker.objects.vnf_instance._get_vnf_instance')
@mock.patch('tacker.objects.vnf_package.VnfPackage.get_by_id')
@mock.patch.object(api, 'model_query')
def test_update_vnf_instances(
self,
mock_model_query,
mock_get_vnf_package,
mock_get_vnf):
vnf_instance_data = fakes.fake_vnf_instance_model_dict(**{
"vim_connection_info": [
objects.VimConnectionInfo._from_dict({
"id": "testid",
"vim_id": "aaa",
"vim_type": "openstack-1",
"interface_info": {"endpoint": "endpoint"},
"access_info": {"username": "xxxxx",
"region": "region",
"password": "password",
"tenant": "tenant"}}),
objects.VimConnectionInfo._from_dict({
"id": "testid3",
"vim_id": "ccc",
"vim_type": "openstack-2",
"interface_info": {"endpoint": "endpoint22"},
"access_info": {"username": "xxxxx",
"region": "region",
"password": "password"}}),
objects.VimConnectionInfo._from_dict({
"id": "testid5",
"vim_id": "eee",
"vim_type": "openstack-4"})
],
"vnf_metadata": {"testkey": "test_value"}})
vnf_instance = objects.VnfInstance(
context=self.context, **vnf_instance_data)
mock_get_vnf.return_value = \
fakes.vnf_instance_model_object(vnf_instance)
def mock_filter(id=None):
print('### mock_filter ###', id)
def mock_update(updated_values, synchronize_session=False):
print('### mock_update ###', updated_values)
if 'vim_connection_info' not in updated_values:
return
compar_updated_values = {}
compar_updated_values['vnf_instance_name'] = "new_instance_name"
compar_updated_values['vnf_instance_description'] = \
"new_instance_discription"
compar_updated_values['vnf_metadata'] = {
"testkey": "test_value1", "testkey2": "test_value2"}
compar_updated_values['vim_connection_info'] = [
objects.VimConnectionInfo._from_dict({
"id": "testid",
"vim_id": "bbb",
"vim_type": "openstack-1A",
"interface_info": {"endpoint": "endpoint11"},
"access_info": {"username": "xxxxx1",
"region": "region1",
"password": "password1",
"tenant": "tenant1"}}),
objects.VimConnectionInfo._from_dict({
"id": "testid3",
"vim_id": "ccc",
"vim_type": "openstack-2",
"interface_info": {"endpoint": "endpoint22"},
"access_info": {"username": "xxxxx",
"region": "region",
"password": "password2",
"tenant": "tenant2"}}),
objects.VimConnectionInfo._from_dict({
"id": "testid5",
"vim_id": "eee",
"vim_type": "openstack-4"}),
objects.VimConnectionInfo._from_dict({
"id": "testid7",
"vim_id": "fff",
"vim_type": "openstack-5A",
"interface_info": {"endpoint": "endpoint55"},
"access_info": {"username": "xxxxx5",
"region": "region5",
"password": "password5",
"tenant": "tenant5"}})
]
compar_updated_values['vnfd_id'] = \
"2c69a161-0000-4b0f-bcf8-391f8fc76600"
compar_updated_values['vnf_provider'] = \
self.vnf_package.get('vnf_provider')
compar_updated_values['vnf_product_name'] = \
self.vnf_package.get('vnf_product_name')
compar_updated_values['vnf_software_version'] = \
self.vnf_package.get('vnf_software_version')
expected_vci = sorted(compar_updated_values.pop(
'vim_connection_info'), key=lambda x: x.id)
actual_vci = sorted(
updated_values.pop('vim_connection_info'),
key=lambda x: x.id)
for e, a in zip(expected_vci, actual_vci):
self.assertDictEqual(
e.to_dict(),
a.to_dict())
self.assertDictEqual(
compar_updated_values,
updated_values)
fake_api_model_query = FakeApiModelQuery(
callback_filter_by=mock_filter, callback_update=mock_update)
mock_model_query.return_value = fake_api_model_query
vnf_lcm_opoccs = {}
body = {"vnf_instance_name": "new_instance_name",
"vnf_instance_description": "new_instance_discription",
"vnfd_id": "2c69a161-0000-4b0f-bcf8-391f8fc76600",
"vnf_configurable_properties": {"test": "test_value1"},
"vnfc_info_modifications_delete_ids": ["test1"],
"metadata": {"testkey": "test_value1",
"testkey2": "test_value2"},
"vim_connection_info": [
{"id": "testid",
"vim_id": "bbb",
"vim_type": "openstack-1A",
"interface_info": {"endpoint": "endpoint11"},
"access_info": {"username": "xxxxx1",
"region": "region1",
"password": "password1",
"tenant": "tenant1"}},
{"id": "testid3",
"vim_type": "openstack-2",
"access_info": {"password": "password2",
"tenant": "tenant2"}},
{"id": "testid7",
"vim_id": "fff",
"vim_type": "openstack-5A",
"interface_info": {"endpoint": "endpoint55"},
"access_info": {"username": "xxxxx5",
"region": "region5",
"password": "password5",
"tenant": "tenant5"}},
]}
@mock.patch.object(objects.vnf_package.VnfPackage, 'get_by_id')
def test_update(self, mock_get_by_id):
mock_get_by_id.return_value =\
fakes_vnflcm.return_vnf_package_with_deployment_flavour()
vnf_instance_data = fakes.get_vnf_instance_data(
self.vnf_package.vnfd_id)
vnf_instance = objects.VnfInstance(context=self.context,
**vnf_instance_data)
vnf_instance.create()
vnf_lcm_oppccs = fakes.get_lcm_op_occs_data(
vnf_instance.id)
vnf_instance.update(
self.context,
vnf_lcm_opoccs,
body,
self.vnf_package,
self.vnf_package.id)
vnf_lcm_oppccs,
self.body_data,
self.vnfd_pkg_data,
vnf_instance_data['vnfd_id'])

View File

@ -120,6 +120,7 @@ def _model_non_instantiated_vnf_instance(**updates):
'tenant_id': uuidsentinel.tenant_id,
'vnfd_id': uuidsentinel.vnfd_id,
'vnfd_version': '1.0',
'vnf_pkg_id': uuidsentinel.vnf_pkg_id,
'vnf_metadata': {"key": "value"}}
if updates:
@ -204,9 +205,9 @@ def _instantiated_vnf_links(vnf_instance_id):
links = {
"self": {"href": "/vnflcm/v1/vnf_instances/%s" % vnf_instance_id},
"terminate": {"href": "/vnflcm/v1/vnf_instances/%s/terminate" %
vnf_instance_id},
vnf_instance_id},
"heal": {"href": "/vnflcm/v1/vnf_instances/%s/heal" %
vnf_instance_id}}
vnf_instance_id}}
return links
@ -218,13 +219,15 @@ def _fake_vnf_instance_not_instantiated_response(
'vnfInstanceName': 'Vnf instance name',
'vnfProductName': 'Sample VNF',
'_links': {
'self': {'href': os.path.join('/vnflcm/v1/vnf_instances/',
uuidsentinel.vnf_instance_id)},
'self': {
'href': os.path.join(
'/vnflcm/v1/vnf_instances/',
uuidsentinel.vnf_instance_id)},
'instantiate': {
'href': os.path.join('/vnflcm/v1/vnf_instances',
uuidsentinel.vnf_instance_id, 'instantiate')
}
},
'href': os.path.join(
'/vnflcm/v1/vnf_instances',
uuidsentinel.vnf_instance_id,
'instantiate')}},
'instantiationState': 'NOT_INSTANTIATED',
'vnfProvider': 'Vnf provider',
'vnfdId': uuidsentinel.vnfd_id,
@ -621,7 +624,7 @@ def get_vnfd_dict(image_path=None):
{'layer_protocol': 'ipv4',
'l3_protocol_data': {}
}]}},
'type': 'tosca.nodes.nfv.VnfVirtualLink'},
'type': 'tosca.nodes.nfv.VnfVirtualLink'},
'VL4': {'properties': {'connectivity_type': {
'layer_protocols': ['ipv4']},
'description': 'Internal virtual link in VNF',

View File

@ -195,7 +195,7 @@ class TestController(base.TestCase):
with mock.patch.object(tacker.db.vnfm.vnfm_db.VNFMPluginDb, 'get_vnfs',
return_value=[]):
with mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()}):
return_value={'VNFM': FakeVNFMPlugin()}):
self.controller = controller.VnfLcmController()
def tearDown(self):
@ -246,7 +246,7 @@ class TestController(base.TestCase):
'VnfLcmController._create_vnf')
@mock.patch.object(objects.vnf_package.VnfPackage, 'save')
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch.object(objects.vnf_instance, '_vnf_instance_create')
@mock.patch.object(objects.vnf_package_vnfd.VnfPackageVnfd, 'get_by_id')
def test_create_without_name_and_description(
@ -310,8 +310,10 @@ class TestController(base.TestCase):
'expected_type': 'description'}
)
@ddt.unpack
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
def test_create_with_invalid_request_body(
self, attribute, value, expected_type):
self, mock_get_service_plugins, attribute, value, expected_type):
"""value of attribute in body is of invalid type"""
body = {"vnfInstanceName": "SampleVnf",
"vnfdId": "29c770a3-02bc-4dfc-b4be-eb173ac00567",
@ -500,8 +502,11 @@ class TestController(base.TestCase):
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
@ddt.data('PATCH', 'PUT', 'HEAD', 'DELETE')
def test_create_not_allowed_http_method(self, method):
def test_create_not_allowed_http_method(self, method,
mock_get_service_plugins):
"""Wrong HTTP method"""
body = {"vnfdId": uuidsentinel.vnfd_id}
req = fake_request.HTTPRequest.blank('/vnf_instances')
@ -544,7 +549,7 @@ class TestController(base.TestCase):
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._notification_process')
@mock.patch('tacker.api.vnflcm.v1.controller.'
@ -586,7 +591,7 @@ class TestController(base.TestCase):
mock_instantiate.assert_called_once()
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._get_vnf')
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
@ -624,7 +629,7 @@ class TestController(base.TestCase):
mock_get_vnf.assert_called_once()
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._notification_process')
@mock.patch('tacker.api.vnflcm.v1.controller.'
@ -669,7 +674,7 @@ class TestController(base.TestCase):
mock_insta_notif_process.assert_called_once()
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._get_vnf')
@mock.patch.object(vim_client.VimClient, "get_vim")
@ -715,7 +720,7 @@ class TestController(base.TestCase):
mock_get_vnf.assert_called_once()
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._get_vnf')
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
@ -755,7 +760,7 @@ class TestController(base.TestCase):
mock_get_vnf.assert_called_once()
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.VnfLcmController.'
'_notification_process')
@mock.patch('tacker.api.vnflcm.v1.controller.'
@ -805,7 +810,7 @@ class TestController(base.TestCase):
mock_insta_notif_process.assert_called_once()
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._get_vnf')
@mock.patch.object(vim_client.VimClient, "get_vim")
@ -851,7 +856,7 @@ class TestController(base.TestCase):
mock_get_vnf.assert_called_once()
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._get_vnf')
@mock.patch.object(vim_client.VimClient, "get_vim")
@ -898,7 +903,7 @@ class TestController(base.TestCase):
mock_get_vnf.assert_called_once()
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._get_vnf')
@mock.patch.object(vim_client.VimClient, "get_vim")
@ -938,12 +943,12 @@ class TestController(base.TestCase):
mock_get_vnf.assert_called_once()
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._get_vnf')
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
def test_instantiate_incorrect_instantiation_state(self, mock_vnf_by_id,
mock_get_vnf, mock_get_service_plugins):
def test_instantiate_incorrect_instantiation_state(
self, mock_vnf_by_id, mock_get_vnf, mock_get_service_plugins):
vnf_instance = fakes.return_vnf_instance_model()
vnf_instance.instantiation_state = 'INSTANTIATED'
mock_vnf_by_id.return_value = vnf_instance
@ -960,12 +965,15 @@ class TestController(base.TestCase):
self.assertEqual(http_client.CONFLICT, resp.status_code)
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._get_vnf')
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
def test_instantiate_incorrect_task_state(self, mock_vnf_by_id,
mock_get_vnf, mock_get_service_plugins):
def test_instantiate_incorrect_task_state(
self,
mock_vnf_by_id,
mock_get_vnf,
mock_get_service_plugins):
vnf_instance = fakes.return_vnf_instance_model(
task_state=fields.VnfInstanceTaskState.INSTANTIATING)
mock_vnf_by_id.return_value = vnf_instance
@ -1001,8 +1009,10 @@ class TestController(base.TestCase):
'expected_type': 'object'},
)
@ddt.unpack
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
def test_instantiate_with_invalid_request_body(
self, attribute, value, expected_type):
self, mock_get_service_plugins, attribute, value, expected_type):
body = fakes.get_vnf_instantiation_request_body()
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
@ -1023,7 +1033,10 @@ class TestController(base.TestCase):
self.assertEqual(expected_message, exception.msg)
def test_instantiate_without_flavour_id(self):
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
def test_instantiate_without_flavour_id(self,
mock_get_service_plugins):
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
req.body = jsonutils.dump_as_bytes({})
@ -1037,7 +1050,10 @@ class TestController(base.TestCase):
self.assertEqual("'flavourId' is a required property",
resp.json['badRequest']['message'])
def test_instantiate_invalid_request_parameter(self):
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
def test_instantiate_invalid_request_parameter(self,
mock_get_service_plugins):
body = {"flavourId": "simple"}
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
@ -1058,7 +1074,10 @@ class TestController(base.TestCase):
"('additional_property' was unexpected)",
resp.json['badRequest']['message'])
def test_instantiate_with_invalid_uuid(self):
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
def test_instantiate_with_invalid_uuid(self,
mock_get_service_plugins):
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s/instantiate' % constants.INVALID_UUID)
body = {"flavourId": "simple"}
@ -1075,7 +1094,7 @@ class TestController(base.TestCase):
resp.json['itemNotFound']['message'])
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._get_vnf')
@mock.patch.object(objects.VnfInstance, "get_by_id")
@ -1099,8 +1118,11 @@ class TestController(base.TestCase):
resp.json['itemNotFound']['message'])
mock_get_vnf.assert_called_once()
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
@ddt.data('HEAD', 'PUT', 'DELETE', 'PATCH', 'GET')
def test_instantiate_invalid_http_method(self, method):
def test_instantiate_invalid_http_method(self, method,
mock_get_service_plugins):
# Wrong HTTP method
body = fakes.get_vnf_instantiation_request_body()
req = fake_request.HTTPRequest.blank(
@ -1120,8 +1142,11 @@ class TestController(base.TestCase):
res_dict = self.controller.show(req, uuidsentinel.instance_id)
self.assertEqual(expected_result, res_dict)
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch.object(objects.VnfInstance, "get_by_id")
def test_show_vnf_instantiated(self, mock_vnf_by_id):
def test_show_vnf_instantiated(self, mock_vnf_by_id,
mock_get_service_plugins):
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s' % uuidsentinel.instance_id)
mock_vnf_by_id.return_value = fakes.return_vnf_instance(
@ -1131,8 +1156,11 @@ class TestController(base.TestCase):
res_dict = self.controller.show(req, uuidsentinel.instance_id)
self.assertEqual(expected_result, res_dict)
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
def test_show_with_non_existing_vnf_instance(self, mock_vnf_by_id):
def test_show_with_non_existing_vnf_instance(self, mock_vnf_by_id,
mock_get_service_plugins):
mock_vnf_by_id.side_effect = exceptions.VnfInstanceNotFound
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s' % uuidsentinel.vnf_instance_id)
@ -1145,9 +1173,9 @@ class TestController(base.TestCase):
resp.json['itemNotFound']['message'])
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
def test_show_with_invalid_uuid(self,
mock_get_service_plugins):
mock_get_service_plugins):
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s' % constants.INVALID_UUID)
@ -1158,10 +1186,10 @@ class TestController(base.TestCase):
resp.json['itemNotFound']['message'])
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@ddt.data('HEAD', 'PUT', 'POST')
def test_show_invalid_http_method(self, http_method,
mock_get_service_plugins):
mock_get_service_plugins):
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s' % constants.UUID)
req.headers['Content-Type'] = 'application/json'
@ -1171,7 +1199,7 @@ class TestController(base.TestCase):
self.assertEqual(http_client.METHOD_NOT_ALLOWED, resp.status_code)
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._notification_process')
@mock.patch('tacker.api.vnflcm.v1.controller.'
@ -1206,7 +1234,7 @@ class TestController(base.TestCase):
mock_notification_process.assert_called_once()
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@ddt.data(
{'attribute': 'terminationType', 'value': "TEST",
'expected_type': 'enum'},
@ -1241,7 +1269,10 @@ class TestController(base.TestCase):
req, constants.UUID, body=body)
self.assertIn(expected_message, exception.msg)
def test_terminate_missing_termination_type(self):
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
def test_terminate_missing_termination_type(self,
mock_get_service_plugins):
body = {'gracefulTerminationTimeout': 10}
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s/terminate' % uuidsentinel.vnf_instance_id)
@ -1255,8 +1286,11 @@ class TestController(base.TestCase):
self.assertEqual("'terminationType' is a required property",
resp.json['badRequest']['message'])
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
@ddt.data('GET', 'HEAD', 'PUT', 'DELETE', 'PATCH')
def test_terminate_invalid_http_method(self, method):
def test_terminate_invalid_http_method(self, method,
mock_get_service_plugins):
# Wrong HTTP method
body = {'terminationType': 'GRACEFUL',
'gracefulTerminationTimeout': 10}
@ -1269,12 +1303,12 @@ class TestController(base.TestCase):
self.assertEqual(http_client.METHOD_NOT_ALLOWED, resp.status_code)
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._get_vnf')
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
def test_terminate_non_existing_vnf_instance(self, mock_vnf_by_id,
mock_get_vnf, mock_get_service_plugins):
def test_terminate_non_existing_vnf_instance(
self, mock_vnf_by_id, mock_get_vnf, mock_get_service_plugins):
body = {'terminationType': 'GRACEFUL',
'gracefulTerminationTimeout': 10}
mock_vnf_by_id.side_effect = exceptions.VnfInstanceNotFound
@ -1293,12 +1327,12 @@ class TestController(base.TestCase):
mock_get_vnf.assert_called_once()
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._get_vnf')
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
def test_terminate_incorrect_instantiation_state(self, mock_vnf_by_id,
mock_get_vnf, mock_get_service_plugins):
def test_terminate_incorrect_instantiation_state(
self, mock_vnf_by_id, mock_get_vnf, mock_get_service_plugins):
mock_vnf_by_id.return_value = fakes.return_vnf_instance()
body = {"terminationType": "FORCEFUL"}
req = fake_request.HTTPRequest.blank(
@ -1318,12 +1352,15 @@ class TestController(base.TestCase):
mock_get_vnf.assert_called_once()
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._get_vnf')
@mock.patch.object(objects.VnfInstance, "get_by_id")
def test_terminate_incorrect_task_state(self, mock_vnf_by_id,
mock_get_vnf, mock_get_service_plugins):
def test_terminate_incorrect_task_state(
self,
mock_vnf_by_id,
mock_get_vnf,
mock_get_service_plugins):
vnf_instance = fakes.return_vnf_instance(
instantiated_state=fields.VnfInstanceState.INSTANTIATED,
task_state=fields.VnfInstanceTaskState.TERMINATING)
@ -1346,7 +1383,7 @@ class TestController(base.TestCase):
mock_get_vnf.assert_called_once()
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._notification_process')
@mock.patch('tacker.api.vnflcm.v1.controller.'
@ -1376,7 +1413,10 @@ class TestController(base.TestCase):
self.assertEqual(http_client.ACCEPTED, resp.status_code)
mock_rpc_heal.assert_called_once()
def test_heal_cause_max_length_exceeded(self):
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
def test_heal_cause_max_length_exceeded(self,
mock_get_service_plugins):
body = {'cause': 'A' * 256}
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s/heal' % uuidsentinel.vnf_instance_id)
@ -1388,14 +1428,18 @@ class TestController(base.TestCase):
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._notification_process')
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._get_vnf')
@mock.patch.object(objects.VnfInstance, "get_by_id")
def test_heal_incorrect_instantiated_state(self, mock_vnf_by_id,
mock_get_vnf, mock_notif, mock_get_service_plugins):
def test_heal_incorrect_instantiated_state(
self,
mock_vnf_by_id,
mock_get_vnf,
mock_notif,
mock_get_service_plugins):
vnf_instance_obj = fakes.return_vnf_instance(
fields.VnfInstanceState.NOT_INSTANTIATED)
mock_vnf_by_id.return_value = vnf_instance_obj
@ -1416,14 +1460,14 @@ class TestController(base.TestCase):
resp.json['conflictingRequest']['message'])
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._notification_process')
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._get_vnf')
@mock.patch.object(objects.VnfInstance, "get_by_id")
def test_heal_incorrect_task_state(self, mock_vnf_by_id, mock_get_vnf,
mock_notif, mock_get_service_plugins):
mock_notif, mock_get_service_plugins):
vnf_instance_obj = fakes.return_vnf_instance(
fields.VnfInstanceState.INSTANTIATED,
task_state=fields.VnfInstanceTaskState.HEALING)
@ -1445,14 +1489,18 @@ class TestController(base.TestCase):
resp.json['conflictingRequest']['message'])
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._notification_process')
@mock.patch('tacker.api.vnflcm.v1.controller.'
'VnfLcmController._get_vnf')
@mock.patch.object(objects.VnfInstance, "get_by_id")
def test_heal_with_invalid_vnfc_id(self, mock_vnf_by_id,
mock_get_vnf, mock_notif, mock_get_service_plugins):
def test_heal_with_invalid_vnfc_id(
self,
mock_vnf_by_id,
mock_get_vnf,
mock_notif,
mock_get_service_plugins):
vnf_instance_obj = fakes.return_vnf_instance(
fields.VnfInstanceState.INSTANTIATED)
mock_vnf_by_id.return_value = vnf_instance_obj
@ -1470,11 +1518,14 @@ class TestController(base.TestCase):
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
expected_msg = "Vnfc id %s not present in vnf instance %s"
self.assertEqual(expected_msg % (uuidsentinel.vnfc_instance_id,
uuidsentinel.vnf_instance_id),
uuidsentinel.vnf_instance_id),
resp.json['badRequest']['message'])
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
@ddt.data('HEAD', 'PUT', 'DELETE', 'PATCH', 'GET')
def test_heal_invalid_http_method(self, method):
def test_heal_invalid_http_method(self, method,
mock_get_service_plugins):
body = {}
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s/heal' % uuidsentinel.vnf_instance_id)
@ -1496,8 +1547,10 @@ class TestController(base.TestCase):
'expected_type': 'array'},
)
@ddt.unpack
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
def test_heal_with_invalid_request_body(
self, attribute, value, expected_type):
self, mock_get_service_plugins, attribute, value, expected_type):
body = {}
req = fake_request.HTTPRequest.blank(
'/vnf_instances/29c770a3-02bc-4dfc-b4be-eb173ac00567/heal')
@ -1537,8 +1590,11 @@ class TestController(base.TestCase):
resp = self.controller.index(req)
self.assertEqual([], resp)
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
@ddt.data('HEAD', 'PUT', 'DELETE', 'PATCH')
def test_index_invalid_http_method(self, method):
def test_index_invalid_http_method(self, method,
mock_get_service_plugins):
# Wrong HTTP method
req = fake_request.HTTPRequest.blank(
'/vnf_instances')
@ -1566,8 +1622,11 @@ class TestController(base.TestCase):
self.assertEqual(http_client.NO_CONTENT, resp.status_code)
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch.object(objects.VnfInstance, "get_by_id")
def test_delete_with_non_existing_vnf_instance(self, mock_vnf_by_id):
def test_delete_with_non_existing_vnf_instance(self, mock_vnf_by_id,
mock_get_service_plugins):
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s' % uuidsentinel.vnf_instance_id)
req.method = 'DELETE'
@ -1582,7 +1641,9 @@ class TestController(base.TestCase):
uuidsentinel.vnf_instance_id,
resp.json['itemNotFound']['message'])
def test_delete_with_invalid_uuid(self):
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
def test_delete_with_invalid_uuid(self, mock_get_service_plugins):
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s' % constants.INVALID_UUID)
req.method = 'DELETE'
@ -1595,8 +1656,11 @@ class TestController(base.TestCase):
constants.INVALID_UUID,
resp.json['itemNotFound']['message'])
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch.object(objects.VnfInstance, "get_by_id")
def test_delete_with_incorrect_instantiation_state(self, mock_vnf_by_id):
def test_delete_with_incorrect_instantiation_state(
self, mock_vnf_by_id, mock_get_service_plugins):
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s' % uuidsentinel.vnf_instance_id)
req.method = 'DELETE'
@ -1615,8 +1679,11 @@ class TestController(base.TestCase):
self.assertEqual(expected_msg % uuidsentinel.vnf_instance_id,
resp.json['conflictingRequest']['message'])
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch.object(objects.VnfInstance, "get_by_id")
def test_delete_with_incorrect_task_state(self, mock_vnf_by_id):
def test_delete_with_incorrect_task_state(self, mock_vnf_by_id,
mock_get_service_plugins):
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s' % uuidsentinel.vnf_instance_id)
req.method = 'DELETE'
@ -1851,7 +1918,7 @@ class TestController(base.TestCase):
self.assertEqual(http_client.NOT_FOUND, resp.status_code)
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch.object(objects.VNF, "vnf_index_list")
@mock.patch.object(objects.VnfInstanceList, "vnf_instance_list")
@mock.patch.object(objects.VnfPackageVnfd, 'get_vnf_package_vnfd')
@ -1892,7 +1959,7 @@ class TestController(base.TestCase):
mock_update.assert_called_once()
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch.object(objects.VNF, "vnf_index_list")
def test_update_vnf_none_vnf_data(
self,
@ -1923,7 +1990,7 @@ class TestController(base.TestCase):
self.assertEqual(res.text, resp.text)
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch.object(objects.VNF, "vnf_index_list")
def test_update_vnf_status_err(
self,
@ -1951,13 +2018,13 @@ class TestController(base.TestCase):
msg = _("VNF %(id)s status is %(state)s") % {
"id": constants.UUID, "state": "ERROR"}
res = self._make_problem_detail(msg %
{"state": "ERROR"}, 409, 'Conflict')
{"state": "ERROR"}, 409, 'Conflict')
resp = req.get_response(self.app)
self.assertEqual(res.text, resp.text)
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch.object(objects.VNF, "vnf_index_list")
@mock.patch.object(objects.VnfInstanceList, "vnf_instance_list")
def test_update_vnf_none_instance_data(
@ -1985,22 +2052,23 @@ class TestController(base.TestCase):
req.method = 'PATCH'
vnf_data = fakes._get_vnf()
msg = _("Can not find requested vnf instance data: %s") % vnf_data.get(
msg = ("Can not find requested vnf instance data: %s") % vnf_data.get(
'vnfd_id')
res = self._make_problem_detail(msg, 404, title='Not Found')
resp = req.get_response(self.app)
self.assertEqual(res.text, resp.text)
@ddt.data('vnfdId', 'vnfPkgId')
@mock.patch.object(TackerManager, 'get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
return_value={'VNFM': FakeVNFMPlugin()})
@mock.patch.object(objects.VNF, "vnf_index_list")
@mock.patch.object(objects.VnfInstanceList, "vnf_instance_list")
@mock.patch.object(objects.VnfPackageVnfd, 'get_vnf_package_vnfd')
@mock.patch.object(VNFLcmRPCAPI, "update")
@mock.patch.object(VNFLcmRPCAPI, "update_vnf_instance_content")
def test_update_vnf_none_vnfd_data(
self,
mock_update,
self, input_id,
mock_update_vnf_instance_content,
mock_vnf_package_vnf_get_vnf_package_vnfd,
mock_vnf_instance_list,
mock_vnf_index_list,
@ -2011,15 +2079,12 @@ class TestController(base.TestCase):
fields.VnfInstanceState.INSTANTIATED)
mock_vnf_package_vnf_get_vnf_package_vnfd.return_value = ""
body = {"vnfInstanceName": "new_instance_name",
"vnfInstanceDescription": "new_instance_discription",
"vnfdId": "2c69a161-0000-4b0f-bcf8-391f8fc76600",
"vnfConfigurableProperties": {
"test": "test_value"
},
"vnfcInfoModificationsDeleteIds": ["test1"],
"metadata": {"testkey": "test_value"},
"vimConnectionInfo": {"id": "testid"}}
body = {"vnfInstanceName": "new_instance_name\
", "vnfInstanceDescription": "new_instance_discription\
", input_id: "2c69a161-0000-4b0f-bcf8-391f8fc76600\
", "vnfConfigurableProperties\
": {"test": "test_value\
"}, "vnfcInfoModificationsDeleteIds": ["test1"]}
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s' % constants.UUID)
req.body = jsonutils.dump_as_bytes(body)
@ -2027,8 +2092,8 @@ class TestController(base.TestCase):
req.method = 'PATCH'
fakes._get_vnf()
msg = _("Can not find requested vnf package vnfd: %s") %\
body.get('vnfdId')
msg = ("Can not find requested vnf package vnfd: %s") %\
body.get(input_id)
res = self._make_problem_detail(msg, 400, 'Bad Request')
resp = req.get_response(self.app)