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,7 +600,8 @@ class VnfLcmController(wsgi.Controller):
self._instantiate(context, vnf_instance, vnf, body)
@check_vnf_state(action="terminate",
instantiation_state=[fields.VnfInstanceState.INSTANTIATED],
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)
@ -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

@ -1241,18 +1241,15 @@ class Conductor(manager.Manager):
raise Exception(str(msg))
# update lcm_op_occs
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')
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')
# 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)
@ -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)')

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
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

View File

@ -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)

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):
@ -337,8 +338,8 @@ 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 = \
@ -361,8 +362,9 @@ 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,
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.")
@ -372,10 +374,13 @@ 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,
@ -531,8 +536,9 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
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,
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.")
@ -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)
@ -728,8 +734,9 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
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,
mock_log.error.assert_called_once_with(
expected_log, {
'id': vnf_instance.id,
'state': fields.VnfInstanceState.NOT_INSTANTIATED})
@mock.patch.object(os, 'remove')
@ -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)
@ -939,9 +953,11 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
'vnf_lcm_subscriptions_get')
def test_sendNotification_retyNotification(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=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

@ -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"},
}
@ -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:
@ -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/',
'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,

View File

@ -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')
@ -942,8 +947,8 @@ class TestController(base.TestCase):
@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
@ -964,8 +969,11 @@ class TestController(base.TestCase):
@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"}
@ -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)
@ -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}
@ -1273,8 +1307,8 @@ class TestController(base.TestCase):
@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
@ -1297,8 +1331,8 @@ class TestController(base.TestCase):
@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(
@ -1322,8 +1356,11 @@ class TestController(base.TestCase):
@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)
@ -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)
@ -1394,8 +1434,12 @@ class TestController(base.TestCase):
@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
@ -1451,8 +1495,12 @@ class TestController(base.TestCase):
@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
@ -1473,8 +1521,11 @@ class TestController(base.TestCase):
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'
@ -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()})
@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)